poj1753 Flip Game(BFS+位压缩)
Posted ColdCode
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1753 Flip Game(BFS+位压缩)相关的知识,希望对你有一定的参考价值。
题目链接
http://poj.org/problem?id=1753
题意
一个棋盘上有16个格子,按4×4排列,每个格子有两面,两面的颜色分别为黑色和白色,游戏的每一轮选择一个格子翻动,翻动该格子意味着将该格子及其上下左右格子(如果存在的话)的黑面朝上变成白面朝上,反之亦然,游戏的目标是格子全部黑面朝上或者全部白面朝上。输入棋盘的初始状态,求最少经过多少轮可以达到游戏的目标。
思路
求最少轮数,我会想到使用bfs来解决(dfs也可以解决),但使用bfs求解,如果每个状态都直接存储下当前棋盘的话,会消耗很大内存,运算速度也非常慢,如果把黑色格子(b)看成1,白色格子(w)看成0,则16个格子对应一个16位的二进制数,可以用一个int来存储,这样就解决了内存消耗及运算速度的问题了。当棋盘状态为全白0x0000(0)或者全黑0xffff(65535)时,游戏结束。还有一个问题是用二进制位表示的棋盘如何进行翻转。假设当前棋盘为0000 0000 0000 0000,对第0行第0列位置(0,0)进行翻转,翻转后的棋盘为1100 1000 0000 0000,对应的十进制数为51200。我们也可以对剩下的15个位置进行翻转,这样可以得到16个十进制数,对应对棋盘的16个位置进行翻转操作。对于任意一个棋盘状态(十进制数表示为n)来说,如果要对(0,0)进行翻转,则翻转后棋盘状态为n^51200(^表示异或),如果对(0,1)位置进行翻转,则与翻转棋盘0000 0000 0000 0000的(0,1)位置得到的十进制数(58368)异或即可,以此类推,这样就可以对二进制位表示棋盘进行翻转操作了。
代码
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 #include <string> 6 using namespace std; 7 8 struct Node 9 { 10 int state; 11 int steps; 12 13 Node(){} 14 Node(int state, int steps):state(state), steps(steps){} 15 }; 16 17 int flip[16]; //存储16中翻转状态 18 int visit[65536]; //记录棋盘状态是否被访问过 19 queue<Node> q; 20 21 void init() //初始化 22 { 23 memset(visit, 0, sizeof(visit)); 24 while(!q.empty()) q.pop(); 25 26 int dir[4][2]={ {1, 0}, {-1, 0}, {0, 1}, {0, -1}}; 27 int temp; 28 for(int i=0; i<4; i++) //计算翻转的16种状态 29 { 30 for(int j=0; j<4; j++) 31 { 32 temp = 0; 33 temp ^= (1<<((3-i)*4 + 3-j)); 34 for(int k=0; k<4; k++) 35 { 36 int ni = i+dir[k][0]; 37 int nj = j+dir[k][1]; 38 39 if(ni>=0 && ni<4 && nj>=0 && nj<4) 40 temp ^= (1<<((3-ni)*4 + 3-nj)); 41 } 42 flip[i*4+j] = temp; 43 } 44 } 45 } 46 47 int bfs() 48 { 49 while(!q.empty()) 50 { 51 Node node = q.front(); 52 q.pop(); 53 if(node.state==0 || node.state==65535) 54 return node.steps; 55 for(int i=0; i<16; i++) 56 { 57 Node next; 58 next.state = node.state^flip[i]; 59 next.steps = node.steps+1; 60 if(!visit[next.state]) 61 { 62 visit[next.state] = 1; 63 q.push(next); 64 } 65 } 66 } 67 return -1; // "Impossible" 68 } 69 70 int main() 71 { 72 //freopen("poj1753.txt", "r", stdin); 73 string s; 74 int state = 0; 75 for(int i=0; i<4; i++) 76 { 77 cin>>s; 78 for(int j=0; j<4; j++) 79 { 80 state = state<<1; 81 if(s[j]==‘b‘) 82 state += 1; 83 } 84 } 85 86 init(); 87 q.push(Node(state, 0)); 88 visit[state] = 1; 89 90 int ans = bfs(); 91 if(ans == -1) 92 cout<<"Impossible"<<endl; 93 else cout<<ans<<endl; 94 return 0; 95 }
参考
1、http://blog.csdn.net/hackbuteer1/article/details/7392245
以上是关于poj1753 Flip Game(BFS+位压缩)的主要内容,如果未能解决你的问题,请参考以下文章