POJ-1753 Flip Game(翻棋子)

题目链接:点击打开链接

题目大意:翻转游戏是在一个矩形的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

   




发布了37 篇原创文章 · 获赞 23 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/zsheng_/article/details/78187225