http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1050
位运算+BFS
^运算表示 翻转
#include<iostream> #include<string> #include<queue> #include<cstring> using namespace std; int vis[(1<<16)+1],dir[5][2]={1,0,-1,0,0,1,0,-1,0,0}; int ANS; struct node { int step,key; }; node fir; string map[4]; queue <node> q; void flip(int i,int j,node tmp) { for(int k=0;k<5;k++) { int x=i+dir[k][0]; int y=j+dir[k][1]; if(x>=0&&x<4&&y>=0&&y<4) { tmp.key^=(1<<(x*4+y)); } } if(!vis[tmp.key]) { vis[tmp.key]=1; tmp.step++; q.push(tmp); } return ; }; void BFS() { q.push(fir); while(!q.empty()) { node t=q.front(); q.pop(); if(t.key==0||t.key==(1<<16)-1){ANS=t.step;return;} for(int i=0;i<4;i++) for(int j=0;j<4;j++) flip(i,j,t); } return; } int main() { int cas; cin>>cas; while(cas--) { memset(vis,0,sizeof(vis)); ANS=-1;int f=0; while(!q.empty())q.pop(); for(int i=0;i<4;i++) { cin>>map[i]; for(int j=0;j<4;j++) if(map[i][j]=='b') f=(f|(1<<(i*4+j))); } fir.step=0;fir.key=f; vis[f]=1; BFS(); if(ANS==-1)cout<<"Impossible"<<endl; else cout<<ANS<<endl; if(cas)cout<<endl; } }