【POJ1753】Flip Game
【题目大意】
有一个4x4规格的一个棋盘,现在有16个一面黑一面白的棋子分布在这个棋盘上。
翻转一个棋子能够使它以及它上下左右的四个棋子从黑变白,从白变黑。
现在问你至少要经过多少次操作才能够使得整个棋盘的颜色相同。
【分析】
考虑到是4x4的规模,想到用BFS枚举+判重。
注意题目的内存限制是64MB,如果普通的用一个二维数组记录状态可能会超过内存限制。
考虑位运算,下面给出AC代码。
1 #include <iostream> 2 #include <fstream> 3 #include <string> 4 #include <cstdio> 5 #include <cmath> 6 #include <queue> 7 const int INF=0x7fffffff; 8 using namespace std; 9 struct map 10 { 11 int shu[6];//位运算按行存储 12 int times;//翻转次数 13 map(){memset(shu,0,sizeof(shu));} 14 }data; 15 bool hash[(1<<16)+10];//哈希表 16 17 bool test(map t);//检测 18 map change(map t,int x,int y); 19 void print();//检测函数 20 int bfs();//广搜 21 int h(map t);//哈希函数 22 23 int main() 24 { 25 int i,j; 26 //文件操作 27 //freopen("data.txt","r",stdin); 28 //freopen("out.txt","w",stdout); 29 memset(data.shu,0,sizeof(data.shu)); 30 31 //读入数据 32 for (i=1;i<=4;i++) 33 { 34 if (i!=1) getchar(); //读取换行符 35 for (j=1;j<=4;j++) 36 { 37 char temp; 38 scanf("%c",&temp); 39 //注意这里存储是从左向右存储 40 if (temp=='w') data.shu[i]=(data.shu[i]<<1)+1; 41 else data.shu[i]=(data.shu[i]<<1)+0; 42 } 43 } 44 int ans=bfs(); 45 if (ans==INF) printf("Impossible\n"); 46 else printf("%d",ans); 47 return 0; 48 } 49 bool test(map t)//检测函数 50 { 51 int cnt=0,i,j; 52 for (i=1;i<=4;i++) cnt+=t.shu[i]; 53 if (cnt==0 || cnt==(15*4)) return 1; 54 return 0; 55 } 56 int bfs() 57 { 58 queue<map>Q; 59 memset(hash,0,sizeof(hash)); 60 int i,j; 61 data.times=0; 62 hash[h(data)]=1; 63 Q.push(data);//加入队列 64 while (!Q.empty()) 65 { 66 map u=Q.front();Q.pop(); 67 if (test(u)) return u.times; 68 for (i=1;i<=4;i++) 69 for (j=1;j<=4;j++) 70 { 71 map v=u; 72 v=change(v,i,j); 73 v.times=u.times+1; 74 if (test(v)) return v.times; 75 if (hash[h(v)]==1) continue;//哈希判重 76 Q.push(v); 77 hash[h(v)]=1; 78 } 79 } 80 return INF; 81 } 82 int h(map t)//哈希函数 83 { 84 int temp=0,i,j; 85 for (i=1;i<=4;i++) temp=(temp<<4)+t.shu[i]; 86 return temp; 87 } 88 //第x行,第y个 89 map change(map t,int x,int y) 90 { 91 t.shu[x]=((t.shu[x])^(1<<(4-y)));//本身 92 t.shu[x+1]=((t.shu[x+1])^(1<<(4-y)));//上面 93 t.shu[x-1]=((t.shu[x-1])^(1<<(4-y)));//下面 94 if (y!=1) t.shu[x]=((t.shu[x])^(1<<((4-y)+1)));//左边 95 if (y!=4) t.shu[x]=((t.shu[x])^(1<<((4-y)-1)));//右边 96 return t; 97 }