Poj_1753 Flip Game(状态压缩,bfs)

题意:

4*4棋盘上有黑白棋子,通过最小次数的转换把棋盘上的棋子变为全白色或者全黑色。每次翻转棋子都要将其上下左右都翻转,每次翻转3-5个棋子。

思路:

题目类似于之前做的Poj_2965,更简单一点。思路就是状态压缩+bfs,自己推update函数推了半天。

代码实现:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAX = 65536;

struct Node{
    bool exist;
    int times;
};

int pos;
int num;
int res;
Node lis[MAX];
unsigned short que[MAX];
void check(unsigned short cur);
unsigned short update(unsigned short cur,int type);
int main(){
    unsigned short initial = 0;
    char tmp;
    int cnt = 0;
    for( int i = 0; i < 4; i++ ){
        for( int j = 0; j < 4; j++ ){
            scanf("%c",&tmp);
            if( tmp == 'b' ){
                initial |= 1<<cnt;
            }
            cnt++;
        }
        getchar();
    }
    //check(initial);
    if( initial==0xffff || initial==0 ){
        printf("0\n");
        return 0;
    }
    for( int i = 0; i < MAX; i++ ){
        lis[i].exist = false;
        lis[i].times = 0;
    }
    pos = 0;
    num = 1;
    res = 0;
    que[pos] = initial;
    while( pos < num ){
        unsigned short cur = que[pos];
        for( int i = 0; i < 16; i++ ){
            unsigned short next = update(cur,i);
            //check(initial);
            //check(next);
            if( lis[next].exist == true ){
                continue;
            }
            if( next==0xffff || next==0 ){
                res = lis[cur].times+1;
                printf("%d\n",res);
                return 0;
            }
            lis[next].exist = true;
            lis[next].times = lis[cur].times+1;
            que[num++] = next;
        }
        pos++;
    }
    printf("Impossible\n");
    return 0;
}

unsigned short update(unsigned short cur,int type){
    unsigned short tmp = 0;
    switch(type){
    case 0:
        tmp = 0XC800;break;
    case 1:
        tmp = 0XE400;break;
    case 2:
        tmp = 0X7200;break;
    case 3:
        tmp = 0X3100;break;
    case 4:
        tmp = 0X8C80;break;
    case 5:
        tmp = 0X4E40;break;
    case 6:
        tmp = 0X2720;break;
    case 7:
        tmp = 0X1310;break;
    case 8:
        tmp = 0X08C8;break;
    case 9:
        tmp = 0X04E4;break;
    case 10:
        tmp = 0X0272;break;
    case 11:
        tmp = 0X0131;break;
    case 12:
        tmp = 0X008C;break;
    case 13:
        tmp = 0X004E;break;
    case 14:
        tmp = 0X0027;break;
    case 15:
        tmp = 0X0013;break;
    }
    return cur^tmp;
}

void check(unsigned short cur){
    for( int i = 0; i < 4; i++ ){
        for( int j = 0; j < 4; j++ ){
            printf("%d ",cur%2);
            cur /= 2;
        }
        printf("\n");
    }
    printf("\n");
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值