港真,这题,DFS太暴力了,原本还以为有什么高级方法……就是16格,flip或者不flip,2^16情况全部测试一遍,找那个使得 judge() == 1(满足全棋盘同色),同时step最小。
#include<cstdio>
#include<iostream>
using namespace std;
int chess[4][4];
int dx[4]={0,-1,0,+1};
int dy[4]={+1,0,-1,0};
int cnt=99999;
bool judge() //判断整个棋盘是否同色,是返回真,否返回假
{
bool now=chess[0][0];
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(now != chess[i][j]) return false;
}
}
return true;
}
void flip(int x,int y) //翻转(x,y)棋子及其周围的四个棋子
{
chess[x][y]=!chess[x][y];
for(int i=0;i<4;i++)
{
int next_x=x+dx[i];
int next_y=y+dy[i];
if(next_x >= 0 && next_x < 4 && next_y >= 0 && next_y < 4)
chess[next_x][next_y]=!chess[next_x][next_y];
}
}
void dfs(int x,int y,int step)
{
if (judge())
{
if (cnt > step) cnt=step;
return;
}
if (x >= 4 || y >= 4) return;
int next_x,next_y;
next_y=(y+1)%4;
next_x=(next_y > y)?x:x+1;
flip(x,y);
dfs(next_x,next_y,step+1); //翻当前棋子,搜索下一个
flip(x,y);
dfs(next_x,next_y,step); //不翻当前棋子,搜索下一个
return;
}
int main()
{
for(int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
char temp;
scanf("%c",&temp);
if(temp == 'b') chess[i][j]=1;
else chess[i][j]=0;
}
scanf("%*c");
}
dfs(0,0,0);
if(cnt == 99999) printf("Impossible\n");
else printf("%d\n",cnt);
return 0;
}