题目大意
在4*4的黑白棋盘上,每个格子初始一个一个黑白值,在反转一个棋子的值的同时会使上下左右的棋子颜色也反转。问最少需要反转多少次使得所有棋子的颜色都一样。
分析
注意到如果一个位置前后反转过两次是没有意义的,也就是说每个棋子最多反转一次。并且反转的顺序也是对结果没有影响的。那么这道题就变成了一个枚举了,每个格子有反转和不反转两种状态,16个格子就是2的16次方个状态。代码
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
const int INF=999999999;
char s[6][6];
int field[6][6];//b==1 w==0
int ans=INF;
void Flip(int x,int y)
{
field[x][y]=(field[x][y]+1)%2;
if(x-1>=1)field[x-1][y]=(field[x-1][y]+1)%2;
if(x+1<=4)field[x+1][y]=(field[x+1][y]+1)%2;
if(y-1>=1)field[x][y-1]=(field[x][y-1]+1)%2;
if(y+1<=4)field[x][y+1]=(field[x][y+1]+1)%2;
}
void Check(int t)//1表示成功 0表示不成功
{
int cnt=0;
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
if(field[i][j]==1)cnt++;
if(cnt==16 || cnt==0)
ans=min(t,ans);
}
void Dfs(int x,int y,int t)
{
if(x==4 && y==4)
{
Check(t);
Flip(x,y);
Check(t+1);
Flip(x,y);
return ;
}
Flip(x,y);
Dfs(x%4+1,x/4+y,t+1);
Flip(x,y);
Dfs(x%4+1,x/4+y,t);
}
int main()
{
for(int i=1;i<=4;i++)
scanf("%s",&s[i]);
for(int i=1;i<=4;i++)
for(int j=0;j<=3;j++)
{
if(s[i][j]=='b')field[i][j+1]=1;
else field[i][j+1]=0;
}
Check(0);
Dfs(1,1,0);
if(ans!=INF)printf("%d\n",ans);
else printf("Impossible\n");
}