Flip Game
题目大意:有一个4x4的棋盘,上面有黑白棋子,每次翻转一枚棋子,翻转的时候,其上下左右若有棋子,则也跟着翻转,要求判断最少需要几次才能够将棋盘翻转成纯色棋盘,即全为黑色或者全部为白色棋子,如果不可能就输出“Impossible”。
题解:每个棋子只能翻转1次,如果翻转2次的话就相当于没有翻转,所以整个棋盘最多翻转16次就可以求出整个棋盘的状态,所以只要求出1-16的全排序(总共就2^16=65536种状态),然后进行翻转,判断,保存目前状态,递归翻转,返回状态的操作即可。
#include<iostream>
#include<cstdio>
using namespace std;
char c[5][5],m[5][5];
int ans=666666;
int jc()//检测
{
int i,j;
char cc=c[1][1];
for(i=1;i<=4;i++)
for(j=1;j<=4;j++)
if(c[i][j]!=cc)
return 0;
return 1;
}
void fz(int x,int y)
{
if(c[x][y]=='b') c[x][y]='w';
else c[x][y]='b';
}
void dg(int n,int s)
{
if(s>ans) return;
int x=(n+3)/4,y=n%4;
if(y==0) y=4;
fz(x,y);
if(x>1) fz(x-1,y);
if(x<4) fz(x+1,y);
if(y>1) fz(x,y-1);
if(y<4) fz(x,y+1);
if(jc())
{
ans=s;
return ;
}
int i,j,k;
char mm[5][5];
for(i=1;i<=4;i++) for(j=1;j<=4;j++) mm[i][j]=c[i][j];
for(i=n+1;i<=16;i++)
{
dg(i,s+1);
for(j=1;j<=4;j++)
for(k=1;k<=4;k++)
c[j][k]=mm[j][k];
}
}
int main()
{
int i,j,k;
for(i=1;i<=4;i++)
{
for(j=1;j<=4;j++)
{
cin>>c[i][j];
m[i][j]=c[i][j];
}
}
if(jc())
{
cout<<0;
return 0;
}
for(i=1;i<=16;i++)
{
dg(i,1);
for(j=1;j<=4;j++)
for(k=1;k<=4;k++)
c[j][k]=m[j][k];
}
if(ans<=16)
cout<<ans;
else
cout<<"Impossible";
return 0;
}