Paint on a Wall
Posted barriery
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Paint on a Wall相关的知识,希望对你有一定的参考价值。
Paint on a Wall
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4012
搜索+状态压缩
这题刚开始以为是dp(之前写过墙是一行的题,然而是在艾神讲完之后才调出来的= =),但是想不出来怎么搞,看到n<=8数据量这么小,应该搜索可以解,然后想都没想就上去写了IDA*,结果有段代码怎么都找不到bug,一直WA。
结束后,用bfs写了遍,每次转移数最多是(2n)^2,最差的情况是2n层,所以复杂度是(2n)^(4n),然而状态去重后,状态数最多为2^(2n)种,复杂度为[(2n)^2]*[2^(2n)],由于n很小,所以不会超时。然而如果用之前的IDA*,差不多会把深度小于deep的所有解空间遍历,一定会超时。
debug用了好几个小时,最后发现是
(lower&bit[other*n+i])>0
写成了
(lower&bit[other*n+i])==1
...不想说什么什么了...
代码如下:
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #define met(a,b) memset(a,b,sizeof(a)) 5 #define mkp(state,deep) make_pair(state,deep) 6 #define X first 7 #define Y second 8 #define N 8 9 using namespace std; 10 typedef pair<int,int> P; 11 int T,n,ans,before,after; 12 char mp[2][N+1]; 13 bool state[1<<16]; 14 int bit[20]; 15 void init(){ 16 for(int i=0;i<=16;++i) 17 bit[i]=(1<<i); 18 } 19 void bfs(){ 20 int finish=(1<<(2*n))-1; 21 met(state,0); 22 queue<P>q; 23 q.push(mkp(0,0)); 24 state[0]=1; 25 while(!q.empty()){ 26 P s=q.front();q.pop(); 27 if(s.X==finish){ 28 ans=s.Y; 29 return; 30 } 31 for(int c=0;c<n;++c) 32 for(int r=0;r<2;++r) 33 if((s.X&bit[r*n+c])==0){ 34 char color=mp[r][c]; 35 int other=(int)(!r); 36 int upper=s.X; 37 int lower=s.X; 38 int deep=s.Y; 39 for(int i=c;i<n;++i){ 40 if((upper&bit[r*n+i])>0&&mp[r][i]!=color) 41 upper^=bit[r*n+i]; 42 else if((upper&bit[r*n+i])==0&&mp[r][i]==color) 43 upper|=bit[r*n+i]; 44 if((lower&bit[other*n+i])>0&&mp[other][i]!=color) 45 lower^=bit[other*n+i]; 46 else if((lower&bit[other*n+i])==0&&mp[other][i]==color) 47 lower|=bit[other*n+i]; 48 if(!state[upper]){ 49 state[upper]=1; 50 q.push(mkp(upper,deep+1)); 51 } 52 int temp; 53 if(r==0)temp=(before&upper)|(after&lower); 54 else if(r==1)temp=(after&upper)|(before&lower); 55 if(!state[temp]){ 56 state[temp]=1; 57 q.push(mkp(temp,deep+1)); 58 } 59 } 60 } 61 } 62 } 63 int main(void){ 64 init(); 65 scanf("%d",&T); 66 for(int t=1;t<=T;++t){ 67 scanf("%d\n",&n); 68 before=after=0; 69 for(int i=0;i<2*n;++i){ 70 if(i<n)before|=(1<<i); 71 else after|=(1<<i); 72 } 73 for(int i=0;i<2;++i) 74 scanf("%s",mp[i]); 75 bfs(); 76 printf("Case #%d: ",t); 77 printf("%d\n",ans); 78 } 79 }
以上是关于Paint on a Wall的主要内容,如果未能解决你的问题,请参考以下文章
自己定义View时,用到Paint Canvas的一些温故,简单的帧动画(动画一 ,"掏粪男孩Gif"顺便再提提onWindowFocusChanged)(代码片段
[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段
javascript 如果浏览器JS API支持,则此片段将Time to First Paint,Connection type和Speed发送到第一个网络跃点。脚本s