hdu1885 Key Task (bfs + 状态压缩)

来源:互联网 发布:apache下载32位 编辑:程序博客网 时间:2024/06/05 22:35

        其实没啥好说的,和hdu1429基本一样。。模板有了,代码改改就AC。。链接在此

题意:

        有4个钥匙,有对应4种颜色的门,有各种墙。。。出口是X,注意可能有多个X。。


思路:

        四个钥匙,状态压缩一小下,我写的可能有点乱,有点麻烦。。献丑了。。。

代码:

#include <iostream>#include <queue>#include <cstring>#include <cstdio>#include <map>using namespace std;const int maxn = 102;int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};char vis[maxn][maxn];int step[(1<<5)][maxn][maxn];int N, M;int key;struct Node{int state;int x, y;};queue<Node> q;map<char, int> Map, m;void init(){key = 0;memset(step, -1, sizeof(step));while (!q.empty()) q.pop();}bool Wall(int x, int y){if (x<0 || y<0 || x>=N || y>=M) return true;if (vis[x][y] == '#') return true;return false;}//判断在state状态下,能否打开目前的门bool door(int x, int y, int state){if (vis[x][y] >= 'A' && vis[x][y] <= 'Z' && vis[x][y] != 'X'){int s = Map[vis[x][y]];if (((1<<s) & state) != 0)return false;elsereturn true;}return false;}int bfs(){while (!q.empty()){Node n = q.front();q.pop();//if (step[n.state][n.x][n.y] >= T) return -1;if (vis[n.x][n.y] == 'X')return step[n.state][n.x][n.y];int newstate = n.state;for (int i=0; i<4; i++){int nx = n.x + dir[i][0];int ny = n.y + dir[i][1];if (Wall(nx, ny) || door(nx, ny, n.state)) continue;if (step[newstate][nx][ny] != -1) continue;if (vis[nx][ny] >= 'a' && vis[nx][ny] <= 'z')newstate = ((1<<m[vis[nx][ny]]) | n.state);elsenewstate = n.state;Node tmp;tmp.state = newstate, tmp.x = nx, tmp.y = ny;step[newstate][nx][ny] = step[n.state][n.x][n.y] + 1;q.push(tmp);}}return -1;}int main(){Map['B'] = 1;Map['Y'] = 2;Map['R'] = 3;Map['G'] = 4;m['b'] = 1;m['y'] = 2;m['r'] = 3;m['g'] = 4;while (scanf("%d %d", &N, &M), N && M){getchar();init();int i, j;Node s;s.state=0;for (i=0; i<N; i++){for (j=0; j<M; j++){char c = getchar();if (c == '*')s.x = i, s.y = j;vis[i][j] = c;}getchar();}step[0][s.x][s.y] = 0;q.push(s);int ans = bfs();if (ans == -1)puts("The poor student is trapped!");elseprintf("Escape possible in %d steps.\n", ans);}return 0;}


原创粉丝点击