2017-10-5
解答
与开灯问题类似.从上向下看,第一行的只与本行以及下一行有关,搜索可缩小至2的N次方
代码
#include<iostream>
using namespace std;
const int N = 4;
char x[N+1][N+1],y[N+1][N+1];
int z[N+1];
void set(int i,int j){
if (x[i][j]=='b') x[i][j]='w';
else x[i][j]='b';
if (x[i][j-1]=='b') x[i][j-1]='w';
else x[i][j-1]='b';
if (x[i][j+1]=='b') x[i][j+1]='w';
else x[i][j+1]='b';
if (x[i-1][j]=='b') x[i-1][j]='w';
else x[i-1][j]='b';
if (x[i+1][j]=='b') x[i+1][j]='w';
else x[i+1][j]='b';
}
int color(char c){
int i,j,s=0;
for (j=1;j<=N;j++){
if (z[j]==1){
set(1,j);
s=s+1;
}
}
for (i=2;i<=N;i++){
for (j=1;j<=N;j++){
if (x[i-1][j]==c){
set(i,j);
s=s+1;
}
}
}
for (j=1;j<=N;j++){
if (x[N][j]==c) return N*N+1;
}
return s;
}
void init(){
int i,j;
for (i=1;i<=N;i++){
for (j=1;j<=N;j++){
x[i][j]=y[i][j];
}
}
}
int main(){
int i,j;
for (i=1;i<=N;i++){
for (j=1;j<=N;j++){
cin>>x[i][j];
y[i][j]=x[i][j];
}
}
int res=N*N+1;
for (z[1]=0;z[1]<=1;z[1]++){
for (z[2]=0;z[2]<=1;z[2]++){
for (z[3]=0;z[3]<=1;z[3]++){
for (z[4]=0;z[4]<=1;z[4]++){
init();
res=min(color('b'),res);
init();
res=min(color('w'),res);
}
}
}
}
if (res==N*N+1) cout<<"Impossible"<<endl;
else cout<<res<<endl;
return 0;
}