您的位置:首页 > 其它

Hdu 2209 翻纸牌游戏[初识状态压缩]

2014-09-01 19:50 393 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2209

题意:说给一个,长度不超过20的01串。表示纸牌的正反面。

每反过来一张纸牌,其相邻的纸牌也要反过来。当然,两端的纸牌的翻转只影响其相邻的一张牌。

问,最少多少步才能使全部的牌都成为正面,也就是说,该串全部位0。

思路:

我们可以看到,最多才20张牌。所以,应该可以想到2进制压缩。(对于没有学过状态压缩的,可能想不到)。

把该串作为一个数的二进制来看。就很easy了。当该数变为0,也就是最终状态了。。

Code:

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 21;
const int M = 1 << 21;
bool hash[M];
int x;
char str
;
struct Node{
    int num;// are you kiding me. yeah, char is one bit. int is four..so you RE.
    int step;
    Node(){}
    Node(int s, int d){
        num = s;
        step = d;
    }
};

int ToInt(char *s){
    int ans = 0, len = strlen(s), k = 1;
    for(int i = len - 1; i >= 0 ;i --){
        ans += (s[i] - '0') * k;
        k = k * 2;
    }
    return ans;
}

void bfs(){
    memset(hash, 0, sizeof(hash));
    int len = strlen(str);
    queue<Node> q;
    q.push(Node(x, 0));
    hash[x] = true;
    while(!q.empty()){
        Node now = q.front();
        q.pop();
        int k;
        if(now.num == 0){
            printf("%d\n",now.step);
            return ;
        }
//        printf("now = %d\n", now.num);
        for(int i = 0; i < len - 1; i ++){
            k = now.num;
            if(i == 0){
                k = k ^ 3;
            }
            else k = k ^ (7 << (i - 1));
            if(!hash[k]){
                q.push(Node(k, now.step + 1));
                hash[k] = true;
            }
        }
        k = now.num;
        k = k ^ ((1 << (len - 1)) + (1 << (len - 2)));
        if(!hash[k]){
            q.push(Node(k, now.step + 1));
            hash[k] = true;
        }
    }
    puts("NO");
    return ;
}
int main(){
    while(~scanf("%s", str)){
        x = ToInt(str);
        if(x == 0){
            puts("0");
            continue;
        }
        if(x == 1 && strlen(str) == 1){
            puts("1");
            continue;
        }
        bfs();
    }
    return 0;
}


状态压缩是一个应该学习一下的点。。可以参看一下学长们的总结。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: