因为项目中需要实现仿微信对话功能,于是抽空实现了下,主要是h5的canvas的把图片和文字绘制到画布上

原文来自我的个人博客:http://lvhww.com/index.php/archives/6/

1.首先准备图片资源:微信头部导航,对话框,二维码等

2.API接口

3,效果图

4,代码DetailWechat.vue

<template>
<div class="s-all">
<v-header :name="name"></v-header>
<!-- 人物列表 -->
<div class="s-content active">
<div class="s-recommend">
<span class="span-1">荐</span>
<span>推荐人物</span></div>
<div class="s-recommend-people">
<ul>
<li v-for="item in recommendList">
<div class="s-img">
<img @click="drawResult(item.name,item.nickname,item._id,$event)"
src="../assets/images/e217d58ec3d03b1ab5df0d92589a04bb.jpg"/>
<!--:src="item.image.replace('/game/static/images/','')"/>-->
</div>
<div class="s-title" v-text="item.name">
</div>
</li>
</ul>
</div>
<div class="s-category">
<span class="span-2">类</span>
<span>分类</span>
</div>
<div class="s-category-a">
<a class="s-bt" @click="getData(Aname.name)" v-for="Aname in Alist">{{Aname.name}}</a>
</div>
<div class="s-category-list">
<ul>
<li v-for="item in itemList">
<a class="s-a-1" @click="drawResult(item.name,item.name,item._id)" :data-alt="item.name"
:data-nickname="item.name" :data-num="item._id" name="s-a-1">
<div class="s-a-img">
<img v-lazy="item.image" class="star-icon" id="star-icon"/>
</div>
<div class="s-a-title">
<div class="s-a-title-name" v-text="item.name"></div>
<div class="s-a-title-play">
<span class="m-icon icon-star"></span>
<span class="m-icon icon-star"></span>
<span class="m-icon icon-star"></span>
<span class="m-icon icon-star"></span>
<span class="m-icon icon-star"></span>
<span class="s-people">123456人在玩</span>
</div>
</div>
</a>
<a class="s-a-2" @click="drawResult(item.name,item.name,item._id,$event)" :data-alt="item.name"
:data-nickname="item.name" :data-num="item._id">
开始<span class="icon-more"></span>
</a>
</li>
</ul>
</div>
</div>
<!-- 正在制作 -->
<div class="box" id="page2">
<img id="loading" class="loading" src="https://h5.tangdaoya.com/game/static/loading.png"/>
<p id="loading-text" class="loading-text">正在生成</p>
</div>
<!-- 制作结果 -->
<div class="box" id="page3">
<div class="common-result-btnbox">
<div class="commonbtn-playAgain btn-back" @click="changeContent()" v-if="ShowAgain">
换个文案试试
</div>
<div id="btn-share" class="commonbtn-share">立即去整人</div>
</div>
<div class="resultimgbox">
<img id="result" class="result" src=""/>
</div>
</div>
<!-- 返回制作 -->
<div class="box" id="page4">
<div class="butbox common-result-btnbox">
<div id="backtohomgpage" class="commonbtn-share">返回制作</div>
</div>
</div>
<div class="" style="display: block">
<img src="../assets/images/header.jpg" id="headerImg" alt="">
<img src="../assets/images/footer.jpg" id="footerImg" alt="">
<img src="../assets/images/qr.png" id="codeImg" alt="">
<img src="../assets/images/8fe39669bff9423bb56c5586f5fa70d1.jpg" id="head2Img" alt="">
</div>
<img src="" id="targetImg" alt="">
</div>
</template>
<script>
import Vue from 'vue'
import api from '../fetch/api.js'
import com from '../assets/js/common'
import axios from 'axios';
import VueLazyload from 'vue-lazyload'
import {Toast} from 'mint-ui'
import VHeader from '@/components/Header.vue'
var headImg = "" || "https://h5.tangdaoya.com/zb/static/image/cover/8fe39669bff9423bb56c5586f5fa70d1.jpg";
var manifest = [{
src: "https://h5.tangdaoya.com/game/static/header.jpg",
id: "header"
}, {
src: "https://h5.tangdaoya.com/game/static/footer.jpg",
id: "footer"
}, {
src: headImg,
id: "head2"
}];
var headerEle;
var footerEle;
var codeEle;
var head2Ele;
var starImgObg;
var chatContent, template;
var starName = "张信哲", starNickName = "張信哲JeffChang", starID = 1, starImg;
var cW = 640, cHeigth = 1138, headL = 18, headW = 63, headR = cW - headL - headW,
padding = 20, fontSize = 23, lingheight = 30, imgTextSpace = 20,
starTextL = headL + headW + imgTextSpace - 3,
starTextR = headR - imgTextSpace,
maxTextW = 405, gY = 0, verticlaSpace = 34, textRadius = 6;
CanvasRenderingContext2D.prototype.roundRect = function (x, y, w, h, r) {
if (w < 2 * r) r = w / 2;
if (h < 2 * r) r = h / 2;
this.beginPath();
this.moveTo(x + r, y);
this.arcTo(x + w, y, x + w, y + h, r);
this.arcTo(x + w, y + h, x, y + h, r);
this.arcTo(x, y + h, x, y, r);
this.arcTo(x, y, x + w, y, r);
this.closePath();
return this;
} export default {
components: {
VHeader
},
data() {
return {
name: '',
itemList: [],
recommendList: [],
Alist: [{
name: '影视大咖'
}, {
name: '女明星'
}, {
name: '男明星'
}, {
name: '商业大亨'
}],
starName: '',
starNickName: '',
starID: '',
starImgObg: '',
chatContent: '',
template: '',
ShowAgain: false
}
},
created() {
this.getData();
},
mounted() {
let self = this;
headerEle = document.getElementById('headerImg');
footerEle = document.getElementById('footerImg');
codeEle = document.getElementById('codeImg');
head2Ele = document.getElementById('head2Img');
CanvasRenderingContext2D.prototype.drawStarText = function (x, y, r, text, translate) {
self.drawStarImg(this, y);
console.log('star')
this.font = "24px Helvetica";
var hastrans = false;
var wordCnt = com.isChineseChar(text) ? 32 : 33;
console.log(wordCnt)
var textArr = self.getText2Arr(this, text, wordCnt);
var h = headW + lingheight * (textArr.length - 1);
var w = (textArr.length > 1) ? maxTextW : (this.measureText(textArr[0]).width + 2 * padding);
if (translate) {
hastrans = true;
var transArr = self.getText2Arr(this, translate, 32);
h = h + lingheight * (transArr.length) + 48;
if (transArr.length > 1) {
w = maxTextW;
}
}
gY = y + h + verticlaSpace;
if (w < 2 * r) r = w / 2;
if (h < 2 * r) r = h / 2;
this.save();
this.beginPath();
this.moveTo(x + r, y);
this.arcTo(x + w, y, x + w, y + h, r);
this.arcTo(x + w, y + h, x, y + h, r);
this.arcTo(x, y + h, x, y, r); this.lineTo(x, y + 31 + 7);
this.lineTo(x - 10, y + 31);
this.lineTo(x, y + 31 - 7);
this.arcTo(x, y, x + w, y, r);
this.closePath();
this.strokeStyle = '#d3d3d3';
this.lineWidth = 2;
this.stroke();
this.fillStyle = "#fff";
this.fill(); this.textBaseline = 'top';
this.textAlign = 'left';
this.fillStyle = '#000';
self.writeTextArr(this, textArr, lingheight, x + padding, y + padding);
//writeMulLineText(this, text, 32, 30, x + padding, y+padding);
//this.fillText(text, x + padding, y+padding);
if (hastrans) {
this.beginPath();
var lineY = y + padding * 2 + textArr.length * lingheight;
this.moveTo(x + padding, lineY);
this.lineTo(x + w - padding, lineY);
this.strokeStyle = "#ddd";
this.stroke();
self.writeTextArr(this, transArr, lingheight, x + padding, lineY + 20);
gY = gY - verticlaSpace;
this.transFlag(x, gY + 8, textRadius);
}
this.restore(); return this;
} CanvasRenderingContext2D.prototype.drawSelfText = function (x, y, r, text) {
self.drawSelfImg(this, y);
this.font = "24px Helvetica"; // Arial
var wordCnt = com.isChineseChar(text) ? 32 : 33;
var textArr = self.getText2Arr(this, text, wordCnt);
var h = headW + lingheight * (textArr.length - 1);
var w = (textArr.length > 1) ? maxTextW : (this.measureText(textArr[0]).width + 2 * padding);
x = x - w;
gY = y + h + verticlaSpace;
if (w < 2 * r) r = w / 2;
if (h < 2 * r) r = h / 2;
this.save();
this.beginPath();
this.moveTo(x + r, y); this.arcTo(x + w, y, x + w, y + h, r);
this.lineTo(x + w, y + 31 + 7);
this.lineTo(x + w + 10, y + 31);
this.lineTo(x + w, y + 31 - 7); this.arcTo(x + w, y + h, x, y + h, r);
this.arcTo(x, y + h, x, y, r);
this.arcTo(x, y, x + w, y, r);
this.closePath(); this.strokeStyle = '#8bdf49';
this.lineWidth = 2;
this.stroke();
this.fillStyle = "#a0e75a";
this.fill(); this.textBaseline = 'top';
this.textAlign = 'left';
this.fillStyle = '#000';
self.writeTextArr(this, textArr, lingheight, x + padding, y + padding);
//writeMulLineText(this, text, 32, 30, x + padding, y+padding);
//this.fillText(text, x + padding, y+padding);
this.restore(); return this;
} CanvasRenderingContext2D.prototype.drawHelloText = function (x, y, r, text) {
this.save();
this.font = "18px Helvetica";
var h = 32;
var w = this.measureText(text).width + 2 * padding;
x = x - w / 2;
gY = y + h + 22;
if (w < 2 * r) r = w / 2;
if (h < 2 * r) r = h / 2; this.beginPath();
this.moveTo(x + r, y);
this.arcTo(x + w, y, x + w, y + h, r);
this.arcTo(x + w, y + h, x, y + h, r);
this.arcTo(x, y + h, x, y, r);
this.arcTo(x, y, x + w, y, r);
this.closePath();
this.fillStyle = "#cecece";
this.fill();
this.textBaseline = 'middle';
this.textAlign = 'center';
this.fillStyle = '#fff';
this.fillText(text, cW / 2, y + h / 2);
this.restore(); return this;
} CanvasRenderingContext2D.prototype.transFlag = function (x, y, r, text) {
this.save();
this.font = "18px Helvetica";
var h = 32;
text = '√ 已翻译';
var transpading = 10;
var w = this.measureText(text).width + 2 * transpading;
gY = y + h + verticlaSpace;
if (w < 2 * r) r = w / 2;
if (h < 2 * r) r = h / 2;
this.beginPath();
this.moveTo(x + r, y);
this.arcTo(x + w, y, x + w, y + h, r);
this.arcTo(x + w, y + h, x, y + h, r);
this.arcTo(x, y + h, x, y, r);
this.arcTo(x, y, x + w, y, r);
this.closePath();
this.fillStyle = "#cecece";
this.fill();
this.textBaseline = 'middle';
this.textAlign = 'left';
this.fillStyle = '#fff';
this.fillText(text, x + transpading, y + h / 2);
this.restore();
return this;
}
CanvasRenderingContext2D.prototype.drawQrcode = function (img, x, y) {
self.drawStarImg(this, y);
var h = 200 + padding;
var w = 200 + padding;
var r = textRadius;
if (w < 2 * r) r = w / 2;
if (h < 2 * r) r = h / 2;
this.save();
this.beginPath();
this.moveTo(x + r, y);
this.arcTo(x + w, y, x + w, y + h, r);
this.arcTo(x + w, y + h, x, y + h, r);
this.arcTo(x, y + h, x, y, r); this.lineTo(x, y + 31 + 7);
this.lineTo(x - 10, y + 31);
this.lineTo(x, y + 31 - 7);
this.arcTo(x, y, x + w, y, r);
this.closePath();
this.strokeStyle = '#d3d3d3';
this.lineWidth = 2;
this.stroke();
this.fillStyle = "#fff";
this.fill();
this.drawImage(img, x + 10, y + 10, 200, 200)
gY = y + h + verticlaSpace;
}
},
methods: {
getData(ev) {
let self = this;
// 默认页面加载的数据
if (ev == undefined) {
self.$http.get('https://h5.tangdaoya.com/game/wechat/getstarbytype/影视大咖')
.then(res => {
let result = res.data.list;
// self.itemList = result;
self.recommendList = result;
}).catch(error => {
Toast('网络出现错误,请稍后再试');
}); } else {
// 传递参数请求接口
self.$http.get('https://h5.tangdaoya.com/game/wechat/getstarbytype/' + ev)
.then(res => {
console.log(res.data.list);
let result = res.data.list;
self.itemList = result;
}).catch(error => {
Toast('网络出现错误,请稍后再试');
});
}
},
drawResult(a, b, c, e) {
let self = this;
self.starName = a;
self.starNickName = b;
self.starID = c;
starImgObg = e.target;
Toast('正在生成中~');
self.getChatContent();
},
gameStart() {
let self = this;
var canvas = document.createElement('canvas');
canvas.width = cW;
canvas.height = cHeigth;
var context = canvas.getContext('2d');
context.fillStyle = '#ebebeb';
context.fillRect(0, 0, cW, cHeigth);
context.drawImage(headerEle, 0, 0);
self.writeHeader(context, starName);
gY = 115; if (template == 1) {
context.drawHelloText(cW / 2, gY, textRadius, com.getTime(true));
} else {
context.drawHelloText(cW / 2, gY, textRadius, com.getDateTime());
} for (var i = 0; i < chatContent.length; i++) {
var contentTemp = chatContent[i]['content'];
if (com.is_weixn()) {
contentTemp = contentTemp.replace(/xxx/ig, nickName);
} else {
contentTemp = contentTemp.replace(/是xxx吗?/ig, '');
}
if (chatContent[i] && chatContent[i]['star']) {
if (chatContent[i]['isImg']) {
// context.drawQrcode(codeEle, starTextL, gY);
context.drawQrcode(codeEle, starTextL, gY); } else {
context.drawStarText(starTextL, gY, textRadius, contentTemp, chatContent[i]['translate']);
if (i == 0 && template == 2) {
self.drawHello(context, starNickName);
gY = gY + 12;
}
}
} else {
context.drawSelfText(starTextR, gY, textRadius, contentTemp);
}
}
// context.drawImage(footerEle, 0, cHeigth - 78, 640, 78);
context.drawImage(footerEle, 0, cHeigth - 78, 640, 78);
console.log('canvas'+canvas);
console.log(canvas);
console.log(canvas.toDataURL("image/png", 0.6));
self.saveImage(canvas.toDataURL("image/png", 0.6))
},
saveImage(data) {
$('#targetImg').attr('src', data);
},
getChatContent() {
let self = this;
var server = "https://h5.tangdaoya.com/game/wechat/getChatContent/" + 2;//this.starID
self.$http.get(server).then(res => {
let result = res.data;
this.chatContent = result.chatContents;
chatContent = this.chatContent;
this.template = result['template'];
if (result['changeContent'] == 0) {
//Selector('.commonbtn-playAgain').style.display = "none";
this.ShowAgain = false;
} else if (result['changeContent'] == 1) {
this.ShowAgain = true;
}
self.gameStart();
}).catch(error => {
//Toast('网络出现错误,请稍后再试');
}); },
changeContent() {
$('#result').attr('src', '');
$('#page2').removeClass('active');
$('#page3').addClass('active');
},
drawStarImg(ctx, y) {
ctx.drawImage(starImgObg, headL, y, headW, headW);
},
writeHeader(ctx, name) {
var y = 67;
ctx.save();
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.fillStyle = '#fff';
ctx.font = "19px Arial";
ctx.fillText(com.getTime(), cW / 2, 18);
ctx.font = "29px Arial";
ctx.fillText(name, cW / 2, y);
ctx.restore();
},
drawSelfImg(ctx, y) {
//ctx.drawImage(selfImgObg, headR, y, headW, headW) ;
// ctx.drawImage(head2Ele, headR, y, headW, headW);
ctx.drawImage(head2Ele, headR, y, headW, headW);
},
getText2Arr(ctx, text, rw) {
var textArr = [];
for (var i = 0; com.getTrueLength(text) > 0; i++) {
var tl = com.cutString(text, rw);
if (ctx.measureText(text.substr(0, tl)).width < 350)
tl = tl + 1;
for (var j = 0; j < tl; j++) {
var temp = text.substr(tl, 1);
if (temp == " " || temp.charCodeAt(0) > 128 || temp == "") {
break;
}
else {
tl = tl - 1;
}
}
//ctx.fillText(text.substr(0, tl).replace(/^\s+|\s+$/, ""), offsetX , i * lineheight + offsetY);
textArr.push(text.substr(0, tl));
text = text.substr(tl);
} return textArr;
},
writeTextArr(ctx, textArr, lineheight, offsetX, offsetY) {
for (var i = 0; i < textArr.length; i++) {
ctx.fillText(textArr[i].replace(/^\s+|\s+$/, ""), offsetX, i * lineheight + offsetY);
}
}
}
}
</script>
<style lang="less" rel="stylesheet/less" scoped>
.s-content {
margin-top: 50px;
height: 1000px;
} .s-recommend {
height: 30px;
line-height: 2em;
border-bottom: 1px solid #F0F0F7;
.span-1 {
background-color: #FF4852;
color: white;
margin-left: 10px;
}
} .s-recommend-people {
width: 100%;
height: 100px;
margin-top: 5px;
border-bottom: 3px solid #F0F0F7;
ul {
width: 100%;
height: 100px;
margin: 0 auto;
li {
position: relative;
display: inline-block;
list-style: none;
width: 25%;
height: 80px;
margin-top: 10px;
margin-left: 6%;
.s-img {
width: 50px;
height: 50px;
margin: 0 auto;
img {
width: 50px;
height: 50px;
border-radius: 10px;
}
}
.s-title {
width: 50px;
height: 20px;
border: 1px solid balck;
margin: 0 auto;
text-align: center;
margin-top: 5px;
font-size: 0.8em;
}
}
}
} .s-category {
height: 30px;
line-height: 2em;
border-bottom: 1px solid #F0F0F7;
.span-2 {
background-color: #139F00;
color: white;
margin-left: 10px;
}
} .s-category-a {
height: 50px;
margin-top: 5px;
a {
border: 1px solid #9b9b9b;
display: inline-block;
border-radius: 10px;
padding: .15rem 0.31rem;
display: inline-block;
margin-top: 12px;
height: 25px;
line-height: 1.6em;
margin-left: 10px;
}
} .s-category-list {
margin-top: 10px;
height: 700px;
ul {
width: 100%;
height: 100%;
li {
border-bottom: 1px solid #F0F0F7;
width: 100%;
height: 80px;
margin-top: 10px;
.s-a-1 {
float: left;
width: 78%;
height: 80px;
.s-a-img {
float: left;
width: 60px;
height: 60px;
background-color: gray;
margin-top: 10px;
margin-left: 10px;
border-radius: 10px;
img {
width: 60px;
height: 60px;
border-radius: 10px;
}
}
.s-a-title {
float: left;
height: 60px;
margin-top: 10px;
margin-left: 5px;
.s-a-title-name {
margin-top: 10px;
color: black;
font-size: 0.8em;
}
.s-a-title-play {
margin-top: 10px;
.s-people {
font-size: 0.8em;
}
.icon-star {
font-size: 0.9em;
}
}
}
}
.s-a-2 {
float: right;
width: 60px;
height: 27px;
border: 1px solid #EFB31D;
margin-top: 25px;
margin-right: 20px;
border-radius: 5px;
line-height: 1.8em;
text-align: center;
color: #EFB31D;
.icon-more {
display: inline-block; color: #EFB31D; }
}
}
}
} /* 制作页样式*/ .box {
display: none;
.loading {
position: relative;
width: 75px;
margin-top: 40%;
}
.loading-text {
position: relative;
text-align: center;
color: #FF4303;
margin-top: 20px auto;
font-family: "微软雅黑";
letter-spacing: 1px;
}
} .commonbtn-share {
display: inline-block;
margin: 0.5%;
padding: 0.5em 0em;
font-size: 16px;
color: white;
background-color: #FF4303;
border-radius: 40px;
width: 35%;
box-sizing: border-box;
-webkit-box-sizing: border-box;
} .active .loading {
-webkit-animation: roting 1s linner infinite;
}
</style>

vue实现微信对话的更多相关文章

  1. 使用vue开发微信公众号下SPA站点的填坑之旅

    原文发表于本人博客,点击进入使用vue开发微信公众号下SPA站点的填坑之旅 本文为我创业过程中,开发项目的填坑之旅.作为一个技术宅男,我的项目是做一个微信公众号,前后端全部自己搞定,不浪费国家一分钱^ ...

  2. VUE使用微信JDK(附踩坑记录)

    VUE使用微信分享SDK(附踩坑记录) 微信分享官方文档 安装JS-SDK npm i -S weixin-jsapi 引入包 ES5 写法 const wx = require('weixin-js ...

  3. vue实现微信分享朋友圈和朋友功能

    vue实现微信分享朋友圈和朋友功能 A-A+ haibao  2018-10-25  11  21  6.2 k  百度已收录  前端开发 温馨提示:本文共3536个字,读完预计9分钟. 这两天在开发 ...

  4. Vue开发微信公众号默认背景为灰色

    最近公司有一个项目,使用Vue开发微信公众号,开发过程遇到一个问题,即设计图的整体背景是白色的,但是公众号里默认的背景是浅灰色,如果某个页面高度没能占满一屏,就会露出浅灰色的默认背景,会显得很不协调. ...

  5. 使用Vue开发微信小程序:mpvue框架

    使用Vue开发微信小程序:mpvue框架:https://www.jianshu.com/p/8f779950bfd9

  6. vue开发微信公众号--开发准备

    由于工作项目的原因,需要使用vue开发微信公众号,但是这种微信公众号更多是将APP套了一个微信的壳子,除了前面的授权和微信有关系以外,其他的都和微信没多大的关系了,特此记录 开发流程 首先需要在电脑上 ...

  7. 纯css3配合vue实现微信语音播放效果

    前言 每次写点东西都扯两句-0-,这几天一半精力放在移动端,一半维护之前的项目.书也少看了,不过还好依旧保持一颗学习的心.对于css3我是之前有专门整理过的,因此对于原理之前也算了解.今天是项目中遇到 ...

  8. 只会Vue怎么开发小程序?vue和微信小程序的到底有哪些区别?

    写了vue项目和小程序,发现二者有许多相同之处,在此想总结一下二者的共同点和区别. 一.生命周期 先贴两张生命周期图对比下: vue生命周期 小程序生命周期 相比之下,小程序的钩子函数要简单得多. v ...

  9. ListView具有多种item布局——实现微信对话列

    这篇文章的效果也是大家常见的,各种通讯应用的对话列表都是这种方式,像微信.whatsapp.易信.米聊等.我们这篇文章也权当为回忆,形成简单的笔记.这篇文章参考了2009年Google IO中的< ...

随机推荐

  1. 用svmpredict输出的结果为空

    源程序:

  2. timer实现

    实现一个 timer 前段时间写过一篇 blog 谈到 用 timer 驱动游戏 的一个想法.当 timer 被大量使用之后,似乎自己实现一个 timer 比用系统提供的要放心一些.最近在重构以前的代 ...

  3. Linux命令发送Http GET/POST请求

    Get请求 curl命令模拟Get请求: 1.使用curl命令: curl "http://www.baidu.com" 如果这里的URL指向的是一个文件或者一幅图都可以直接下载到 ...

  4. WPF 分页控件的实现 -用户控件

    效果图:

  5. 【Python】面向对象--类的特殊成员方法

    类的特殊成员方法 1. __doc__ 表示类的描述信息 class Func(object): '''__doc__方法是用来打印类的描述信息''' def tell(self): pass def ...

  6. bootstrap-datetimepicker 开始时间与结束时间互相约束

    JS $("#start").datetimepicker({ keyboardNavigation: false, language: 'zh-CN', forceParse: ...

  7. 【codevs3160】最长公共子串 后缀数组

    题目描述 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入 读入两个字符串 输出 输出最长公共子串的长度 样例输入 yeshowmuchiloveyoumydearmotherrea ...

  8. Go语言【第十篇】:Go数据结构之:指针

    Go语言指针 Go语言中指针是很容易学习的,Go语言中使用指针可以更简单的执行一些任务.我们都知道变量是一种使用方便的占位符,用于引用计算机内存地址.Go语言的取地址符是 &,放到一个变量前使 ...

  9. javascript中var let const三种变量声明方式

    javascript中var let const三种变量声明方式 1.var  ①var表示声明了一个变量,并且可以同时初始化该变量. ②使用var语句声明的变量的作用域是当前执行位置的上下文:一个函 ...

  10. [HNOI2008]GT考试 矩阵优化DP

    ---题面--- 题解: 一开始看觉得很难,理解了之后其实还挺容易的. 首先我们考虑朴素DP: 令f[i][j]表示长串到了第i项, 与不吉利数字(模式串)匹配到了第j项的方案. 显然ans = f[ ...