POJ1753 Flip Game

题目链接: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的编写。

棋盘
 012345
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;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值