Description
Input
Output
Sample Input
bwwb
bbwb
bwwb
bwww
Sample Output
4
题意:
在一个4X4的矩形方格上玩翻转游戏,每个方格有一个棋子,每个棋子有两个面,一个面是白色,一个面是黑色。每一轮你都可以翻3-5个棋子。规则是,随意选一个在位置[i,j]的棋子来翻转,并且连同它上下左右的4个棋子一块翻转。b代表黑色,w代表白色。这个题的目标是要么都变成黑色,要么都变成白色,问最少要多少轮达成这两个目标之一。
输入初始图,如果这个图已经正确了就输出0,如果不能达成目标就输出Impossible,否则就输出最小轮数。
这个题就是用枚举举遍所有情况,然后一个一个深搜看看是不是符合条件,符合条件直接退出,不符合则继续,由于表格只有16个,所以可以得知最多的步数只能是16,所以可以根据步数从0到16依次枚举,第一个符合条件的就是最小的步数。
参考了别人的代码
#include <iostream>
#include <string.h>
using namespace std;
int pieces[4][4],ans;
bool flag;
int dir[5][2]={0,-1,0,1,-1,0,1,0,0,0}; //用来翻棋的坐标变化
bool check() //用来检查这个图是不是已经到了目标的要求
{
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(pieces[i][j]!=pieces[0][0])
return false;
return true; //是的话返回真
}
void convert(int row,int col) //用来翻转棋子
{
for(int i=0;i<5;i++)
{
int sx=row+dir[i][0],sy=col+dir[i][1];
if(sx<0||sx>3||sy<0||sy>3)
continue;
pieces[sx][sy]=!pieces[sx][sy];
}
return;
}
void DFS(int row,int col,int step) //一行一行的搜索
{
if(ans==step)
{
flag=check();
return;
}
convert(row,col); //翻棋子
if(flag||row==4)
return;
if(col<3)
DFS(row,col+1,step+1);
else
DFS(row+1,0,step+1);
convert(row,col); //不行的话就翻回来
if(col<3)
DFS(row,col+1,step);
else
DFS(row+1,0,step);
return;
}
int main()
{
int i,j;
char temp;
memset(pieces,0,sizeof(pieces)); //初始化为0
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
cin>>temp;
if(temp=='b')
pieces[i][j]=1; //定义pieces数组存储初始图,1代表b,0代表w
}
for(ans=0;ans<=16;ans++) //对每一步产生的可能进行枚举
{
DFS(0,0,0); //每一次都从(0,0)开始搜索
if(flag)
break;
}
if(flag)
cout<<ans<<endl;
else
cout<<"Impossible"<<endl;
return 0;
}