POJ Flip Game(BFS + 位运算)

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


一个翻转会带动四周,求至少要几次才能全白或者全黑,不能输出Impossible。

总共也就1 << 16 种状态,用数的位来存储就可以了。然后bfs找最快的, x ^ (1 << j) 是将x的第j位取反,怎么取反,看看棋子的位置就可以了 。



#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include <queue>
using namespace std;
char mp[5][5];
bool vis[1 << 17];
int start = 0;
struct node {
    int state, rds;
};
inline int solve(int x, int now) {
    now ^= 1 << x;
    if(x % 4 != 0) {
        now ^= 1 << (x-1);
    }
    if(x < 12) {
        now ^= 1 << (x+4);
    }
    if(x > 3) {
        now ^= 1 << (x-4);
    }
    if(x % 4 != 3) {
        now ^= 1 << (x+1);
    }
    if(!vis[now]) {
        vis[now] = 1;
        return now;
    }
    return -1;
}
void bfs() {
    queue<node> que;
    node cur;
    cur.state = start;
    cur.rds = 0;
    que.push(cur);
    vis[start] = 1;
    while (!que.empty()) {
        cur = que.front();
        que.pop();
        if(cur.state == 0 || cur.state == (1 << 16) - 1) {
            printf("%d\n", cur.rds);
            return ;
        }
        for (int i = 0; i < 16; i ++) {
                int tmp = solve(i, cur.state);
                if(tmp != -1) {
                    node N;
                    N.state = tmp;
                    N.rds = cur.rds + 1;
                    que.push(N);
                }
        }
    }
    printf("Impossible\n");
}
int main () {
    for (int i = 0; i < 4; i ++) {
        scanf("%s", mp[i]);
        for (int j = 0; j < 4; j ++) {
            start = (start << 1) + (mp[i][j] == 'b' ? 1 : 0);
        }
    }
    bfs();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值