与画家问题本质上一样,都是用枚举。需要注意的仅是一些细节上的问题。
#include <iostream>
#include <cmath>
#include <climits>
#include <string>
#include <cctype>
#include <vector>
#include <cmath>
#include <cstring>
#include <array>
using namespace std;
int board[5][6]={0};
int flip[5][6]={0};
int minblack=10000,minwhilt=10000;
int total;
bool enumerate();
bool guess();
int main(){
int i,j,minb,minw;
char c;
for(i=1;i<=4;i++){
for(j=1;j<=4;j++){
cin>>c;
if(c=='b') board[i][j]=0;
else board[i][j]=1;
}
}
if(enumerate()==true) minb=minblack;
else minb=-1;
for(int i=0;i<5;i++){
for(int j=0;j<6;j++){
flip[i][j]=0;
}
}
for(i=1;i<=4;i++){
for(j=1;j<=4;j++){
if(board[i][j]==0) board[i][j]=1;
else board[i][j]=0;
}
}
if(enumerate()==true) minw=minblack;
else minw=-1;
if(minw<0 && minb<0)
cout<<"Impossible";
else if(minb>=0 && minw<0) cout<<minb;
else if(minw>=0 && minb<0) cout<<minw;
else if(minb>=minw) cout<<minw;
else cout<<minb;
return 0;
}
bool guess()
{
int i,j;
for(i=1;i<4;i++){
for(j=1;j<=4;j++){
flip[i+1][j]=(flip[i][j]+flip[i][j-1]+flip[i][j+1]+flip[i-1][j]+board[i][j])%2;
}
}
for(j=1;j<=4;j++){
if(board[4][j]!=(flip[4][j]+flip[4][j-1]+flip[4][j+1]+flip[3][j])%2)
return(false);
}
return(true);
}
bool enumerate(){
int i=0,j,flag=0,m,n;
while(i<=16){
if(guess()==true){
flag=1;
total=0;
for(m=1;m<=4;m++){
for(n=1;n<=4;n++){
if(flip[m][n]==1) total++;
}
}
if(total<minblack) minblack=total;
}
flip[1][1]++;
j=1;
while(flip[1][j]>1){
flip[1][j]=0;
j++;
flip[1][j]++;
}
i++;
}
if(!flag) return(false);
else return(true);
}