題目:Ignatius 被關在 A×B×C 的立方體城堡中,起點 (0,0,0),終點 (A-1,B-1,C-1)。每分鐘可移動到六個相鄰坐標(上下左右前後)。城堡地圖用 0/1 表示路/牆。魔王 T 分鐘後回來,求能否在 T 分鐘內逃出(到達出口瞬間魔王回來算成功),能則輸出最少分鐘數,否則 -1。多組測試數據,A,B,C ≤ 50,T ≤ 1000。
狀態:(z, x, y) 三維坐標。
轉移:六個方向 dz,dx,dy ∈ {(1,0,0),(-1,0,0),(0,1,0),(0,-1,0),(0,0,1),(0,0,-1)}。
目標:從起點到終點的最短步數(每步耗時 1 分鐘)。
約束:不越界、不撞牆 (map[z][x][y] != 1)、不重複訪問。
(z, x, y, time)。time=0。time。time+1。scanf / 快速 IO,C++ cin/cout 需關閉同步 ios::sync_with_stdio(false); cin.tie(nullptr);。vis[z][x][y] 布爾陣列,入隊時標記,避免重複入隊導致 TLE/MLE。int dir[6][3] = {{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}}; 對應 z,x,y 三維。memset 清空 vis 與 map。ans 後,若 ans <= T 輸出 ans,否則 -1。#include <bits/stdc++.h>
using namespace std;
struct Node { int z, x, y, t; };
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int K; cin >> K;
while (K--) {
int A, B, C, T; cin >> A >> B >> C >> T;
vector> maze(A, vector(B));
for (int z = 0; z < A; ++z)
for (int x = 0; x < B; ++x)
cin >> maze[z][x];
vector>> vis(A, vector>(B, vector(C, false)));
queue q;
q.push({0, 0, 0, 0});
vis[0][0][0] = true;
int ans = -1;
int dz[6] = {1,-1,0,0,0,0};
int dx[6] = {0,0,1,-1,0,0};
int dy[6] = {0,0,0,0,1,-1};
while (!q.empty()) {
Node cur = q.front(); q.pop();
if (cur.z == A-1 && cur.x == B-1 && cur.y == C-1) {
ans = cur.t; break;
}
for (int i = 0; i < 6; ++i) {
int nz = cur.z + dz[i], nx = cur.x + dx[i], ny = cur.y + dy[i];
if (nz < 0 || nz >= A || nx < 0 || nx >= B || ny < 0 || ny >= C) continue;
if (vis[nz][nx][ny] || maze[nz][nx][ny] == '1') continue;
vis[nz][nx][ny] = true;
q.push({nz, nx, ny, cur.t + 1});
}
}
if (ans != -1 && ans <= T) cout << ans << '\n';
else cout << -1 << '\n';
}
return 0;
}
DFS 探索完整路徑才回溯,在大迷宮中會遍歷指數級路徑;BFS 層層擴展,首次到達終點即為最短路,複雜度 O(A*B*C) 穩定可控。求無權圖最短路徑,BFS 是唯一正解。
| 指標 | 複雜度 | 說明 |
|---|---|---|
| 時間 | O(A·B·C) | 每個格子最多入隊一次,6 方向常數因子 |
| 空間 | O(A·B·C) | 訪問陣列 + 隊列最大長度 |
HDU 1253 是三維 BFS 的標準模板題。關鍵在於:正確建模三維坐標與六方向移動、使用 scanf/快速 IO 處理大數據、BFS 保證最短路、時間限制判斷。掌握此題,可輕鬆應對各類三維/多維網格最短路徑問題(如 LUOGU P1046、POJ 2251 等)。