POJ 2251 Dungeon Master(BFS + A*)

题意:

3维迷宫,求从起点到终点最少要走的时间,若不能走到,则输出“Trapped!”

思路:

1. 求最短路径首先想到 BFS,本题稍有变化就是在于 3 维迷宫,其实和 2 维迷宫都是一样的;

2. 解法一采用了优先队列 + 估值函数,但是看来时间上并没有优化太多,同样都是 16ms;

 

解法一:BFS + A*(16ms)

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;

const int MAXN = 35;
const int dir[6][3] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};  
char gird[MAXN][MAXN][MAXN];
int L, R, C, ex, ey, ez;
bool vis[MAXN][MAXN][MAXN];

struct ST {
    int x, y, z, step, eval;
    ST(int _x, int _y, int _z, int _s, int _e) : x(_x), y(_y), z(_z), step(_s), eval(_e) {} 
    bool operator < (const ST& other) const {
        if (eval == other.eval)
            return step > other.step;
        return eval > other.eval;
    }
};

bool judge(int x, int y, int z) {
    if (gird[z][x][y] != '#' && 
        0 < x && x <= R && 0 < y && y <= C && 0 < z && z <= L) {
        return true;
    }
    return false;
}

int evaluation(int x, int y, int z) {
    return abs(ex - x) + abs(ey - y) + abs(ez - z);
}

int bfs(int x, int y, int z) {
    priority_queue<ST> Q;
    Q.push(ST(x, y, z, 0, 0));
    vis[z][x][y] = true;

    while (!Q.empty()) {
        ST s = Q.top();
        Q.pop();

        if (gird[s.z][s.x][s.y] == 'E') 
            return s.step;

        for (int i = 0; i < 6; i++) {
            int a = s.x + dir[i][0];
            int b = s.y + dir[i][1];
            int c = s.z + dir[i][2];

            if (judge(a, b, c) && !vis[c][a][b]) {
                vis[c][a][b] = true;
                int eval = s.step + 1 + evaluation(a, b, c);
                Q.push(ST(a, b, c, s.step + 1, eval));
            }
        }
    }
    return -1;
}

int main() {
    while (scanf("%d%d%d", &L, &R, &C) && L && R && C) {
        int x, y, z;
        for (int i = 1; i <= L; i++) {
            for (int j = 1; j <= R; j++) {
                scanf("%s", &gird[i][j][1]);

                for (int k = 1; k <= C; k++) {
                    if (gird[i][j][k] == 'S')
                        x = j, y = k, z = i;
                    if (gird[i][j][k] == 'E')
                        ex = j, ey = k, ez = i;
                }
            }
        }
        memset(vis, false, sizeof(vis));
        int ans = bfs(x, y, z);
        if (ans != -1)
            printf("Escaped in %d minute(s).\n", ans);
        else
            printf("Trapped!\n");
    }
    return 0;
}

解法二:普通 BFS(16ms)

#include <iostream>
#include <algorithm>
#include <deque>
using namespace std;

const int MAXN = 35;
const int dir[6][3] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};  
char gird[MAXN][MAXN][MAXN];
int L, R, C;
bool vis[MAXN][MAXN][MAXN];

struct ST {
    int x, y, z, step;
    ST(int _x, int _y, int _z, int _step) : x(_x), y(_y), z(_z), step(_step) {} 
};

bool judge(int x, int y, int z) {
    if (gird[z][x][y] != '#' && 
        0 < x && x <= R && 0 < y && y <= C && 0 < z && z <= L) {
        return true;
    }
    return false;
}

int bfs(int x, int y, int z) {
    deque<ST> Q;
    Q.push_back(ST(x, y, z, 0));
    vis[z][x][y] = true;

    while (!Q.empty()) {
        ST s = Q.front();
        Q.pop_front();

        if (gird[s.z][s.x][s.y] == 'E') 
            return s.step;

        for (int i = 0; i < 6; i++) {
            int a = s.x + dir[i][0];
            int b = s.y + dir[i][1];
            int c = s.z + dir[i][2];

            if (judge(a, b, c) && !vis[c][a][b]) {
                vis[c][a][b] = true;
                Q.push_back(ST(a, b, c, s.step + 1));
            }
        }
    }
    return -1;
}

int main() {
    while (scanf("%d%d%d", &L, &R, &C) && L && R && C) {
        int x, y, z;
        for (int i = 1; i <= L; i++) {
            for (int j = 1; j <= R; j++) {
                scanf("%s", &gird[i][j][1]);

                for (int k = 1; k <= C; k++) {
                    if (gird[i][j][k] == 'S')
                        x = j, y = k, z = i;
                }
            }
        }
        memset(vis, false, sizeof(vis));
        int ans = bfs(x, y, z);
        if (ans != -1)
            printf("Escaped in %d minute(s).\n", ans);
        else
            printf("Trapped!\n");
    }
    return 0;
}
posted @ 2013-03-19 14:10  kedebug  阅读(340)  评论(0编辑  收藏  举报