本题采用 DFS+ 枚举的方法
思路上需要注意的是:
1、要达到最后统一正反面的目标,中间走的每一步棋先后顺序不影响最后结果。
2、每一个棋子翻偶数次相当于没翻,翻基数次才有效果。所以16个位置最多有效频数为16步。 所以一共有2^16种状态。
编程实现上需要注意的是:
关键在于DFS如何递归,利用一个deep,
1、当要进行下一步翻转时,使用DFS(deep+1)
2、当前翻转不成立,需要对下一个棋子进行翻转时,使用DFS(deep).
#include<iostream>
using namespace std;
bool chess[6][6] = {false};
int step;
bool flag;
int r[]={-1,1,0,0,0};//便于翻棋操作
int c[]={0,0,-1,1,0};
void flip(int row,int col)
{
int i;
for(i=0;i<5;i++)
chess[row+r[i]][col+c[i]]=!chess[row+r[i]][col+c[i]];
return;
}
bool judge_all()
{
int i,j;
for(i = 1; i<5;i++)
for(j = 1; j<5 ;j++)
{
if(chess[1][1] != chess[i][j])
return false;
}
return true;
}
void dfs(int row,int col,int deep)
{
if(deep == step)
{
flag = judge_all();
return ;
}
if(flag || row == 5) return ;
flip(row,col);
if(col < 4)
dfs(row,col+1,deep+1);
else dfs(row+1,1,deep+1);
flip(row,col);
if(col< 4)
dfs(row,col+1,deep);
else dfs(row+1,1,deep);
return ;
}
int main()
{
char temp;
int i,j;
for(i = 1; i<5;i++)
for(j = 1;j<5 ;j++)
{
cin>>temp;
if('b' == temp)
chess[i][j] = true;
}
for(step = 0; step <=16;step ++ )
{
dfs(1,1,0);
if(flag) break;
}
if(flag)
cout<<step<<endl;
else cout<<"Impossible"<<endl;
//system("pause");
return 0;
}