总结两个非常相似的题目:
题目一 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;
}