1 条题解

  • 0
    @ 2026-10-27 6:55:30

    思路与算法

    每个非墙格是顶点,朝上下层、前后行、左右列的六个相邻格移动各花1分钟。用队列从S开始分层BFS:弹出本层全部格子,再把时间加1。第一次弹出E时输出当前时间;队列耗尽仍没到达则输出Trapped!。用动态字符数组保存地图并把已入队格标成墙,队列存扁平下标,不需要额外距离数组。

    正确性说明

    BFS初始层只含起点,对应距离0。假设第d层恰按最短距离d到达,所有新邻居经一条边可在d+1到达;任何更短路径都应在更早层发现它们,因此第一次入队的层数就是最短距离。每格只入队一次。首次弹出E得到最少分钟数;若队列为空,所有可达格都已探索,故E不可达,Trapped!正确。分层计数与队列中每个点的距离等价。

    复杂度

    设各组地图格数总和为V,每格至多检查6个方向。读入与地图初始化O(V),BFS与队列操作O(V),总时间O(V);单组字符地图和队列共O(LRC)空间。未使用固定三维数组,行列层范围只由实际输入决定。

    易错点

    三维共有六个方向,不能只检查平面四向。每组数据要重置起点、终点、地图、队列与计时。三个0是整份输入的结束标记。题面样例和提示明确要求Escaped in X minute(s).或Trapped!,不是只输出一个数字。空行可忽略,地图行本身不能被按空格拆成单格。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        size_t L, R, C;
        while (cin >> L >> R >> C && (L || R || C)) {
            size_t plane = R * C, total = L * plane, start = 0, finish = 0;
            vector<char> a(total);
            for (size_t z = 0; z < L; ++z)
                for (size_t y = 0; y < R; ++y) {
                    string row;
                    cin >> row;
                    for (size_t x = 0; x < C; ++x) {
                        size_t p = z * plane + y * C + x;
                        a[p] = row[x];
                        if (row[x] == 'S')
                            start = p;
                        if (row[x] == 'E')
                            finish = p;
                    }
                }
            vector<size_t> q;
            q.reserve(total);
            q.push_back(start);
            a[start] = '#';
            size_t head = 0, distance = 0;
            bool found = false;
            while (head < q.size() && !found) {
                size_t until = q.size();
                while (head < until) {
                    size_t p = q[head++];
                    if (p == finish) {
                        found = true;
                        break;
                    }
                    size_t z = p / plane, y = (p % plane) / C, x = p % C;
                    auto visit = [&](size_t v) {
                        if (a[v] != '#') {
                            a[v] = '#';
                            q.push_back(v);
                        }
                    };
                    if (z)
                        visit(p - plane);
                    if (z + 1 < L)
                        visit(p + plane);
                    if (y)
                        visit(p - C);
                    if (y + 1 < R)
                        visit(p + C);
                    if (x)
                        visit(p - 1);
                    if (x + 1 < C)
                        visit(p + 1);
                }
                if (!found)
                    ++distance;
            }
            if (found)
                cout << "Escaped in " << distance << " minute(s).\n";
            else
                cout << "Trapped!\n";
        }
    }
    
    • 1

    信息

    ID
    2034
    时间
    1000ms
    内存
    64MiB
    难度
    普及−
    标签
    递交数
    0
    已通过
    0
    上传者