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;
}
相关推荐
止观止1 小时前
告别“祖传C++”:开启你的现代C++之旅
c++·c++11·c++20·编程思想·现代c++
罗湖老棍子1 小时前
二维vector完全指南1:从定义到增删改查
数据结构·c++·算法·stl
再卷也是菜1 小时前
C++篇(22)LRU Cache
数据结构·c++·算法
语落心生1 小时前
海量数据集的AI自动化预测打标 -- 振动特征多标签分类
算法
语落心生1 小时前
海量数据集AI自动化打标 - 温度周期检测
算法
语落心生1 小时前
海量数据集的AI自动化预测打标 -- 矿业音频分类
算法
吃着火锅x唱着歌1 小时前
LeetCode 3185.构成整天的下标对数目II
算法·leetcode·职场和发展
D_evil__1 小时前
[C++高频精进] 现代C++特性:Lambda表达式
c++
鱼鱼块1 小时前
《最小栈的巧妙设计:用辅助栈实现 O(1) 获取最小值》
javascript·算法·面试