【第十九课】BFS:广度优先搜索 (acwing-844走迷宫 / 含过程演示的视频推荐 / c++代码)

news2024/12/28 4:57:14

目录

BFS思路

可能需要看的视频和博客

代码如下

输出最短路径途径点


 

关于这种类型的题,我是有点印象的。。。当时蓝桥杯校内选拔就有这种题,当时还没学算法hhh

BFS思路

对应上图来理解BFS的方式还是很容易的,只是如何在题目中应用BFS的思想来解决问题呢?从具体的树的模型框架来看还容易理解,可是如果到了题目中这种二维数组走迷宫的形式,又该如何将我们已经理解的BFS思想对应到这种题目里面呢? 

在走迷宫问题中,

我们可以将每一个可能的步骤或者位置看作是树的一个节点,因为我们每移动一个位置,都会距起始位置远一点,每到一个新的位置,就相当于到达了树的新的一层。

如果有多个具有相同地位的满足条件的位置,这些位置就可以看做是同一层的节点。

起始位置是根节点。每一次移动都相当于从当前节点到达子节点。

通过上面的叙述相信对这种方法的实际应用有了大概的思路。

可能需要看的视频和博客

下面这两个视频里有详细的走迷宫问题的广度优先搜索的动态过程非常推荐看一下,会对BFS在迷宫问题里与在树的结构 之间的联系有更清晰的理解。

【【信息学奥赛教程】广度优先搜索算法 - 走迷宫】

【【直观的算法】如何用最短的路径走出迷宫】

我们这里用到数组模拟队列,需要回顾的可以看之前写的这篇文章

【第十一课】数组模拟栈和队列 / 单调栈 / 单调队列(滑动窗口) (c++代码 / 思路 )(acwing-828,829,830,154)

其实用数组模拟栈和队列甚至链表,其实主要就是运用数组的结构,但是更改数组下标的含义,这样的思路来模拟的。 

代码如下

#include<iostream>
#include<cstring>//memset函数的头文件
using namespace std;

typedef pair<int,int> PII;//定义 坐标对
const int N=110;
int n,m;
int g[N][N];//存储二维迷宫
int d[N][N];//存储从起点到达 每个被访问过的位置 的最短路径长度
PII q[N*N];//创建N*N大小的队列,足以容纳整个迷宫的每个位置
int bfs()
{
    int hh=0,tt=0;//定义队头和队尾
    q[0]={0,0};//将起始点存入队列

    memset(d,-1,sizeof d);//初始化迷宫所有的点为-1 表示未被访问过
    d[0][0]=0;//起始点标记为0 表示已访问,并且起始点到(0,0) (也就是其自身)的最短路径长度为0

    //表示在二维坐标系中,某点的四个相邻位置的 偏移量
    int dx[4]={-1,0,1,0};
    int dy[4]={0,1,0,-1};
    
    while(hh<=tt)//只要队列中还有 待寻找下一个满足条件的节点 的当前节点时,就继续执行循环
    {
        PII t=q[hh++];//将队头元素出队

        for(int i=0;i<4;i++)
        {
            //由于t是pair类型,可以由.first/.second访问元素(这里元素也就是x y坐标)
            //  由原来的坐标加上偏移量就得出四个方向上的坐标
            int x=t.first+dx[i];
            int y=t.second+dy[i];
            //首先要满足在迷宫大小范围内的可以通过的点(即g为0),并且未被访问过(保证了最短路)
            if(x>=0 && x<n && y>=0 && y<m && g[x][y]==0 && d[x][y]==-1)
            {
                d[x][y]=d[t.first][t.second]+1;//更新最短路径长度
                q[++tt]={x,y}; //将新位置加入队列
            }
        }
    }

    return d[n-1][m-1];//返回终点的最短路径长度
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            scanf("%d",&g[i][j]);
        }
    }

    printf("%d",bfs());
    return 0;
}

很多需要解释的都写在注释里了。

我们在对这个迷宫进行广搜的时候,其实会遍历迷宫中的所有可以走的位置。因此可以说 d 数组是用来存储从起点到达二维网格中每个点所对应的最短路径长度

我们是如何实现遍历所有可以走的位置呢?

在while循环内部,对每一个节点进行for循环遍历其周围的四个节点,如果有多种方向可选会发生什么?

上面的这两个问题其实互为对方的答案。

就是因为我们对每个方向都进行判断,或有多种可能的路径选择,才会将所有可以走的位置都遍历过,并且d数组的作用也可以用 “记录所有可行的点到起始点的最短距离”这一说法进行描述。

输出最短路径途径点

在前面代码基础上,做了一些添加。修改的的地方有注释。

