额,
题意:
给定一个4*4的黑白棋盘的初始状态,判断能否通过满足一些给定的翻转规则,使得所有棋面的颜色都一样,如果可以,输出最小步数;
分析:
我一点优化都没有,直接BFS暴搜,中间有一个state整型变量保存整个图的当前信息,因为总共就16个位,所以刚刚,取出一个状态的 时候,再将state转换为图,可能直接在每一个状态里面保存图回更快些吧,内存应该也不太
#include<iostream> #include<algorithm> #include<queue> using namespace std; struct node { int cnt; int state; node(int a=0,int b=0):cnt(a),state(b){} }; bool vis[1<<16]; int g[4][4]; char map[4][4]; int ans,num=0; queue<node> Q; void changetograph(int state) { for(int i=0;i<4*4;i++) { if(state&(1<<i)) g[i/4][i%4]=1; else g[i/4][i%4]=0; } } int changetostate(int x,int y) { int temp=0; int t[4][4]; for(int i=0;i<4;i++) for(int j=0;j<4;j++) t[i][j]=g[i][j]; t[x][y]^=1;//悲剧性的少了这一句,找了很久orz if(x-1>=0) t[x-1][y]^=1; if(y-1>=0) t[x][y-1]^=1; if(x+1<4) t[x+1][y]^=1; if(y+1<4) t[x][y+1]^=1; for(int i=0;i<4;i++) for(int j=0;j<4;j++) if(t[i][j]==1) temp|=(1<<(4*i+j)); return temp; } bool BFS() { node temp; while(!Q.empty()) { temp=Q.front(); Q.pop(); changetograph(temp.state); /*for(int i=0;i<4;i++) { for(int j=0;j<4;j++) printf("%d ",g[i][j]); printf("\n"); }*/ if(temp.state==0 || temp.state==((1<<16)-1)) { ans=temp.cnt; return true; } for(int i=0;i<4;i++) { for(int j=0;j<4;j++) { int t=changetostate(i,j); if(!vis[t]) { Q.push(node(temp.cnt+1,t)); vis[t]=true; } } } } return false; } int main() { int st=0; for(int i=0;i<4;i++) { scanf("%s",map[i]); for(int j=0;j<4;j++) { if(map[i][j]=='b') { st|=(1<<(4*i+j)); g[i][j]=1; } else g[i][j]=0; } } //for(int i=0;i<4;i++) //{ // for(int j=0;j<4;j++) // printf("%d ",g[i][j]); // printf("\n"); //} memset(vis,false,sizeof(vis)); vis[st]=true; Q.push(node(0,st)); if(BFS()) printf("%d\n",ans); else printf("Impossible\n"); return 0; }