GESP6级C++考试语法知识(二十七、广度优先搜索(二、二维BFS))


第二课《迷宫王国大冒险------二维 BFS》


🌟一、故事开始:迷宫王国的宝藏

1、很久以前,在:

🏰「迷宫王国」里,

藏着一颗神秘宝石。


2、小骑士阿勇接到了任务:

找到宝藏!


3、可是问题来了:

迷宫里:

  • 有墙壁

  • 有陷阱

  • 有死胡同


4、而且:

阿勇必须走最短路线!


5、于是,他想:

"这次不能用 DFS 乱冲了!"

因为:

DFS 容易:

复制代码
一条路冲到底

结果绕远路。


6、这次应该使用BFS的方法:

于是他按照BFS方法,上路了。


🌟二、今天同学们要学什么?

今天是:

🌟二维 BFS!


上一课:

我们在一维"数字线"上移动。

今天:

我们进入:

🗺️二维地图!


🌟三、认识地图坐标

1、假设地图长这样:

复制代码
S . . #
# . . .
. . # E

2、这里:

复制代码
S = 起点
E = 终点
# = 墙
. = 可以走

3、🌟地图中的位置怎么表示?

使用:

坐标!


4、例如:

复制代码
(行, 列)

比如:

(1) 左上角:

复制代码
(0,0)

(2) 终点:

复制代码
(2,3)

🌟四、在地图里怎么移动?

小骑士每次可以:


⬆️上

⬇️下

⬅️左

➡️右


这叫:

四方向移动


🌟五、方向数组

这是 BFS 的经典的技巧!


1、🌟方向数组

复制代码
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

2、🌟什么意思?


(1)第0个方向

复制代码
(-1, 0)

表示:

向上走


(2)第1个方向

复制代码
(1, 0)

表示:

向下走


(3)第2个方向

复制代码
(0, -1)

表示:

向左走


(4)第3个方向

复制代码
(0, 1)

表示:

向右走


🌟六、BFS 如何搜索迷宫?


1、假设阿勇在:

复制代码
(0,0)

2、BFS 会:


(1)第1层

搜索:

一步能到的位置。


(2)第2层

搜索:

两步能到的位置。


(3)第3层

搜索:

三步能到的位置。


3、像不像:

🌊水波扩散?


🌟七、为什么 BFS 一定最短?

这是今天最核心的问题!


1、因为:

BFS 是按层搜索的!


2、它的搜索方式:

第一层:

1步到达


第二层:

2步到达


第三层:

3步到达


.......


3、所以:


第一次到终点,

一定是最少步数!


4、这就是:

BFS 最强大的地方!


🌟八、visited 二维数组

1、上一课:

我们用:

复制代码
vis[x]

2、今天地图是二维的。

所以:

复制代码
vis[x][y]

3、表示:

复制代码
(x,y) 是否来过

4、🌟为什么必须有 visited?

否则:

阿勇会这样:

复制代码
左 → 右 → 左 → 右

无限绕圈!


🌟九、地图越界问题(初学者易错!)

1、假设地图大小:

复制代码
n 行
m 列

2、合法位置必须满足:

复制代码
0 <= x < n
0 <= y < m

3、否则:

就会:

🚫走出地图!


🌟十、第一道迷宫题


1、🎮题目

地图:

复制代码
S . . #
# . . .
. . # E

2、要求:

求最少步数


🌟十一、BFS 参考程序


复制代码
#include <iostream>
#include <queue>
using namespace std;

struct Node
{
    int x;
    int y;
    int step;
};

char mp[105][105];

bool vis[105][105];

int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

