兩層 N×M 迷宮(N,M ≤ 10),入口 S(0,0,0),公主 P,傳送門 #(瞬間移至另一層同座標,若目標是牆則死),牆 *,平地 .。求能否在 T 時刻內到達公主。移動上下左右耗 1 時刻,層間傳送 0 時刻。
(layer, x, y, step),layer ∈ {0,1}。BFS 保證最短步數。
// 移動到 (nx, ny) 後檢查
if (maze[layer][nx][ny] == '#') {
int nl = 1 - layer; // 切換層
if (maze[nl][nx][ny] != '*') { // 目標非牆
// 傳送到另一層同座標,步數不變
push(nl, nx, ny, step);
}
// 否則此路不通(撞死)
} else {
push(layer, nx, ny, step + 1); // 普通移動
}
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 15;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int n, m, T;
char maze[2][MAXN][MAXN];
bool vis[2][MAXN][MAXN];
struct Node { int layer, x, y, step; };
bool valid(const Node& nd) {
if (nd.x < 0 || nd.x >= n || nd.y < 0 || nd.y >= m) return false;
if (maze[nd.layer][nd.x][nd.y] == '*' || maze[nd.layer][nd.x][nd.y] == '#') return false;
if (vis[nd.layer][nd.x][nd.y]) return false;
if (nd.step > T) return false;
return true;
}
bool bfs(int sx, int sy, int sl) {
queue q;
q.push({sl, sx, sy, 0});
vis[sl][sx][sy] = true;
while (!q.empty()) {
Node cur = q.front(); q.pop();
for (int d = 0; d < 4; d++) {
Node nxt = {cur.layer, cur.x + dx[d], cur.y + dy[d], cur.step + 1};
// 檢查當前層目標格
char target = maze[cur.layer][nxt.x][nxt.y];
if (target == '#') {
// 傳送門:切換層
nxt.layer = 1 - cur.layer;
nxt.step = cur.step; // 傳送不耗時
target = maze[nxt.layer][nxt.x][nxt.y];
if (target == '*') continue; // 另一層是牆,死
}
if (valid(nxt)) {
if (maze[nxt.layer][nxt.x][nxt.y] == 'P') return true;
vis[nxt.layer][nxt.x][nxt.y] = true;
q.push(nxt);
}
}
}
return false;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int tc; cin >> tc;
while (tc--) {
cin >> n >> m >> T;
int sx=0, sy=0, sl=0;
for (int l = 0; l < 2; l++)
for (int i = 0; i < n; i++) {
cin >> maze[l][i];
for (int j = 0; j < m; j++)
if (maze[l][i][j] == 'S') { sx=i; sy=j; sl=l; }
}
memset(vis, 0, sizeof(vis));
cout << (bfs(sx, sy, sl) ? "YES" : "NO") << '\n';
}
return 0;
}
vis[2][N][M] 分層標記step > T