hdu 5025 Saving Tang Monk[状态压缩bfs]( 2014 ACM/ICPC Asia Regional Guangzhou Online)

来源:互联网 发布:网络直播平台 合作模式 编辑:程序博客网 时间:2024/05/08 16:50

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5025

比赛的时候自己也在写这个。。但是,最后没有写出来。。不是自己写不出来。。只是,当时,思路已经很是混乱了。。表示心情很是糟糕。。其他队也已经a了。也没有心情写了。。很显然,自己比赛时的心态有待改观。。特别是正式的比赛中,心情应该比较平静。。。

题目意思:
孙悟空要救唐三藏,每杀一个蛇需要额外+1时间。钥匙必须是按顺序拿的。。

钥匙最多9把,蛇最多5个。。。

之前自己对于相同的对象,自己不知道怎么来区分,表示,又学习了,对于 相同的对象,我们可以标示他们为不同的对象。。。。。。- - 。。这也很符合人们的基本逻辑思想的。。。。

自己刚开始的做法是对钥匙和蛇一起压缩。。。但是,这样是会MLE的。。。

我们可以发现的是,我们必须按顺序来拿钥匙。。这是这个问题的突破点。。钥匙的状态直接减到10。。很的轻松。。。

Code:

#include <iostream>#include <algorithm>#include <cmath>#include <cstring>#include <cstdio>#include <queue>#include <stack>using namespace std;const int N = 104;const int dx[] = {0, 0, -1, 1};const int dy[] = {1, -1, 0, 0};int n, m, bx, by;bool vis[N][N][10][(1 << 5) + 1];char map[N][N];struct Node{    int x, y;    int step, key, s;    Node(){}    Node(int a, int b, int sx, int k, int sn){        x = a; y = b;        step = sx; key = k;        s = sn;    }};bool operator < (Node a, Node b){    if(a.step > b.step) return true;    return false;}void bfs(){    memset(vis, 0, sizeof(vis));    priority_queue<Node> q;    q.push(Node(bx, by, 0, 0, 0));    vis[bx][by][0][0] = true;    while(!q.empty()){        Node tmp1 = q.top(), tmp2;        q.pop();//        printf("%d %d key = %d snake = %d step = %d\n", tmp1.x, tmp1.y, tmp1.key, tmp1.s ,tmp1.step);        if(map[tmp1.x][tmp1.y] == 'T' && tmp1.key == m){            printf("%d\n", tmp1.step);            return ;        }        for(int i = 0; i < 4; i ++){            tmp2.x = tmp1.x + dx[i]; tmp2.y = tmp1.y + dy[i];            if(tmp2.x > n || tmp2.x < 1 || tmp2.y > n || tmp2.y < 1 || map[tmp2.x][tmp2.y] == '#') continue;//            printf("%d %d %c\n", tmp2.x, tmp2.y, map[tmp2.x][tmp2.y]);            if(map[tmp2.x][tmp2.y] >= 'a' && map[tmp2.x][tmp2.y] <= 'e'){                int snakenum = map[tmp2.x][tmp2.y] - 'a';                tmp2.key = tmp1.key;                if(tmp1.s & (1 << snakenum)){                    tmp2.step = tmp1.step + 1;                    tmp2.s = tmp1.s;                }                else {                    tmp2.s = tmp1.s | (1 << snakenum);                    tmp2.step = tmp1.step + 2;                }                if(!vis[tmp2.x][tmp2.y][tmp2.key][tmp2.s]){                    q.push(tmp2);                    vis[tmp2.x][tmp2.y][tmp2.key][tmp2.s] = true;                }            }            else {                if(map[tmp2.x][tmp2.y] > '0' && map[tmp2.x][tmp2.y] <= '9'){                    int keynum = map[tmp2.x][tmp2.y] - '0';                    if(tmp1.key == keynum - 1){                        tmp2.key = tmp1.key + 1;                    }                    else tmp2.key = tmp1.key;                    tmp2.step = tmp1.step + 1;                    tmp2.s = tmp1.s;                    if(!vis[tmp2.x][tmp2.y][tmp2.key][tmp2.s]){                        q.push(tmp2);                        vis[tmp2.x][tmp2.y][tmp2.key][tmp2.s] = true;                    }                }                else {                    tmp2.key = tmp1.key;                    tmp2.s = tmp1.s;                    tmp2.step = tmp1.step + 1;                    if(!vis[tmp2.x][tmp2.y][tmp2.key][tmp2.s]){                        q.push(tmp2);                        vis[tmp2.x][tmp2.y][tmp2.key][tmp2.s] = true;                    }                }            }        }    }    puts("impossible");}int main(){//    freopen("1.txt", "r", stdin);    while(scanf("%d %d", &n, &m) && (n || m)){        getchar();        int snake = 0;        for(int i = 1; i <= n; i ++){            for(int j = 1; j <= n; j ++){                scanf("%c", &map[i][j]);                if(map[i][j] == 'K') bx = i, by = j;                if(map[i][j] == 'S') map[i][j] = 'a' + snake ++;            }            getchar();        }        bfs();    }    return 0;}

比较DT的问题是。。。自己交G++ AC。。 C++ TLE。。。

很是无语。。。。。三观尽毁。。。

0 0
原创粉丝点击