首页 > 代码库 > hdu3278Puzzle

hdu3278Puzzle

其实最终的结果无非是中间8个方块是相同的颜色,外面16个方块是另外两种颜色。那么其实可以把外面两种颜色看作是0,中间的颜色看做是1。

那么题目就变成了把那种颜色看做1,而其它两种颜色看做0,可以用最少的步骤得到结果。

那么24个方块就可以用24位二进制来标记。那么判重的方式找到了,映射为一个int类型的整数hash

而方块的移动可以看做是位运算的组合,慢慢想想就能够用位运算直接在整数hash上运算,而得到另一个整数。

  1 #include <stdio.h>  2 #include <string.h>  3 #include <string>  4 #include <queue>  5 #include <iostream>  6 #include <map>  7 using namespace std;  8 int q[1<<24];  9 short step[1<<24]; 10 /* 11 0 1 2 3 4 5 --> 1 2 3 4 5 0 12 0 1 2 3 4 5 --> 5 0 1 2 3 4 13 6 7 8 9 10 11 ->7 8 9 19 11 6 14  15 0 6 12 18 --> 6 12 18 0 16 0 6 12 18 --> 18 0 6 12 17 1 7 13 19 --> 7 13 19 1 18 1 7 13 19 --> 19 1 7 13 19 4 20 */ 21 inline int min(const int&a, const int &b) 22 { 23     return a < b ? a : b; 24 } 25 int tmp[5],c; 26 int inline col1(int k,int s) 27 { 28     c = -1; 29     for(int i=0; i<4; i++) 30     { 31         c -= (1<<(i*6+k)); 32         tmp[i]=s&(1<<(i*6+k)); 33     } 34     s=s&c; 35     tmp[0]<<=18; 36     tmp[1]>>=6; 37     tmp[2]>>=6; 38     tmp[3]>>=6; 39     s=s+tmp[0]+tmp[1]+tmp[2]+tmp[3]; 40     return s; 41 } 42 int inline col2(int k,int s) 43 { 44     c = -1; 45     for(int i=0; i<4; i++) 46     { 47         c -= (1<<(i*6+k)); 48         tmp[i]=s&(1<<(i*6+k)); 49     } 50     s=s&c; 51     tmp[0]<<=6; 52     tmp[1]<<=6; 53     tmp[2]<<=6; 54     tmp[3]>>=18; 55     s=s+tmp[0]+tmp[1]+tmp[2]+tmp[3]; 56     return s; 57 } 58 int inline row1(int k,int s) 59 { 60     c = 63<<(k*6); 61     int tmp = c&s; 62     s -= tmp; 63     int t = tmp&(1<<(k*6)); 64     tmp -= t; 65     tmp>>=1; 66     tmp +=(t<<5); 67     return s+tmp; 68 } 69 int inline row2(int k,int s) 70 { 71     c = 63<<(k*6); 72     int tmp = c&s; 73     s -= tmp; 74     int t = tmp&(1<<(k*6+5)); 75     tmp -= t; 76     tmp<<=1; 77     tmp +=(t>>5); 78     return s+tmp; 79 } 80 void bfs() 81 { 82     int head = 0,tail = 0; 83     int cur = 0,tmp,i; 84     for(i=7; i<=10; ++i) 85         cur += 1<<i; 86     for(i=13; i<=16; ++i) 87         cur+= 1<<i; 88     step[cur] = 1; 89     q[tail++] = cur; 90      91     while(head < tail) 92     { 93         cur = q[head++]; 94         for(i=0; i<6; ++i) 95         { 96             tmp = col1(i,cur); 97             if(!step[tmp]) 98             { 99             100                 step[tmp] = step[cur] + 1;101                 q[tail++] = tmp;102             }103             tmp = col2(i,cur);104             if(!step[tmp])105             {106                 step[tmp] = step[cur] + 1;107                 q[tail++] = tmp;108             }109         }110         for(i=0; i<4; ++i)111         {112             tmp = row1(i,cur);113             if(!step[tmp])114             {115                 step[tmp] = step[cur] + 1;116                 q[tail++] = tmp;117             }118             tmp = row2(i,cur);119             if(!step[tmp])120             {121                 122                 step[tmp] = step[cur]+ 1;123                 q[tail++] = tmp;124             }125         }126     }127 }128 int main()129 {130     int t,k,i,j,w,g,b;131     scanf("%d",&t);132     char ch;133     bfs();134     for(k=1; k<=t; ++k)135     {136         w = g = b = 0;137         for(i=0; i<4; ++i)138         {139             getchar();140             for(j=0; j<6; ++j)141             {142                 scanf("%c",&ch);143                 if(ch==B)144                     b += 1<<(i*6+j);145                 else if(ch==G)146                     g += 1<<(i*6+j);147                 else148                     w += 1<<(i*6+j);149             }150         }    151         printf("Case %d: %d\n",k,min(step[b]-1,min(step[g],step[w])-1));152     }153 }

 

hdu3278Puzzle