#include<iostream>
#include<cstring>
using namespace std;
typedef pair<int,int> PII;
const int N=120;
int n,m;
int g[N][N],d[N][N];
PII q[N*N];
PII p[N][N];//记录前驱节点
int bfs()
{
    int hh=0,tt=0;
    q[0]={0,0};

    memset(d,-1,sizeof d);
    d[0][0]=0;

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

    while(hh<=tt)
    {
        PII t=q[hh++];

        for(int i=0;i<4;i++)
        {
            int x=t.first+dx[i];
            int y=t.second+dy[i];

            if(x>=0 && x<n && y>=0 && y<m && d[x][y]==-1 && g[x][y]==0)
            {
                d[x][y]=d[t.first][t.second]+1;
                p[x][y]=t;//记录前驱节点,表明是从位置 t 移动到 (x, y) 的
                q[++tt]={x,y};
            }
        }
    }
    //倒着输出最短路径的途径坐标点
    int x=n-1,y=m-1;
    while(x||y)
    {
        cout<<x<<" "<<y<<endl;
        auto t=p[x][y];
        x=t.first,y=t.second;
    }
    return d[n-1][m-1];
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            scanf("%d",&g[i][j]);
        }
    }
    cout<<bfs()<<endl;
    return 0;
}

这个不难理解,仔细想一下哦。


BFS先写到这。 

有问题欢迎指出,一起加油!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1418339.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】2024.01.29 克隆机

题目描述 有一台神奇的克隆机&#xff0c;可以克隆任何东西。将样品放进克隆机&#xff0c;可以克隆出一份一样的“复制品”。小明得到了 k 种珍贵的植物种子&#xff0c;依次用 A,B,C,D,...,Z 表示&#xff08;1≤k≤26&#xff09;。一开始&#xff0c;每种植物种子只有…

如何在Shopee波兰站点进行选品和销售策略

在Shopee波兰站点进行选品时&#xff0c;卖家需要考虑一些热销品类和策略&#xff0c;以提高产品的市场竞争力和销售业绩。以下是一些值得考虑的关键品类和策略&#xff0c;帮助卖家在波兰市场取得成功。 先给大家推荐一款shopee知虾数据运营工具知虾免费体验地址&#xff08;…

DS:经典算法OJ题(1)

创作不易&#xff0c;友友们给个三连呗&#xff01;&#xff01; 本文为经典算法OJ题练习&#xff0c;大部分题型都有多种思路&#xff0c;每种思路的解法博主都试过了&#xff08;去网站那里验证&#xff09;是正确的&#xff0c;大家可以参考&#xff01;&#xff01; 一、移…

【docker】Docker-compose单机容器集群编排

一、Compose的相关知识 1. Compose的相关概念 Compose是单机编排容器集群或者是分布式服务容器的应用工具。通过Compose&#xff0c;可以使用YAML文件来配置应用程序的服务。然后&#xff0c;使用一个命令&#xff0c;就可以从配置中创建并启动所有服务。 Docker-Compose是一…

VScode通过SSH连接远程服务器

一. 在VScode上安装SSH插件 直接在VScode应用商店搜索安装即可: 二. 登陆服务器的root用户 使用命令"su -"或者"sudo -i -u root"都可以。 三.用vim编辑器打开服务器的SSH配置文件,把PasswordAuthentication后面的no改为yes&#xff0c;表示SSH允许远程密…

MySql的使用方法

一.什么是MySql MySql是一种数据库管理系统&#xff0c;是用来存储数据的&#xff0c;可以有效的管理数据&#xff0c;数据库的存储介质为硬盘和内存。 和文件相比&#xff0c;它具有以下优点&#xff1a; 文件存储数据是不安全的&#xff0c;且不方便数据的查找和管理&#xf…

Java项目:基于SSM框架实现的高校毕业生就业管理系统(ssm+B/S架构+源码+数据库+毕业论文)

一、项目简介 本项目是一套ssm817基于SSM框架实现的高校毕业生就业管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调…

江科大stm32学习笔记6——GPIO输入准备

一、按键消抖 由于按键内部使用的是机械式弹簧片&#xff0c;所以在按下和松开时会产生5~10ms的抖动&#xff0c;需要通过代码来进行消抖。 二、滤波电容 在电路中&#xff0c;如果见到一端接在电路中&#xff0c;一端接地的电容&#xff0c;则可以考虑它的作用为滤波电容&am…

1.Mybatis入门

