题解:P16471 [GKS 2013 #A] Cross the maze
题目大意
给你一个迷宫,求从起点到终点的路线,要求左手扶住墙壁,并沿着墙壁行走,看起来这段话很难理解对吧,实际上就是不停的左转,不能左转时直走,不能直走时就转身右转,如果到达终点时步数小于 \(10000\) 就输出方案,否则输出 Edison ran out of energy.。
sol
很显然就是一道模拟题,按题目模拟即可,也没什么好说的,具体细节见代码注释。
:::info[code]{open}
#include <bits/stdc++.h>
using namespace std;
int T;
// 方向数组:北(N)、东(E)、南(S)、西(W) 对应的行、列偏移量
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
// 方向对应的字符:0=N,1=E,2=S,3=W
char ch[] = {'N', 'E', 'S', 'W'};
// 计算当前方向 左转90度 后的方向(左手边方向)
int f(int d) {
return (d - 1 + 4) % 4;
}
int main() {
cin >> T;
for (int t = 1; t <= T; t++) {
cout << "Case #" << t << ": ";
int n;
cin >> n;
// 存储迷宫地图,#是墙,.是路
char mp[1010][1010];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> mp[i][j];
}
}
// 起点(sx,sy) 终点(ex,ey)
int sx, sy, ex, ey;
cin >> sx >> sy >> ex >> ey;
// 当前坐标(x,y),目标坐标(tx,ty)
int x = sx, y = sy;
int tx = ex, ty = ey;
int d;
// 起点一定在四个角落,初始化机器人初始朝向
// 左上角(1,1) → 朝东(E)
if (x == 1 && y == 1) d = 1;
// 右上角(1,n) → 朝南(S)
else if (x == 1 && y == n) d = 2;
// 右下角(n,n) → 朝西(W)
else if (x == n && y == n) d = 3;
// 左下角(n,1) → 朝北(N)
else d = 0;
string ans;
// 标记是否成功到达终点
bool flag = 0;
// 最多走10000步
for (int st = 0; st < 10000; ++st) {
// 已经到达终点
if (x == tx && y == ty) {
flag = 1;
break;
}
// 优先左转(左手贴墙)
int l = f(d); // 左转后的方向
int nx = x + dx[l];
int ny = y + dy[l];
// 左转后的格子不越界且不是墙
if (nx > 0 && nx <= n && ny > 0 && ny <= n && mp[nx][ny] == '.') {
d = l; // 更新方向为左转后的方向
x = nx;
y = ny;
ans += ch[d];
continue;
}
// 左转走不了,就直走
nx = x + dx[d];
ny = y + dy[d];
// 直走的格子不越界且不是墙
if (nx > 0 && nx <= n && ny > 0 && ny <= n && mp[nx][ny] == '.') {
x = nx;
y = ny;
ans += ch[d];
continue;
}
// 左转、直走都不行,右转(顺时针转90度)
d = (d + 1) % 4;
}
if (flag) {
cout << ans.size() << '\n';
cout << ans << '\n';
} else {
cout << "Edison ran out of energy.\n";
}
}
return 0;
}

浙公网安备 33010602011771号