POJ1753 Flip Game

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Fitz1318/article/details/86146329

题目链接:http://poj.org/problem?id=1753

大致题意:翻转游戏在一个长方形的4x4场地上进行,在其16个方格中分别放置双面棋子。每个棋子的一面是白色,另一面是黑色,每个都是黑色或白色朝上。每一轮你翻转3至5个,将被翻转的棋子的颜色从黑色改为白色,反之亦然。根据以下规则,每轮选择要翻转的棋子: ①选择16个中的任何一个②将所选择棋子以及该棋子相邻的上下左右棋子翻转(如果有的话)

解题思路:

①对于每个格子,它要么反转0次,要么反转1次(当然,它的邻格子也跟着反转),因为它反转偶数次和反转0次的效果是一样的,同理反转奇数次的效果和反转1次的效果是一样的。
②由于只有16个格子,我们可以选择0个格子,1个格子,2个格子,3个格子......进行反转,总的选择情况为

③当0个格子被反转时,看它是否为纯色,否则选择一个格子进行反转(有16种选择),看反转后是否为纯色,否则选择两个格子进行反转(有120种选择),看反转后是否为纯色。
④只要③中有纯色出现,就停止③,输出相应的被选择的格子个数,结束。如果16个格子都被翻转了,还是没变成纯色,则输出“Impossible”。

⑤分别写一个判断是否一个颜色的judge函数和一个翻转flip函数,在这里可以将棋盘扩大成6*6,这样保证最中间的4*4,及题目所给的棋盘的每一个棋子都有上下左右棋子。

 ⑥设所要翻转的棋子为(i,j),则对这个棋子进行翻转时需要同时翻动(i-1,j).(i+1,j)(i,j)(i,j-1)(i,j+1),这五个棋子,所以在最初可以设置一个r={-1,1,0,0,0},c={0,0,-1,1,0},便于翻转函数flip的编写。

棋盘
  0 1 2 3 4 5
0            
1   棋子 棋子 棋子 棋子  
2   棋子 棋子 棋子 棋子  
3   棋子 棋子 棋子 棋子  
4   棋子 棋子 棋子 棋子  
5            


AC代码:

#include <iostream>
using namespace std;
bool chess[6][6] = {0};
bool flag;
int deep;
int step;
int row[5] = {-1,1,0,0,0};
int col[5] = {0,0,-1,1,0};

int judge()//判断是不是全黑或全白
{
    for(int i=1; i<5; i++)
        for(int j=1; j<5; j++)
            if(chess[i][j] != chess[1][1])
                return 0;
    return 1;
}

void flip(int r,int c)//翻棋
{
    for(int i=0; i<5; i++)
        chess[r+row[i]][c+col[i]] =!chess[r+row[i]][c+col[i]];
}

void dfs(int r,int c,int deep)
{
    if(deep == step){
        flag = judge();
        return;
    }
    if(flag||r==5)
        return;
        
    //翻棋
    flip(r,c);
    if(c<4)
        dfs(r,c+1,deep+1);
    else
        dfs(r+1,1,deep+1);
        
    //不符合则翻回来
    flip(r,c);
    if(c<4)
        dfs(r,c+1,deep);
    else
        dfs(r+1,1,deep);
    return;
}
int main()
{
    char temp;
    int i,j;
    for(i=1; i<5; i++){
        for(j=1; j<5;j++){
            cin >> temp;
            if(temp == 'b')
                chess[i][j] = 1;
        }
    }
    for(step=0; step<16; step++){
        dfs(1,1,0);
        if(flag)
            break;
    }
    if(flag)
        cout << step << endl;
    else
        cout << "Impossible" << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Fitz1318/article/details/86146329