HDU 1885 —— Key Task 状压BFS

来源:互联网 发布:java 连接sqlserver 编辑:程序博客网 时间:2024/06/08 00:16

原题:http://acm.hdu.edu.cn/showproblem.php?pid=1885

题意:问从*到X至少走几步;

    ’ # ‘ 是墙,’ . ‘ 是空地;大写字母是门,小写字母是钥匙,字母相同才可配对,如 b 开 B ,且钥匙一直都在并非开完一扇门钥匙就失效了;


思路:手里拥有钥匙的状态,状压一下,每次走到一个点,判断在已拥有的钥匙的状态下这个点是否走过 vis[i][j][status];


#include<cstdio>#include<cstring>#include<string>#include<queue>using namespace std;const int maxn = 110;char map[maxn][maxn];bool vis[maxn][maxn][35];int n, m;int sx, sy;int f[4][2] = {-1, 0, 0, -1, 0, 1, 1, 0};struct node{int x, y;int step;int key;};int Num(char c){if(c == 'B' || c == 'b')return 1;if(c == 'G' || c == 'g')return 2;if(c == 'R' || c == 'r')return 3;if(c == 'Y' || c == 'y')return 4;}void bfs(){queue<node>q;while(!q.empty())q.pop();node a;a.x = sx, a.y = sy;a.step = 0;a.key = 0;vis[sx][sy][0] = true;q.push(a);while(!q.empty()){node b = q.front();q.pop();if(map[b.x][b.y] == 'X'){printf("Escape possible in %d steps.\n", b.step);return;}for(int i = 0;i<4;i++){node c;int nx = b.x + f[i][0];int ny = b.y + f[i][1];int key = b.key;if(nx < 0 || ny < 0 || nx >= n || ny >= m || map[nx][ny] == '#')continue;if(map[nx][ny] >= 'A' && map[nx][ny] <= 'Z' && !vis[nx][ny][key] && map[nx][ny] != 'X'){int k = Num(map[nx][ny]);if(key & (1 << k)){vis[nx][ny][key] = true;c.x = nx, c.y = ny, c.key = b.key, c.step = b.step + 1;q.push(c);}} else if(map[nx][ny] >= 'a' && map[nx][ny] <= 'z'){int k = Num(map[nx][ny]);key = key | (1 << k);if(!vis[nx][ny][key]){vis[nx][ny][key] = true;c.x = nx, c.y = ny, c.key = key, c.step = b.step + 1;q.push(c);}}else{if(!vis[nx][ny][key]){vis[nx][ny][key] = true;c.x = nx, c.y = ny, c.key = b.key, c.step = b.step + 1;q.push(c);}}}}printf("The poor student is trapped!\n");return;}int main(){while(~scanf("%d%d", &n, &m)){if(n == 0 && m == 0)break;for(int i = 0;i<n;i++){scanf("%s", map[i]);for(int j = 0;j<m;j++){if(map[i][j] == '*')sx = i, sy = j;}}memset(vis, false, sizeof vis);bfs();}return 0;}


0 0
原创粉丝点击