题解: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;
}
posted @ 2026-06-13 12:35  Synthx  阅读(6)  评论(0)    收藏  举报