http://poj.org/problem?id=1753
#include<iostream>
using namespace std;
typedef long long ll;
char c[5][5];
int res[5][2]={{0,0},{1,0},{0,1},{-1,0},{0,-1}};
int get(int x){//二进制数一共有几个1
return x?(x&1)+get(x>>1):0;
}
int check(int x,int y,int &s){ //将其反转
if(0<=x&&x<=3&&0<=y&&y<=3) s^=1<<(x<<2)+y;
}
int main(){
//每个格子有俩个状态:翻面 1,未翻面 0,由于翻面次数为 2那么等于未翻面,所以只有2个状态,用二进制状压枚举求解。
int fir=0; //初始值
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
cin>>c[i][j];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if (c[i][j]=='b') fir+=1<<(i<<2)+j;
int ans=1e9;
for(int i=0;i<1<<16;i++){ //初始状态到末状态的选择一共只有1<<16个这么多,大概是1e6左右,所以都跑一遍看看有没有答案即可。(1代表该格子要选择。)
int tmp=i,sum,x=fir;
if((sum=get(tmp))>=ans) continue; //若当前选择答案>=之前最优解ans,则不管
//开始BFS
for(int j=0;j<4;j++)
for(int k=0;k<4;k++){
if(tmp&1) for(int t=0;t<5;t++) check(j+res[t][0],k+res[t][1],x);
tmp>>=1;
}
if(x==0||x==(1<<16)-1) ans=sum;
}
if(ans==1e9)cout<<"Impossible"<<endl;
else cout<<ans<<endl;
}