uestc Can You Help God Wu

状态压缩

用01表示当前格子是否是正确的颜色,然后用十进制存储。

 

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <queue>
  7 using namespace std;
  8 #define N 250007
  9 
 10 struct node
 11 {
 12     int num,step;
 13 }S;
 14 
 15 char E[3][18];
 16 int vis[70000];
 17 int n,C;
 18 
 19 int BFS(node S)
 20 {
 21     queue<node> que;
 22     que.push(S);
 23     vis[S.num] = 1;
 24     int D = ((1<<(2*n))-1);
 25     while(!que.empty())
 26     {
 27         node tmp = que.front();
 28         que.pop();
 29         if(tmp.num == D)
 30             return tmp.step;
 31         int i,j,a,b;
 32         for(i=0;i<2;i++)
 33         {
 34             for(j=0;j<n;j++)
 35             {
 36                 int pos = i*n+j;
 37                 node now;
 38                 if(tmp.num & (1<<pos)) //已经是该颜色
 39                     continue;
 40                 int Num = 0;
 41                 for(a=pos;a<(i==0?n:2*n);a++)  //往右
 42                 {
 43                     if(tmp.num & (1<<a))   //已经染好,不能再涂
 44                         break;
 45                     if(E[a/n][a%n] == E[pos/n][pos%n])
 46                         Num = Num | (1<<a);    //染色
 47                 }
 48                 for(a=pos-1;a>=(i==0?0:n);a--)  //往左
 49                 {
 50                     if(tmp.num & (1<<a))
 51                         break;
 52                     if(E[a/n][a%n] == E[pos/n][pos%n])
 53                         Num = Num | (1<<a);
 54                 }
 55                 for(pos=Num;pos!=0;pos=Num&(pos-1))  //子状态
 56                 {
 57                     if(vis[tmp.num|pos])
 58                         break;
 59                     vis[tmp.num|pos] = 1;
 60                     now.num = tmp.num|pos;
 61                     now.step = tmp.step + 1;
 62                     que.push(now);
 63                 }
 64                 pos = i*n+j;
 65                 if(i >= 1)
 66                     continue;
 67                 if(tmp.num & (1<<(n+pos)))
 68                     continue;
 69                 Num = 0;
 70                 for(a=pos;a<n;a++)  //双行往右
 71                 {
 72                     if(tmp.num & (1<<a) || tmp.num & (1<<(a+n)))
 73                         break;
 74                     if(E[a/n][a%n] == E[pos/n][pos%n])
 75                         Num = Num | (1<<a);
 76                     if(E[(a+n)/n][(a+n)%n] == E[pos/n][pos%n])
 77                         Num = Num | (1<<(a+n));
 78                 }
 79                 for(a=pos-1;a>=0;a--)  //双行往左
 80                 {
 81                     if(tmp.num & (1<<a) || tmp.num & (1<<(a+n)))
 82                         break;
 83                     if(E[a/n][a%n] == E[pos/n][pos%n])
 84                         Num = Num | (1<<a);
 85                     if(E[(a+n)/n][(a+n)%n] == E[pos/n][pos%n])
 86                         Num = Num | (1<<(a+n));
 87                 }
 88                 for(pos=Num;pos!=0;pos=Num&(pos-1))  //子状态
 89                 {
 90                     if(vis[tmp.num|pos])
 91                         continue;
 92                     vis[tmp.num|pos] = 1;
 93                     now.num = tmp.num|pos;
 94                     now.step = tmp.step + 1;
 95                     que.push(now);
 96                 }
 97             }
 98         }
 99     }
100 }
101 
102 int main()
103 {
104     int t,cs = 1,i,j;
105     scanf("%d",&t);
106     while(t--)
107     {
108         scanf("%d",&n);
109         for(i=0;i<=1;i++)
110             scanf("%s",E[i]);
111         memset(vis,0,sizeof(vis));
112         S.num = 0;
113         S.step = 0;
114         int res = BFS(S);
115         printf("Case #%d: %d\n",cs++,res);
116     }
117     return 0;
118 }

 

posted @ 2015-02-10 19:29  UsedRose  阅读(135)  评论(0编辑  收藏  举报