POJ 1753 Flip Game
2014-04-16 17:32
295 查看
这一题,要用位运算,我用的是BFS,方法也很显示,不断从最开始的状态开始扩展,直到找到全白或全黑的情况再退出,visited数组用来判断是不是已经出现过,防止重复的循环。
BFS+位运算
用DFS也可以解决这道题,代码引用别人的。
DFS+位运算
效率最高的是高斯消元的方法,我暂时不会,努力学习中,代码也是别人的。
高斯消元
BFS+位运算
#include <algorithm> #include <cstdio> #include <queue> using namespace std; int matrix; struct Piece { int m; int c; }; int wei[16] = {0xC800,0xE400,0x7200,0x3100,0x8C80,0x4E40,0x2720,0x1310,0x08C8,0x04E4,0x0272,0x0131,0x008C,0x004E,0x0027,0x0013}; int main(){ int i,j; bool visited[65536]; matrix=0; char temp[5]; queue<Piece> qqq; for(i=0;i<4;i++){ scanf("%s",temp); for(j=0;j<4;j++){ if(temp[j]=='b') matrix|=(1<<(i*4+j)); } } memset(visited,false,sizeof(visited)); int ccc=-1; if(matrix==0 || matrix==0Xffff){ printf("0\n"); return 0; } Piece start; start.m=matrix; start.c=0; qqq.push(start); visited[matrix]=1; while(!qqq.empty()){ Piece p=qqq.front(); if(p.m==0 || p.m==0Xffff){ ccc=p.c; break; } qqq.pop(); p.c++; for(i=0;i<16;i++){ Piece p2=p; p2.m^=wei[i]; if(visited[p2.m]){ continue; } visited[p2.m]=true; qqq.push(p2); } } if(ccc!=-1){ printf("%d\n",ccc); } else printf("Impossible\n"); return 0; }
用DFS也可以解决这道题,代码引用别人的。
DFS+位运算
#include <iostream> using namespace std; int fanzhuan[16]; int mychess; char chess[18]; //翻转第i个,利用了按位异或,与1异或相当于翻转,与0异或相当于不转 int turn[16] = {0xC800,0xE400,0x7200,0x3100,0x8C80,0x4E40,0x2720,0x1310,0x08C8,0x04E4,0x0272,0x0131,0x008C,0x004E,0x0027,0x0013}; //我是核心部分哦~ bool dfs(int now,int level,int last )//从last开始 { if(now==level)//现在已经是第level次翻转了 { if(mychess==0||mychess==0x00ffff) return true; else return false; }else{ //还剩16-last个可供翻转,但是我还想要翻转level-now个 if(16-last<level-now) return false; for(int i =last;i<16;i++) { if(fanzhuan[i])//已经翻转过了,没必要再翻转了 continue; fanzhuan[i]=1;//翻转i mychess^=turn[i]; if(dfs(now+1,level,i))//如果我把第i个翻转后,继续进行会成功,那么返回true。如果将来不成功,再把i转回来 return true; fanzhuan[i]= 0;//既然不成功,转回来呗 mychess^=turn[i]; } return false; } } int main() { int i=0; //输入字符 while(i<16) { cin>>chess+i; i+=4; } //将字母转化为数字 mychess =0; for(i=0;i<16;i++) { if(chess[i]=='b')//b->1 mychess |=(1<<(15-i)); } if(mychess!=0&&mychess!=0xffff) { for(i=1;i<=16;i++) { //选取i个翻转 memset(fanzhuan,0,sizeof(fanzhuan)); if(dfs(0,i,0)) break; } if(i>16) printf("Impossible\n"); else printf("%d\n",i); }else { printf("0\n"); } cin>>i; return 0; }
效率最高的是高斯消元的方法,我暂时不会,努力学习中,代码也是别人的。
高斯消元
#include <iostream> using namespace std; #define SIZE 20 #define N 16 #define INF (1<<20) bool a[SIZE][SIZE]={0},isfree[SIZE]={0},x[SIZE]={0}; //isfree[i]表示x[i]为自由元 int pivot[SIZE]={0},freex[SIZE]={0},r[SIZE]={0}; //pivot[i]是第i个主元所在的列,r[i]为其所在的行;freex[i]是第i个自由元所在的列 char board[SIZE][SIZE]; int Gauss(int s) { int i,j,k,index,col,p,f,cnt; bool tmp; for (i=0;i<N;i++) for (j=0;j<N;j++) a[i][j]=0; for (i=0;i<4;i++) //构造系数矩阵A for (j=0;j<4;j++) { k = 4*i+j; a[k][k]=1; if (i>0) a[k][k-4]=1; //上 if (i<3) a[k][k+4]=1; //下 if (j>0) a[k][k-1]=1; //左 if (j<3) a[k][k+1]=1; //右 a[k] = (board[i][j]=='b')^s; } for (p=f=k=col=0; k<N && col<N; k++,col++) //消元 { for (i=k; i<N && !a[i][col]; i++); if ( (index=i)==N ) {k--;isfree[col]=true;freex[f++]=col;continue;} isfree[col] = false; pivot[p] = col; r[p++] = k; if (index!=k) for (j=col;j<=N;j++) {tmp=a[k][j];a[k][j]=a[index][j];a[index][j]=tmp;} for (i=k+1;i<N;i++) if (a[i][col]) for (j=col;j<=N;j++) a[i][j] ^= a[k][j]; } for (i=k;i<N;i++) //判定无解 if (a[i] ) return INF; int tot= (1<<f); int res = INF; for (k=0;k<tot;k++) //枚举自由变量的取值。无自由元时也可以统一进来 { index = k; //自由变量取遍k的每一个二进制位 cnt = 0; for (j=0;j<f;j++) { x[freex[j]] = (index & 1); if (x[freex[j]]) cnt++; index>>=1; } for (i=p-1;i>=0;i--) //回代求得每一个(共p个)主元的值 { x[r[i]] = a[r[i]] ; for (j=N-1; j>pivot[i]; j--) if (a[r[i]][j]) x[r[i]] ^= x[j]; if (x[r[i]]) cnt++; } if (cnt<res) res=cnt; } return res; } int main() { int i,j,tmp,ans=INF; for (i=0;i<4;i++) for (j=0;j<4;j++) cin >> board[i][j]; if ( (tmp=Gauss(0))<ans ) ans=tmp; if ( (tmp=Gauss(1))<ans ) ans=tmp; if (ans!=INF) cout << ans << endl; else cout << "Impossible" << endl; return 0; }
相关文章推荐
- poj 1753 Flip Game
- poj--1753--Flip Game(dfs好题)
- POJ 1753 Flip Game (DFS + 枚举)
- poj 1753 Flip Game
- poj1753 Flip Game(BFS+位压缩)
- POj 1753--Flip Game(位运算+BFS)
- poj-1753-Flip Game
- POJ 1753 Flip Game (DFS + 暴力枚举)
- POJ 1753 Flip Game (枚举)
- Poj 1753 Flip Game 状态压缩 + DFS
- POJ1753 Flip Game
- zoj 2050 || poj 1753 Flip Game(状态压缩 简单BFS)
- POJ 1753枚举—flip game
- poj 1753 Flip Game 高斯消元
- POJ 1753 Flip game ( 高斯消元枚举自由变量)
- POJ 1753 Flip Game (枚举 + 位运算)
- Flip Game -- POJ -- 1753
- poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)
- poj 1753 Flip Game
- POJ1753 Flip Game(AC)