码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1753 Flip Game

时间:2020-02-13 09:17:49      阅读:57      评论:0      收藏:0      [点我收藏+]

标签:namespace   ssi   lag   判断   思路   解决   flag   翻转   efi   

POJ 1753 Flip Game

题意

在一个4x4的棋盘上放有16枚一面黑一面白的棋子。
每次操作时,你可以选择一枚棋子,然后将这枚棋子以及它上下左右相邻的棋子(如果有的话)翻面(颜色反转)。
给定棋盘初始的样子,请问在一些操作后,是否可以将所有棋子都变成一个颜色?如果可以的话,最少需要多少步?

思路

因为每个棋子只有两种状态 \(B\) ,\(W\) 所以我们可以枚举每个棋子 或者 不翻

输入是 固定的 \(4*4\) 棋盘,一共就是 \(2^{16}\) 种情况

利用位运算来枚举 \(1 << x\) 代表 \(2^x\) ,二进制表示下的数字,只有 \(0\) 或者 \(1\) 正好可以用来解决这种枚举情况

假如 二进制上的第 \(i\) 位代表 \(1\) ,说明我们要翻转该棋子,假如为 \(0\) 不翻该棋子

枚举范围\([0,2^{16}-1]\) ,可以用 \(i,j\) 来映射到 一维数组上 \(i * 4 + j\)

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define endl '\n'
const int N = 5;
const int INF = 0x3f3f3f3f;
char g[N][N],backup[N][N];
int ans = INF;
int dx[5] = {0,0,0,1,-1};// x方向数组
int dy[5] = {0,1,-1,0,0};// y方向数组
void turn_all(int x,int y) {/
    for(int i = 0;i < 5; ++i){//改变5个方向
        int nx = x + dx[i],ny = y + dy[i];
        if(nx < 0 || nx >= 4 || ny < 0 || ny >= 4) continue;//如果越界了就不操作
        if(g[nx][ny] == 'b') g[nx][ny] = 'w';
        else g[nx][ny] = 'b';
    }
}
int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    for(int i = 0;i < 4; ++i) cin >> g[i];
    for(int op = 0;op < (1 << 16); ++op) {
        int step = 0;
        bool flag = 0;
        memcpy(backup,g,sizeof g);//备份棋盘
        for(int i = 0;i < 4; ++i) {// 位运算枚举子集
            for(int j = 0;j < 4; ++j) {
                if(op >> (i * 4 + j) & 1) {//判断 第 i*4 + j 位是否位 1
                    turn_all(i,j);
                    step ++;
                }
            }
        }
        for(int i = 0;i < 4; ++i) {// 判断棋子是否全部为一种颜色
            for(int j = 0;j < 4; ++j) {
                if(g[i][j] != g[0][0]) {
                    flag = 1;
                    break;
                }
            }
            if(flag) break;
        }
        if(flag == 0) ans = min(ans,step);// 如果全部同色,更新答案
        memcpy(g,backup,sizeof g);// 还原棋盘
    }
    if(ans == INF) cout << "Impossible";// 如果答案没有被更新,输出Impossible
    else cout << ans;
    return 0;
}

POJ 1753 Flip Game

标签:namespace   ssi   lag   判断   思路   解决   flag   翻转   efi   

原文地址:https://www.cnblogs.com/lukelmouse/p/12301988.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!