POJ-1753 Flip Game(翻棋子)

来源:互联网 发布:文明网络标语 编辑:程序博客网 时间:2024/06/06 12:42

题目链接:点击打开链接

题目大意:翻转游戏是在一个矩形的4x4域上进行的,它的每一个16个方块上都有两面正面的棋子。每片的一边是白色的,另一边是黑色的,每一块都是黑色或白色的。每一轮你掷3到5个,这样就把他们的上侧的颜色从黑色变为白色,反之亦然。

       根据以下规则,

       1.每一轮都选择被翻转的棋子:选择16块中的任意一个。

       2.把选中的部分和所有相邻的部分都翻转到左边,右边,顶部,和选择的部分(如果有的话)。

向输出文件写入单个整数,即从给定位置获得游戏目标所需的最少轮数。如果目标最初是实现的,那么就写0。如果不可能实现目标,那么就写“不可能”的单词

解题思路:

  因为一个棋子只有两种状态,要么黑要么白,要使得整个棋盘(本题中是4*4的棋盘)都是一种颜色,最多只要16步就好了,一个棋子实际上只要翻转一次,整个棋盘最多要翻转2^16次。

 翻转次数不是很大,我们只要枚举出所有情况就好了,用dfs即可。

解题代码:

#include<iostream>using namespace std;bool map[16][16]= {false};bool flag=false;int step;int a[6]= {-1,1,0,0,0},b[6]= {0,0,-1,1,0};   //左右上中下bool judge()      //判断是否全部同色{    for(int i=1; i<=4; i++)     //五个位置,除开自身,只要判断四个        for(int j=1; j<=4; j++)        {            if(map[i][j]!=map[1][1])                return false;        }    return true;}void flip(int row,int col)     //翻转棋子{    for(int i=0; i<=4; i++)        map[row+a[i]][col+b[i]]=!map[row+a[i]][col+b[i]];    return;}void dfs(int row,int col, int deep){    if(deep==step)       //判断是否从map[1][1]翻转到当前位置    {        flag=judge();        return;    }    if(flag||row==5) return;    flip(row,col);    if(col<4)                  //将翻转后的全部遍历一遍,看是否符合        dfs(row,col+1,deep+1);    else        dfs(row+1,1,deep+1);    flip(row,col);              //若前面的循环内检验出不符合条件,则翻回来    if(col<4)        dfs(row,col+1,deep);    else        dfs(row+1,1,deep);    return;}int main(){    char fir;    for(int i=1; i<=4; i++)        for(int j=1; j<=4; j++)        {            cin>>fir;            if(fir=='b') map[i][j]=true;    //把黑棋标记为true,白旗为false        }    for(step=0; step<=16; step++)     //根据思路,一共只要走4*4(16)步    {        dfs(1,1,0);        if(flag) break;    }    if(flag)        cout<<step<<endl;    else        cout<<"Impossible"<<endl;    return 0;}






~step by step