思路:把翻牌次数做dfs,表示某一个棋子翻和不翻会不会达到效果
AC代码
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
/*
思路:把翻牌次数做dfs,表示某一个棋子翻和不翻会不会达到效果
*/
int step;//翻拍次数
int g[4][4], flag;
int all_equal() //看看是否都是相同的颜色
{
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
if(g[i][j] != g[0][0]) return 0;
}
}
return 1;
}
void four(int x, int y) //枚举四个方向(把能改变的棋子都改变
{
g[x][y] = !g[x][y];//先把本身棋子翻掉,再去翻其它1棋子
if(x < 3){
g[x+1][y] = !g[x+1][y];
}
if(x > 0){
g[x-1][y] = !g[x-1][y];
}
if(y < 3){
g[x][y + 1] = !g[x][y+1];
}
if(y > 0){
g[x][y-1] = !g[x][y-1];
}
}
void dfs(int x, int y, int t)
{
if(t == step){ //从0,0开始翻一直翻到到达翻牌次数为止
flag = all_equal();
return;
}
if(flag || x == 4) return;//递归边界
//对该棋子x,y(和它的四个方向)进行翻 ,并自己反派次数加一(表示选该棋子)
four(x,y);
//翻下一个棋子
if(y < 3){//表示下个棋子在此棋子右侧
dfs(x,y + 1, t + 1);//次数加一
} else{
dfs(x + 1, 0, t + 1);
}
//不翻本棋子和下个棋子(在翻一遍就好了)
four(x,y);//回溯
if(y < 3){
dfs(x,y + 1, t); //因为不翻,所以不记翻牌次数
} else{
dfs(x + 1,0,t);
}
}
int main()
{
char t;
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
cin >> t;
if(t == 'b') g[i][j] = 1;
}
}
//枚举反派的次数
for(step = 0; step <= 16; step++)
{
dfs(0,0,0);//每次从0,0出开始操作
if(flag) break;
}
if(flag) {
cout << step << endl;
}else cout << "Impossible" << endl;
return 0;
}