int main()
{
    int n = 3;
    int m = 4;

    // 地图
    char temp[3][4] =
    {
        {'S','.','.','#'},
        {'#','.','.','.'},
        {'.','.','#','E'}
    };

    // 复制地图
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            mp[i][j] = temp[i][j];
        }
    }

    queue<Node> q;

    // 起点
    q.push({0,0,0});

    vis[0][0] = true;

    while(!q.empty())
    {
        Node cur = q.front();
        q.pop();

        int x = cur.x;
        int y = cur.y;

        // 到达终点
        if(mp[x][y] == 'E')
        {
            cout << "最少步数:" << cur.step << endl;
            return 0;
        }

        // 枚举四个方向
        for(int i = 0; i < 4; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];

            // 判断是否合法
            if(nx >= 0 && nx < n &&
               ny >= 0 && ny < m &&
               !vis[nx][ny] &&
               mp[nx][ny] != '#')
            {
                vis[nx][ny] = true;

                q.push({nx, ny, cur.step + 1});
            }
        }
    }

    cout << "无法到达终点" << endl;

    return 0;
}

🌟十二、程序执行过程


1、开始:

复制代码
(0,0)

进入队列。


2、然后扩展:

复制代码
(0,1)

3、再扩展:

复制代码
(1,1)
(0,2)

4、继续:

像水波一样。


5、最终:

第一次到达:

复制代码
E

时,

一定最短!


🌟十三、二维 BFS 模板


🌊二维 BFS 四步法


第一步

起点入队。


第二步

取出队头。


第三步

枚举四个方向。


第四步

合法就入队。


🌟十四、新手易犯的错误


❌错误1:忘记 visited

会无限循环。


❌错误2:忘记判断边界

数组越界。


❌错误3:墙壁也进入队列

必须:

复制代码
mp[nx][ny] != '#'

❌错误4:step 不加1

下一层步数必须:

复制代码
cur.step + 1

🌟十五、什么时候想到二维 BFS?

以后看到:


1、🏰迷宫


2、🛣️最短路径


3、🚶最少移动次数


4、🌊扩散问题


5、🔥火焰蔓延


6、🦠病毒感染


🌟就要想到:

BFS!是不是可以!


⚔️十六、课堂挑战题 ⚔️


🎮挑战1

地图:

复制代码
S . #
. . .
# . E

求最少步数。


🎮挑战2

如果:

小骑士还能:

斜着走

怎么办?


提示:

方向数组要改成:

八方向!


🌟十七、本课总结


1、🌊二维 BFS 的本质:

在地图上进行层层扩散!


2、📦BFS 的核心工具:

queue 队列


3、🧭方向数组:

专门处理移动方向


4、🚪第一次到终点:

一定最短!


5、🛑visited 必不可少:

防止重复进入!


🌟今天同学们真正学会的:

不只是走迷宫的方法。

而要掌握:

"地图中的最短路思维"。

相关推荐
卷无止境4 分钟前
C++ 存储类说明符(Storage Class Specifier)大横评
c++·后端
卷无止境14 分钟前
C++ 编程的一大坑:非常量全局变量是"万恶之源"
c++·后端
C语言小火车15 分钟前
C++ 快速排序(Quick Sort)深度精讲:分治思想、Lomuto 分区法及三数取中优化,面试手撕必会
c语言·开发语言·c++·面试·排序算法·快速排序
地平线开发者19 分钟前
【地平线 征程 6 工具链进阶教程】QAT 训练常见问题和排查
算法
地平线开发者20 分钟前
征程 6 | 直方图量化配置与校准实例
算法
地平线开发者1 小时前
征程 6E/M Matrix 开发评板使用系列(一):开箱与点亮
算法·自动驾驶
Jerry1 小时前
LeetCode 59. 螺旋矩阵 II
算法
可编程芯片开发1 小时前
基于FOC控制器的BLDC无刷直流电机控制系统matlab编程与仿真
算法
瓶中怪1 小时前
ROS2 机器人软件系统
linux·c++·python·ubuntu·vmware·ros2·机器人软件开发
从零开始的代码生活_2 小时前
NAT、代理服务与内网穿透详解
linux·服务器·网络·c++·http·智能路由器