Dungeon Master POJ - 2251 & 胜利大逃亡 HDU - 1253 (BFS 三维迷宫)

总结两个非常相似的题目:
题目一 Dungeon Master:https://vjudge.net/problem/POJ-2251
题目二 胜利大逃亡:https://vjudge.net/problem/HDU-1253

说明:
两题都是三维迷宫逃脱类,很相似,几处小不同:
题目一没有时间限制,只问逃不逃得出去及最短时间;但是出生点终点不固定
题目二加上时间限制;但出生点和终点固定;cin也许会超时
思路
三维空间,那么数组和结构体我们可以多加个维度,然后BFS求最短路即可:
代码
题目一代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include<iomanip>
#include <stack>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
int dz[] = {0, 0, 0, 0, 1,-1};
int dx[] = {1,-1, 0, 0, 0, 0};
int dy[] = {0, 0, 1,-1, 0, 0};
struct P {
    int z, x, y;
    P(int z = 0, int x = 0, int y = 0): z(z), x(x), y(y) {}
};
char s[50][50][50];
int d[50][50][50];
int h, r, c;
int sh,sr,sc;
int eh,er,ec;
bool bfs() {
    memset(d, INF, sizeof(d));
    d[sh][sr][sc] = 0;
    queue<P> q;
    q.push(P(sh,sr,sc));
    while(!q.empty()) {
        P t = q.front(); q.pop();
        if(t.z == eh && t.x == er && t.y == ec) return true;
        for(int i = 0; i < 6; i++) {
            int mz = t.z + dz[i];
            int mx = t.x + dx[i];
            int my = t.y + dy[i];
            if(mz>=0 && mz<h && mx>=0 && mx<r && my>=0 && my<c)
                if((s[mz][mx][my]=='.' || s[mz][mx][my]=='E') && d[mz][mx][my] > d[t.z][t.x][t.y]+1) {
                    d[mz][mx][my] = d[t.z][t.x][t.y] + 1;
                    q.push(P(mz, mx, my));
                }
        }
    }
    return false;
}
int main() {

    while(cin >> h >> r >> c && h) {
        for(int u = 0; u < h; u++)
            for(int i = 0; i < r; i++)
                scanf("%s",s[u][i]);
        for(int u = 0; u < h; u++)
            for(int i = 0; i < r; i++)
                for(int j = 0; j < c; j++) {
                    if(s[u][i][j] == 'S') sh = u, sr = i, sc = j;
                    if(s[u][i][j] == 'E') eh = u, er = i, ec = j;
                }
        if(bfs()) printf("Escaped in %d minute(s).\n", d[eh][er][ec]);
        else printf("Trapped!\n");
    }
    return 0;
}
---------------------------------------------------我是分隔线--------------------------------------------------------

题目二代码:
(可以在时间上剪枝,已超时可直接“-1”)

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include<iomanip>
using namespace std;
typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL;
const int maxn = 1e4+10;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
int dz[] = {0, 0, 0, 0, 1,-1};
int dx[] = {1,-1, 0, 0, 0, 0};
int dy[] = {0, 0, 1,-1, 0, 0};
struct P {
    int z, x, y;
    P(int z = 0, int x = 0, int y = 0): z(z), x(x), y(y) {}
};
int h, r, c, t;
int s[55][55][55];
int d[55][55][55];
inline bool in_border (int mz, int mx, int my) {
    return mx>=0 && mx<r && my>=0 && my<c && mz>=0 && mz<h;
}
bool cmp (const void* p1, const void* p2) {
    return true;
}
void bfs() {
    memset(d, INF, sizeof(d));
    d[0][0][0] = 0;
    queue<P> q;
    q.push(P(0, 0, 0));
    while(!q.empty()) {
        P tmp = q.front(); q.pop();
        if(tmp.z==h-1 && tmp.x==r-1 && tmp.y==c-1) {
            if(d[tmp.z][tmp.x][tmp.y] <= t)
                cout << d[tmp.z][tmp.x][tmp.y] << endl;
            else cout << "-1" << endl;
            return;
        }
        for(int i = 0; i < 6; i++) {
            int mz = tmp.z + dz[i];
            int mx = tmp.x + dx[i];
            int my = tmp.y + dy[i];
            if(!in_border(mz, mx, my) || s[mz][mx][my]==1) continue;
            if(d[mz][mx][my] > d[tmp.z][tmp.x][tmp.y]+1) {
                q.push(P(mz, mx, my));
                d[mz][mx][my] = d[tmp.z][tmp.x][tmp.y]+1;
            }
        }
    }
    cout << "-1" << endl;
}

int main() {int T; cin >> T;
    while(T--){
        scanf("%d%d%d%d", &h, &r, &c, &t);
        for(int u = 0; u < h; u++)
        for(int i = 0; i < r; i++)
            for(int j = 0; j < c; j++)
                scanf("%d", &s[u][i][j]);
        bfs();
    }
    return 0;
}
发布了54 篇原创文章 · 获赞 43 · 访问量 1960

猜你喜欢

转载自blog.csdn.net/Jungle_st/article/details/104639706