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 }

 

posted @ 2016-09-08 20:10  barriery  阅读(258)  评论(0编辑  收藏  举报