top1编程
← 返回题目
题解

迷宫

1 条题解

  • 0
    @ 2026-8-7 16:01:05

    P4890 迷宫(基础)

    解题思路

    第一步,读懂题目。 有一个 n×n 的方格迷宫,数字 0 表示可以走,数字 1 表示障碍物不能走。起点在左上角(1,1),终点是右下角(n,n),只能向上、下、左、右四个方向走,问能不能从起点走到终点。测试数据保证起点和终点都是 0。

    第二步,想到用深搜(DFS)。 从起点开始,像走迷宫一样一步一步尝试:能往哪个方向走就往哪个方向走,走不通就退回来换一个方向。把问题交给一个函数 dfs(x, y),它表示"我正在格子 (x,y),请帮我看看能不能走到终点"。

    第三步,防止绕圈。 走过的格子要标记成 1,就像在地上做个记号,免得在同一块地方转来转去浪费时间。因为 1 本来也表示障碍物,标记成 1 正好表示"这里走过了,不能再走"。

    第四步,判断出口。 只要 dfs 走到了 (n,n) 就说明成功,用一个开关 ok 记录下来。四个方向用两个小数组 dx、dy 来表示:上(-1,0)、下(1,0)、左(0,-1)、右(0,1)。还要检查新位置有没有越出迷宫的边界(1 到 n 之间),以及那个格子是不是 0。

    边界情况: 如果 n=2,只有四个格子,起点(1,1)到终点(2,2),只要中间的路线能走通就行。起点和终点本身就是 0,所以至少可以从起点出发。全部走完都到不了终点就输出 NO。

    参考代码

    // 迷宫:判断能否从(1,1)走到(n,n),0可走1不可走,DFS深搜
    #include <iostream>
    using namespace std;
    
    int n, g[12][12], ok;   // g存迷宫, ok标记是否到达终点
    int dx[4] = {-1, 1, 0, 0};
    int dy[4] = {0, 0, -1, 1};
    
    // 从(x,y)出发深搜四个方向
    void dfs(int x, int y) {
        if (x == n && y == n) { ok = 1; return; }
        g[x][y] = 1; // 走过标记为障碍,防止回头
        for (int k = 0; k < 4; k++) {
            int nx = x + dx[k], ny = y + dy[k];
            if (nx >= 1 && nx <= n && ny >= 1 && ny <= n && !g[nx][ny] && !ok)
                dfs(nx, ny);
        }
    }
    
    int main() {
        cin >> n;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                cin >> g[i][j];
        dfs(1, 1);
        cout << (ok ? "YES" : "NO") << endl;
        return 0;
    }
    

    复杂度分析

    深搜中每个格子最多被访问一次,所以时间复杂度是 O(n²)。n 最大是 10,也就是最多 100 个格子,非常快。空间上只需要存 n×n 的迷宫,也是 O(n²)。

    • 1