目录 前言 1入门 1.1 入门程序实现 1.2 数据准备 ​编辑 1.3 配置Mybatis 1.4 编写SQL语句 1.5 单元测试 1.6 解决SQL警告与提示 2. JDBC介绍(了解) 2.1 介绍 2.2 代码 2.3 问题分析 2.4 技术对比 3. 数据库连接池 3.1 介绍 3.2 产品 4. lombok 4.1 介绍 4.…

【李宏毅机器学习】Transformer 内容补充

视频来源&#xff1a;10.【李宏毅机器学习2021】自注意力机制 (Self-attention) (上)_哔哩哔哩_bilibili 发现一个奇怪的地方&#xff0c;如果直接看ML/DL的课程的话&#xff0c;有很多都是不完整的。开始思考是不是要科学上网。 本文用作Transformer - Attention is all you…

网页可读内容抽取 API 数据接口

网页可读内容抽取 API 数据接口 智能提取文章关键元素信息&#xff0c;智能抽取&#xff0c;多种元素信息。 1. 产品功能 智能提取网页可阅读内容&#xff1b;提供网页可阅读内容的 HTML 代码&#xff1b;支持传递网页 HTML 或网页 URL 参数&#xff1b;支持多种元素信息抽取…

Springboot入门教程详解

Springboot入门教程详解 博客主页&#xff1a;划水的阿瞒的博客主页 欢迎关注&#x1f5b1;点赞&#x1f380;收藏⭐留言✒ 系列专栏&#xff1a;Springboot入门教程详解首发时间&#xff1a;&#x1f39e;2024年1月29日&#x1f3a0; 如果觉得博主的文章还不错的话&#xff0c…

深入解析美颜SDK和动态贴纸技术的工作原理与应用

美颜SDK和动态贴纸技术作为图像处理领域的瑰宝&#xff0c;为用户提供了实时、高质量的美化效果。 一、美颜SDK的工作原理 美颜SDK是一种集成在移动应用、直播平台中的处理工具&#xff0c;通过算法实现实时美颜效果。 1.人脸检测与关键点定位 美颜的第一步是识别图像中的人…

Python基础篇: python安装

Python的安装 一、了解python二、官网找到下载链接三、安装3.1、选择自定义安装&#xff0c;并且选择添加系统变量3.2、选择软件安装位置&#xff0c;尽量安装在C盘之外的盘内&#xff0c;并且安装路径不要有中文3.3、等待进度条的完成&#xff0c;该过程会比较慢&#xff0c;请…

go语言(二十一)---- channel的关闭

channel不像文件一样需要经常去关闭&#xff0c;只有当你确实没有任何发送数据了&#xff0c;或者你想显示的结束range循环之类的&#xff0c;才去关闭channel。关闭channel后&#xff0c;无法向channel再发送数据&#xff0c;&#xff08;引发pannic错误后&#xff0c;导致接收…

(Sping Xml方式整合第三方框架)学习Spring的第十天

Spring整合mybatis 1 . 导入Mybatis整合Spring的相关坐标 <dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.13.RELEASE</version></dependency><dependency><…

C#使用OpenCvSharp4库中5个基础函数-灰度化、高斯模糊、Canny边缘检测、膨胀、腐蚀

C#使用OpenCvSharp4库中5个基础函数-灰度化、高斯模糊、Canny边缘检测、膨胀、腐蚀 使用OpenCV可以对彩色原始图像进行基本的处理&#xff0c;涉及到5个常用的处理&#xff1a; 灰度化 模糊处理 Canny边缘检测 膨胀 腐蚀 1、测试图像lena.jpg 本例中我们采用数字图像处…

微搭低代码从入门到精通01应用介绍

目录 1 学习路线图2 应用介绍3 编辑器介绍总结 低代码的概念于2014年由 Forrester 首次正式提出。其将低代码定义为&#xff1a;能够以“最少的手写代码”和设置快速开发应用、配置和部署业务应用程序。 不同应用厂商的解法不一样&#xff0c;Gartner评估了400多款低代码/无代码…

2024Cypress自动化测试开发指南!

cypress是基于JavaScript语言为编写语言的自动化测试开发工具&#xff0c;配合使用cucumber测试开发框架&#xff0c;以node.js为服务进程&#xff0c;可以简单的帮助测试人员完成需要人工手点的所有页面人机交互操作&#xff0c;可以模拟键盘和鼠标输入&#xff0c;快捷完成ca…

C++STL之map、set的使用和模拟实现

绪论​&#xff1a; “我这个人走得很慢&#xff0c;但是我从不后退。——亚伯拉罕林肯”&#xff0c;本章是接上一章搜索二叉树中红黑树的后续文章&#xff0c;若没有看过强烈建议观看&#xff0c;否则后面模拟实现部分很看懂其代码原理。本章主要讲了map、set是如何使用的&am…