POJ1753-FlipGame
2012-08-28 12:01
218 查看
第一种方法:先枚举第一行的16种情况,然后依次翻转第2、3、4行分别使上一行为同一色,然后判断第四行,若仍为同一色,则比较翻转次数;否则Impossible.
第二种方法是看了别人的思路后写的,枚举+bfs:用unsigned short记录棋子的2^16=65536种情况,将初始状态入队列,再出队列判断是否是0或65535(同一色),若是则输出,否则将由该状态翻转1次的入队列,依次类推。关键减少时间的步骤是要记录最大的棋子,比如a状态由翻转2,5两个棋子得到,那么a的下一次翻转只需从6开始,前面的情况一定出现过,因此需记录5,减少重复。
Problem: 1753 | User: wjinkun | |
Memory: 352K | Time: 16MS | |
Language: GCC | Result: Accepted |
#include <stdio.h> #include <string.h> int piece[4][4],temp_piece[4][4]; void flip(int i,int j) { temp_piece[i][j]=!temp_piece[i][j]; if(i-1>=0) temp_piece[i-1][j]=!temp_piece[i-1][j]; if(i+1<=3) temp_piece[i+1][j]=!temp_piece[i+1][j]; if(j-1>=0) temp_piece[i][j-1]=!temp_piece[i][j-1]; if(j+1<=3) temp_piece[i][j+1]=!temp_piece[i][j+1]; } int main() { int i,j,k,min=17,n; for(i=0; i<4; i++) //b1w0 { for(j=0; j<4; j++) if(getchar()=='b') piece[i][j]=1; else piece[i][j]=0; getchar(); } //全翻至白 for(i=0; i<16; i++) //第一行2^4=16种情况 { memcpy(temp_piece,piece,sizeof(piece)); n=0; for(j=0; j<4; j++) if((i&(1<<j))>>j) //第一行第j个翻转 { flip(0,j); n++; } for(j=1; j<4; j++) //翻转第2.3.4行分别使上一行为都为白 for(k=0; k<4; k++) if(temp_piece[j-1][k]) { flip(j,k); n++; } for(j=0; j<4; j++) //检查第4行是否都为白 if(temp_piece[3][j]) { n=17; break; } if(n<min) min=n; } //全翻至黑 for(i=0; i<16; i++) { memcpy(temp_piece,piece,sizeof(piece)); n=0; for(j=0; j<4; j++) if((i&(1<<j))>>j) { flip(0,j); n++; } for(j=1; j<4; j++) for(k=0; k<4; k++) if(!temp_piece[j-1][k]) { flip(j,k); n++; } for(j=0; j<4; j++) if(!temp_piece[3][j]) { n=17; break; } if(n<min) min=n; } if(n!=17) printf("%d\n",min); else printf("%s","Impossible\n"); return 0; }
第二种方法是看了别人的思路后写的,枚举+bfs:用unsigned short记录棋子的2^16=65536种情况,将初始状态入队列,再出队列判断是否是0或65535(同一色),若是则输出,否则将由该状态翻转1次的入队列,依次类推。关键减少时间的步骤是要记录最大的棋子,比如a状态由翻转2,5两个棋子得到,那么a的下一次翻转只需从6开始,前面的情况一定出现过,因此需记录5,减少重复。
Problem: 1753 | User: wjinkun | |
Memory: 588K | Time: 16MS | |
Language: GCC | Result: Accepted |
#include <stdio.h> unsigned short queue[65536][2]; //[0]记录状态,[1]记录下一次起始位置 unsigned short step[65536]; //步数 int main() { int rear=1,top=0,i,j,temp; for(i=0; i<4; i++) //b1w0 { for(j=0; j<4; j++) if(getchar()=='b') queue[0][0]|=1<<(i*4+j); getchar(); } while(rear>top) { if(queue[top][0]==0||queue[top][0]==65535) { printf("%d\n",step[queue[top][0]]); return 0; } else { for(i=queue[top][1]; i<16; i++) { temp=queue[top][0]; temp^=1<<i; if(i%4!=0) temp^=1<<(i-1); if(i%4!=3) temp^=1<<(i+1); if(i-4>=0) temp^=1<<(i-4); if(i+4<16) temp^=1<<(i+4); queue[rear][0]=temp; queue[rear++][1]=i+1; step[temp]=step[queue[top][0]]+1; } top++; } } printf("%s\n","Impossible\n"); return 0; }
相关文章推荐
- poj1753 flip game题解
- POJ1753 Flip Game
- POJ1753:Flip Game(BFS、枚举、位运算)
- POJ1753-Flip Game
- 【枚举】POJ1753 Flip Game&POJ2965 The Pilots Brothers' refrigerator
- POJ1753-Flip Game
- poj1753-Flip Game
- poj1753 - Flip Game
- POJ1753-Flip Game
- POJ1753-Flip Game
- 【poj1753】Flip Game
- poj1753 Flip Game
- 【模拟+递归+位运算】POJ1753-Flip Game
- Flip Game---poj1753(状压+bfs)
- poj1753:Flip Game解题报告
- poj1753-Flip Game 【状态压缩+bfs】
- poj1753:Flip Game
- POJ1753 Flip Game
- POJ-1753-Flip Game
- POJ 1753 : Flip Game