C++ 算法题解:迷宫寻路

题干

输入

第一行是两个数字h和w,分别是迷宫的高和宽。

接下来是h行,每行w个数字,其中0表示可以通行,1表示不可以通行。

接下来的一行是beginx和beginy两个数字,表示从哪里开始走迷宫。

再接下来的一行是endx和endy,表示终点在哪里。

例如:

6 6

1 1 1 1 1 1

1 0 0 0 0 0

1 1 1 1 1 1

0 0 1 0 1 1

0 0 1 0 0 0

0 0 0 1 1 1

1 1

5 1

表示这是一个6x6的迷宫,接下来的6行给出迷宫的形状。

接下来的1 1表示起点是( 1, 1 )

再接下来的一行5 2表示终点是( 5, 2 )

这个例子里显然是存在路径的。

输出

如果起点可以到达终点,输出yes,否则输出no。

上例中输出yes。

输入样例 1

6 6

1 1 1 1 1 1

1 0 0 0 0 0

1 1 1 1 1 1

0 0 1 0 1 1

0 0 1 0 0 0

0 0 0 1 1 1

1 1

5 1

输出样例 1

yes

输入样例 2

6 6

1 1 1 1 1 1

1 0 1 0 0 0

1 1 1 1 1 1

1 0 1 0 1 1

1 0 1 0 0 0

1 0 1 1 1 1

1 1

1 5

输出样例 2

no

题解

cpp 复制代码
#include <stdio.h>
// 定义迷宫最大尺寸
#define MAX 100
// 迷宫高,宽
int h, w;
// 迷宫定义
int maze[MAX][MAX];
// 根据题目推测可能输入矩阵左上为原点,宽为x坐标,高为y坐标
// 一步可以移动的路径上,下,左,右
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
// 判断点位是否为迷宫内未访问过的路径点
bool valid(int x, int y) {
    printf("check valid(%d, %d): maze = %d\n", x, y, maze[y][x]);
    return x >= 0 && x < h && y >= 0 && y < w && maze[y][x] == 0;
}
// 以深度优先搜索算法判断起点和终点是否联通
bool dfs(int x, int y, int ex, int ey) {    
    // 打印调试信息:当前位置和目标位置
    printf("curr:(%d, %d), end:(%d, %d)\n",x ,y ,ex ,ey);
    // 如果起点和终点重合,既抵达终点,则返回true
    if (x == ex && y == ey) {
        return true;
    }
    // 标识访问过的路径点
    maze[y][x] = -1;
    // 遍历每一个相邻路径点
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        // 判断是否为迷宫内未访问过的路径点
        if (valid(nx, ny)) {            
            // 打印调试信息:地图
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    if(i == y && j == x){
                        // 打印当前位置
                        printf("* ");
                    } else if(i == ny && j == nx){
                        // 打印下一个路径点
                        printf("@ ");
                    } else if(maze[i][j] == -1){
                        // 打印已经访问过的路径点
                        printf("x ");
                    } else {
                        // 打印迷宫
                        printf("%d ",maze[i][j]);
                    }
                }
                printf("\n");
            }
            // 以下一个新路径点为起点判断是否与终点联通
            if (dfs(nx, ny, ex, ey)) {
                // 如果联通则返回true
                return true;
            }
        }
    }
    // 如果每一个相邻路径点都不连通则返回false
    return false;
}

int main() {
    // 读入高,宽
    scanf("%d %d", &h, &w);
    // 读入行
    for (int i = 0; i < h; i++) {
        // 读入列
        for (int j = 0; j < w; j++) {
            scanf("%d ", &maze[i][j]);
        }
    }
    
    int beginx, beginy, endx, endy;
    // 读入起点
    scanf("%d %d", &beginx, &beginy);
    // 读入终点
    scanf("%d %d", &endx, &endy);

    // 检查起点终点是否可通行
    if (maze[beginx][beginy] == 1 || maze[endx][endy] == 1) {
        printf("no\n");
        return 0;
    }

    if (dfs(beginx, beginy, endx, endy)) {
        printf("yes\n");
    } else {
        printf("no\n");
    }

    return 0;
}
相关推荐
MC皮蛋侠客4 小时前
Google Test 单元测试指南
c++·单元测试·google test
艾莉丝努力练剑5 小时前
【Linux:文件】Ext系列文件系统进阶
linux·运维·服务器·c++·文件系统·文件io·ext
kkeeper~5 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
wabs6667 小时前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
2401_876964137 小时前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
basketball6167 小时前
C++ NULL 和 nullptr 区别 以及 nullptr 的核心实现
java·开发语言·c++
嗝o゚7 小时前
CANN GE 算子融合——融合算法与调度策略
算法·昇腾·cann·ge
小江的记录本8 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
Fre丸子_8 小时前
自定义文件夹选取功能
c++
Ulyanov9 小时前
用声明式语法重新定义Python桌面UI:QML+PySide6现代开发入门(一)
开发语言·python·算法·ui·系统仿真·雷达电子对抗仿真