题目:http://poj.org/problem?id=1753
思路1:0MS
1)递归枚举第一行,16种情况;
2) 然后分别通过下一行的翻转来使上一行全‘b’或全'w';
3)一旦第一行16种情况的其中一种形成,则下面的翻转情况就唯一确定了,所以枚举量为16;
4)最后检查最后一行是否全‘b’或全‘w’来判断满不满足全‘b’或全‘w’。
思路2:
还可使用高斯消元法做
#include <cstdio>
#include <cstring>
#define INF 20
int cnt1;
char anti(char c)
{
if(c=='b') c='w';
else c='b';
return c;
}
void digui(char arr[][5],int cnt,int cur)
{
if(cur==4)
{
char arr1[5][5];
int i,j,cnt2,flag;
for(i=0;i<4;i++)
strcpy(arr1[i],arr[i]);
cnt2=cnt;
for(i=1;i<4;i++)
{
for(j=0;j<4;j++)
{
if(arr[i-1][j]=='b')
{
arr[i-1][j]=anti(arr[i-1][j]);
arr[i][j]=anti(arr[i][j]);
if(j-1>=0)
arr[i][j-1]=anti(arr[i][j-1]);
if(j+1<4)
arr[i][j+1]=anti(arr[i][j+1]);
if(i+1<4)
arr[i+1][j]=anti(arr[i+1][j]);
cnt2++;
}
}
}
flag=0;
for(i=0;i<4;i++)
{
if(arr[3][i]!='w')
flag=1;
}
if(flag==0)
{
if(cnt2<cnt1)
cnt1=cnt2;
}
for(i=0;i<4;i++)
strcpy(arr[i],arr1[i]);
cnt2=cnt;
for(i=1;i<4;i++)
{
for(j=0;j<4;j++)
{
if(arr[i-1][j]=='w')
{
arr[i-1][j]=anti(arr[i-1][j]);
arr[i][j]=anti(arr[i][j]);
if(j-1>=0)
arr[i][j-1]=anti(arr[i][j-1]);
if(j+1<4)
arr[i][j+1]=anti(arr[i][j+1]);
if(i+1<4)
arr[i+1][j]=anti(arr[i+1][j]);
cnt2++;
}
}
}
flag=0;
for(i=0;i<4;i++)
{
if(arr[3][i]!='b')
flag=1;
}
if(flag==0)
{
if(cnt2<cnt1)
cnt1=cnt2;
}
for(i=0;i<4;i++)
strcpy(arr[i],arr1[i]);
return;
}
else
{
for(int k=0;k<2;k++)
{
if(k==1)
{
arr[0][cur]=anti(arr[0][cur]);
if(cur-1>=0)
arr[0][cur-1]=anti(arr[0][cur-1]);
if(cur+1<4)
arr[0][cur+1]=anti(arr[0][cur+1]);
arr[1][cur]=anti(arr[1][cur]);
digui(arr,cnt+1,cur+1);
arr[0][cur]=anti(arr[0][cur]);
if(cur-1>=0)
arr[0][cur-1]=anti(arr[0][cur-1]);
if(cur+1<4)
arr[0][cur+1]=anti(arr[0][cur+1]);
arr[1][cur]=anti(arr[1][cur]);
}
else
{
digui(arr,cnt,cur+1);
}
}
return;
}
}
int main(){
//freopen("input.txt","r",stdin);
char arr[5][5];
for(int i=0;i<4;i++)
{
gets(arr[i]);
}
int sum=0;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(arr[i][j]=='w')
sum+=1;
if(sum==0 || sum==16)
{
printf("%d\n",0);
return 0;
}
cnt1=INF;
digui(arr,0,0);
if(cnt1==INF)
printf("Impossible\n");
else
printf("%d\n",cnt1);
return 0;
}