广度优先遍历搜索迷宫最短路径
思路分析
由于广度是扩散逐层的方式遍历,相当于是多条路同时跑,最后先到终点就是最短路径了。
广度优先搜索主要使用队列来进行处理
路径用一个单独的vector存储,每一个点的坐标由二维转为一维,如(2, 3)存储在vector中下标为2*col + 3,这个位置存储到达(2, 3)的节点,即每个位置存储上个节点的位置。
测试用例
请输入迷宫的行列数(例如:10 10):6 6
请输入迷宫的路径信息(0表示可以走,1表示不能走):
0 0 1 1 1 1
1 0 0 0 0 1
1 0 1 1 0 1
1 0 0 0 0 1
1 0 1 1 1 1
1 0 0 0 0 0
结果为:
* * 1 1 1 1
1 * 0 0 0 1
1 * 1 1 0 1
1 * 0 0 0 1
1 * 1 1 1 1
1 * * * * *
如果用深度优先搜索则答案路径不是最短。为
* * 1 1 1 1
1 * * * * 1
1 0 1 1 * 1
1 * * * * 1
1 * 1 1 1 1
1 * * * * *
完整代码
#include <iostream>
#include <stack>
#include <queue>
using namespace std;// 用栈来模拟递归的dfs
// 定义迷宫每个节点的四个方向,从右开始,顺时针
const int RIGHT = 0;
const int DOWN = 1;
const int LEFT = 2;
const int UP = 3;// 迷宫每个节点方向的数量
const int WAY_NUM = 4;// 定义节点向某个方向行走是否可行
const int YES = 4;
const int NO = 5;class Maze
{
public:Maze(int row, int col): _row(row), _col(col){// 二维数组的创建_pMaze = new Node * [_row];for (int i = 0; i < _row; ++i){_pMaze[i] = new Node[_col];}// 将到达(i,j)的节点对象存入 _pPath[i * _row + j]_pPath.resize(_row * _col);}// 初始化迷宫每个节点对象void initNode(int x, int y, int val){_pMaze[x][y]._x = x;_pMaze[x][y]._y = y;_pMaze[x][y]._val = val;// 节点四个方向默认初始化for (int i = 0; i < WAY_NUM; ++i){_pMaze[x][y]._state[i] = NO;}}// 初始化迷宫0节点的四个方向的可达性void setNodeState(){for (int i = 0; i < _row; ++i){for (int j = 0; j < _row; ++j){//cout << "(" << _pMaze[i][j]._x << "," << _pMaze[i][j]._y << ") ";// (i,j) 本身就不可达if (_pMaze[i][j]._val == 1){continue;}//(i, j) 四个方向的可达性设置// 右侧可达性if (j < _col - 1 && _pMaze[i][j + 1]._val == 0){_pMaze[i][j]._state[RIGHT] = YES;}// 下方可达性if (i < _row - 1 && _pMaze[i + 1][j]._val == 0){_pMaze[i][j]._state[DOWN] = YES;}if (j > 0 && _pMaze[i][j - 1]._val == 0){_pMaze[i][j]._state[LEFT] = YES;}if (i > 0 && _pMaze[i - 1][j]._val == 0){_pMaze[i][j]._state[UP] = YES;}}cout << endl;}}// 深度搜索路径void searchMazePath(){if (_pMaze[0][0]._val == 1){return;}_queue.push(_pMaze[0][0]);while (!_queue.empty()){Node front = _queue.front();int x = front._x;int y = front._y;if (x == _row - 1 && y == _col - 1){return;}// 往右寻找if (_pMaze[x][y]._state[RIGHT] == YES){_pMaze[x][y]._state[RIGHT] = NO;// 防止再走回来_pMaze[x][y + 1]._state[LEFT] = NO;// 辅助数组中记录下一节点的行走路径信息_pPath[x * _row + y + 1] = _pMaze[x][y];_queue.push(_pMaze[x][y + 1]);if (check(_pMaze[x][y + 1])){return;}}// 往下寻找if (_pMaze[x][y]._state[DOWN] == YES){_pMaze[x][y]._state[DOWN] = NO;// 防止再走回来_pMaze[x + 1][y]._state[UP] = NO;_pPath[(x + 1) * _row + y] = _pMaze[x][y];_queue.push(_pMaze[x + 1][y]);if (check(_pMaze[x + 1][y])){return;}}// 往左寻找if (_pMaze[x][y]._state[LEFT] == YES){_pMaze[x][y]._state[LEFT] = NO;// 防止再走回来_pMaze[x][y - 1]._state[RIGHT] = NO;// 记录 到(x, y - 1) 的上一个节点_pPath[x * _row + y - 1] = _pMaze[x][y]; _queue.push(_pMaze[x][y - 1]);_queue.push(_pMaze[x][y - 1]);if (check(_pMaze[x][y - 1])){return;}}// 往上寻找if (_pMaze[x][y]._state[UP] == YES){_pMaze[x][y]._state[UP] = NO;// 防止再走回来_pMaze[x - 1][y]._state[DOWN] = NO;_pPath[(x - 1) * _row + y] = _pMaze[x][y];_queue.push(_pMaze[x - 1][y]);if (check(_pMaze[x - 1][y])){return;}}// 四个方向都无法走(可能是走过或者是值为1)_queue.pop();}}// 打印搜索结果void showMazePath(){if (_queue.empty()){cout << "不存在一条迷宫路径!" << endl;}else{// 因为_pPath存储每个节点的前一个节点// !!!从终点位置往前依次遍历找到路径int x = _row - 1;int y = _col - 1;for (;;){_pMaze[x][y]._val = '*';if (x == 0 && y == 0){break;}// 找前一个节点Node node = _pPath[x * _row + y];x = node._x;y = node._y;}for (int i = 0; i < _row; ++i){for (int j = 0; j < _col; ++j){if (_pMaze[i][j]._val == '*'){cout << "* ";}else{cout << _pMaze[i][j]._val << " ";}}cout << endl;}}}
private:// 定义迷宫每个节点的信息struct Node{int _x;int _y;int _val;int _state[WAY_NUM]; // 往四个方向走的可行性};// 检查是否到出口bool check(Node& node){return node._x == _row - 1 && node._y == _col - 1;}Node** _pMaze; // 二维数组存放迷宫int _row;int _col;queue<Node> _queue; // BFS依赖队列vector<Node> _pPath; // 记录BFS节点行走信息//stack<Node> _stack; // 用栈来代替递归进行深度搜索
};int main()
{cout << "请输入迷宫的行列数(例如:10 10):";int row, col, data;cin >> row >> col;Maze maze(row, col); // 创建迷宫对象cout << "输入迷宫的每个位置信息(0表示可以走,1表示不能走):" << endl;for (int i = 0; i < row; ++i){for (int j = 0; j < col; ++j){cin >> data;maze.initNode(i, j, data);}}// 开始设置所有节点四个方向的状态maze.setNodeState();// 从左上角开始搜索路径maze.searchMazePath();// 打印迷宫路径搜索结果maze.showMazePath();return 0;
}相关文章:
广度优先遍历搜索迷宫最短路径
思路分析 由于广度是扩散逐层的方式遍历,相当于是多条路同时跑,最后先到终点就是最短路径了。 广度优先搜索主要使用队列来进行处理 路径用一个单独的vector存储,每一个点的坐标由二维转为一维,如(2, 3)存储在vector中下标为2*…...
分布式计算基础知识
分布式系统的概念 分布式系统是由多个独立计算机组成的系统,这些计算机通过网络进行通信和协作,共同完成一个任务。分布式系统的特点是具有高可用性、可扩展性和容错性。 在分布式系统中,每个计算机节点都可以独立地执行任务,同…...
Mybatis方式完成CRUD操作
Mybatis方式完成CRUD操作 文章目录 Mybatis方式完成CRUD操作1、java以Mybatis方式操作DB1.1、配置数据源-创建 resources/mybatis-config.xml1.2、创建java bean-Monster1.3、配置Mapper接口声明方法1.4、配置xxMapper,完成SQL配置,实现CRUD操作1.5、Test测试 2、需…...
css背景 background的属性作用和值
当我们在 HTML 中设置背景时,可以使用 background 属性。这个属性有多个值,可以使用不同的值来设置背景图片、背景颜色、背景位置、背景重复等等。以下是用表格列出的常见的 background 属性的值及其作用: 属性值描述background-color设置背…...
六大行文化特色知识(上)
中国六大银行都是综合性大型商业银行,业务涵盖面广泛且多元,代表着中国金融界最雄厚的资本和实力,这也是为什么很多毕业生想进国有行的原因,今天小编就带大家来了解一下关于六大行的特色知识,从如信银行考试中心平台了…...
匿名对象的特性和使用场景你知道吗?
目录 一、匿名对象的概念 二、单参数和多参数构造场景的匿名对象 ①只有一个参数的构造函数 ②多个参数的构造函数 三、使用匿名对象作为函数的参数的缺省值 四、只为调用类中的一个函数时 五、匿名对象的特性 1、匿名对象的生命周期只有一行 2、匿名对象具有常性 3、当匿…...
企业应该如何做到数字化转型成功?
01 成长型企业数字化转型的意义 成长型企业想要实现数字化转型,那么我们需要先弄明白,对于成长型企业而言,数字化转型到底具有什么意义?希望实现哪些目标? 可以归结为以下四点: 提升企业的生产力和效率&…...
PBDB Data Service:Bibliographic references for fossil collections(采集记录参考书目)
Bibliographic references for fossil collections(采集记录参考书目) 描述用法参数以下参数可用于检索与通过各种条件选择的集合关联的引用您可以使用以下参数根据书目参考文献的属性筛选结果集以下参数也可用于筛选选择以下参数可用于根据所选匹配项的…...
浅析图形验证码安全
0x01 前言 验证码的定义: 验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的…...
论文笔记:基于手机位置信息的地图匹配算法
2015计算机应用 整体思路和论文笔记:Hidden Markov Map MatchingThrough Noise and Sparseness_UQI-LIUWJ的博客-CSDN博客 很像,也是应用HMM进行地图匹配 HMMM本文 状态转移矩阵 观测概率矩阵 正态分布均值都是0,唯一不同的是S…...
因果推断系列16-面板数据与固定效应
因果推断系列16-面板数据与固定效应 1.平行趋势2.未观测变量的控制3.固定效应4.固定效应可视化5.时间效应小结加载第三方包 import warnings warnings.filterwarnings(ignore)import pandas as pd import numpy as np from matplotlib import style from matplotlib import...
第三十三章 弹性池塘2(弹城少年歌词)
熟悉的K26,熟悉的漉菽香味,熟悉的絮絮叨叨。 为什么坎迪总有那么多话想说,就算恢复正常,自己应该也找不出如滔滔江水连绵不断的语词洪流吧。 不,不是词汇量的问题。 当你习惯于将金玉良言与废屁空套话区分开来时&#…...
PMP之预测部分
引论 什么是项目 项目是为创造独特的产品、服务或成果而进行的临时性工作。 项目管理是把事办成的方法论,万物皆可项目。 项目的基本要素 项目(独特性、临时性)、驱动变更、启动背景、创造商业价值。 组织级项目管理(OPM&am…...
Node.js 异步流控制
目录 1、简介 2、状态管理 3、控制流 3.1、串联 3.2、完全并行 3.3、有限并行 1、简介 在其核心,JavaScript被设计为在“主”线程上是非阻塞的,这是呈现视图的位置。你可以想象这在浏览器中的重要性。例如,当主线程被阻塞时࿰…...
掌握这些思维技巧,解救996的打工人!
你身边有没有这样的人:面对堆积如山的工作、随时弹出的任务,接二连三的群也能游刃有余地处理。回看自己,旧的任务还在做,新的任务已经从天而降,日程表上满是任务却无从下手…… 明明忙个不停却成果甚微,这…...
【嵌入式Linux】MBR分区表 和 GPT分区表
文章目录 GUID以及分区表MBR分区方案GPT 分区方案GPT分区表结构 GPT分区表LBALBA0(MBR兼容部分)LBA1LBA 2-33python生成GPT分区表gpt分区表实例 gpt分区表查看查看百问网T113-s3固件查看友善之臂nanopi-m1-plus官方固件查看荣品RV1126固件查看f1c200s固件…...
【华为OD机试真题】MVP争夺战(python)100%通过率 超详细代码注释 代码解读
【华为OD机试真题 2022&2023】真题目录 @点这里@ 【华为OD机试真题】信号发射和接收 &试读& @点这里@ 【华为OD机试真题】租车骑绿道 &试读& @点这里@ MVP争夺战 知识点DFS搜索 时间限制:1s 空间限制:256MB 限定语言:不限 题目描述: 在星球争霸篮球赛对…...
实战打靶集锦-019-BTRSys2.1
提示:本文记录了博主的一次普通的打靶经历 目录 1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查4.1 FTP服务探查4.2 Apache服务探查4.2.1 wpscan扫描4.2.2 Metasploit神器4.2.3 手工探查页面4.2.3.1 Appearance Editor4.2.3.2 Plugins Editor 5. 提权5.1 系统信息枚…...
2023中国(苏州)国际电源工业展览会暨高端论坛
时间:2023年11月9~11日 地点:苏州国际博览中心 30000㎡展出面积 500参展商 50000名专业观众 中国电源行业风向标----相约苏州,共襄盛举! ◆展会背景Exhibition background: …...
基于SpringBoot+Vue的校园疫情防控系统(附源码和数据库)
文章目录 第一章2.主要技术第三章第四章 系统设计4.1功能结构4.2 数据库设计4.2.1 数据库E/R图4.2.2 数据库表 第五章 系统功能实现5.1系统功能模块5.2后台功能模块5.2.1管理员功能 源码咨询 第一章 springboot校园疫情防控系统演示录像2022 一个好的系统能将校园疫情防控的管理…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
