我自己写用了暴力枚举的方法,不幸竟然超时了,网上有DFS和位操作的方法。
我的代码关键是求一组数字中组合的算法。
#include <stdio.h>
#include <MALLOC.H>
bool judge(int *k){
if(k[1]==0)
{
for(int i=2;i<=16;i++)
if(k[i]==1)
return false;
return true;
}
else
{
for(int i=2;i<=16;i++)
if(k[i]==0)
return false;
return true;
}
}
void flip(int *k,int i){
int x=(i-1)/4+1;
int y=i%4;
if(y==0)
y=4;
k[i]=!k[i];
if(x>1)
k[i-4]=!k[i-4];
if(y>1)
k[i-1]=!k[i-1];
if(x<4)
k[i+4]=!k[i+4];
if(y<4)
k[i+1]=!k[i+1];
}
bool combine(int *arr,int start,int count,int num,int k){
int i;
if(num==0)
{
return judge(arr);
}
if(count==0)
return false;
for(i=start;i<=16-count+1;i++)
{
int *new_arr=(int*)malloc(sizeof(int)*20);
for(int j=1;j<=16;j++)
new_arr[j]=arr[j];
flip(new_arr,i);
if(judge(new_arr))
{
free(new_arr);
return true;
}
if(combine(new_arr,i+1,count-1,num,k+1))
{
free(new_arr);
return true;
}
free(new_arr);
}
return false;
}
int main()
{
char s[10][10];
int k[20];
int i;
int j;
for(i=1;i<=4;i++)
scanf("%s",s[i]);
for(i=1;i<=4;i++)
for(j=1;j<=4;j++)
{
if(s[i][j-1]=='b')
k[i*4+j-4]=0;
else if(s[i][j-1]=='w')
k[i*4+j-4]=1;
}
for(i=0;i<=16;i++)
if(combine(k,1,i,i,1))
{
printf("%d",i);
break;
}
if(i==17)
printf("Impossible");
return 0;
}