《数据结构、算法与应用C++语言描述》-栈的应用-迷宫老鼠问题

迷宫老鼠

问题描述

迷宫(如图 8-9 所示)是一个矩形区域,有一个入口和一个出口。迷宫内部包含不能穿越的墙壁或障碍物。这些障碍物沿着行和列放置,与迷宫的边界平行。迷宫的入口在左上角,出口在右下角。

在这里插入图片描述

假定用 nxm 的矩阵来描述迷宫,矩阵的位置(1,1)表示入口,(n,m)表示出口,n 和m分别代表迷宫的行数和列数。迷宫的每个位置都可用其行号和列号表示。在矩阵中,当且仅当在位置(i,j)处有一个障碍时,其值为 1,否则其值为 0。图 8-10 给出了图8-9 中的迷宫所对应的矩阵表示。迷宫老鼠(rat in a maze)问题是要寻找一条从入口到出口的路径。路径是一个由位置组成的序列,每一个位置都没有障碍,而且除入口之外,路径上的每个位置都是前一个位置在东、南、西或北方向上相邻的一个位置(如图8-11 所示)。

在这里插入图片描述

我们要编写程序来解决迷宫老鼠问题。假设迷宫是一个方阵(即m=n)且足够小,能够整个存储在目标计算机的内存中。程序应是独立的,一个用户可以输入自己选择的迷宫来直接寻找迷宫路径。

求解策略

逻辑:首先把迷宫的入口作为当前位置。如果当前位置是迷宫出口,那么已经找到了一条路径,寻找工作结束。如果当前位置不是迷宫出口,则在当前位置上放置障碍物,以阻止寻找过程又绕回到这个位置。然后检查相邻位置是否有空闲(即没有障碍物),如果有,就移动到一个空闲的相邻位置上,然后从这个位置开始寻找通往出口的路径。如果不成功,就选择另一个空闲的相邻位置,并从它开始寻找通往出口的路径。为了方便移动,在进入新的相邻位置之前,把当前位置保存在一个栈中。如果所有空闲的相邻位置都已经被探索过,但还未能找到路径,则表明迷宫不存在从入口到出口的路径。

路径的表示:注意,在栈中始终有一条从入口到当前位置的路径。如果最终到达了出口,那么栈中的路径就是从入口到出口的路径。

padding:为了避免在处理内部位置和边界位置时存在差别,可以在迷宫的周围增加一圈障碍物。对于一个mxm的数组maze,这一圈障碍物将占据数组maze的第0行、第m+1行、第0列和第m+1列。

最长路径:一个没有障碍物的 m× m 迷宫,最长的路径可包含 m 2 m^2 m2个位置。

因为路径包含的位置没均不相同,而且迷宫仅有 m 2 m^2 m2 个位置,所以一条路径所包含的位置最多不超过 m 2 m^2 m2。又因为路径的最后一个位置不必存储到栈中,所以在栈中存储的位置最多是 m 2 − 1 m^2 - 1 m21。注意,在一个没有障碍物的迷宫中,在入口和出口之间,总有一条最多包含 2m 个位置的路径。

偏移量表:例如,如果当前位置是(3,4),则其右边相邻位置的行坐标为3+offset[0].row=3,列坐标为 4+offset[0].col=5。

在这里插入图片描述

防止走回去:为了不重蹈已经走过的位置,我们在每一个走过的位置maze[i] [j]上设置障碍物。

代码

#include <iostream>
#include <stack>
using namespace std;/*用于存储迷宫地址的结构体*/
struct position
{int row,  //行col;  //列operator int() const { return row; }friend ostream& operator<<(ostream& out, const position x){out << "(" << x.row << "," << x.col << ")";return out;}
};/*创建二维数组*/
template <class T>
bool make2dArray(T**& x, int numberOfRows, int numberOfColumns)
{try {//行指针x = new T * [numberOfRows];//为每一行分配内存for (int i = 0; i < numberOfRows; i++)x[i] = new int[numberOfColumns];return true;}catch (bad_alloc) { return false; }
}/*遍历二维数组*/
template<class T>
void traverse2dArray(T**& x, int numberOfRows, int numberOfColumns)
{for (int i = 0; i < numberOfRows; i++){for (int j = 0; j < numberOfColumns; j++){cout.width(4);cout << x[i][j] << "  ";}cout << endl;}
}/*迷宫老鼠全局变量*/
int** maze,mazeSize;
stack<position> path;//存储路径的数组栈
/*迷宫老鼠问题*/
/*展示界面*/
void welcome()
{cout << "******Welcome To RAT IN A MAZE******" << endl;cout << "************Jasmine,2022************" << endl;
}
/*输入迷宫*/
void inputMaze()
{cout << "Please enter the size of Maze-Matrix:";while (!(cin >> mazeSize)){cin.clear();//清空标志位while (cin.get() != '\n')//删除无效的输入continue;cout << "Please enter the size of Maze-Matrix:";}//+2的原因是为了避免在处理内部位置和边界位置时存在差别make2dArray<int>(maze, mazeSize + 2, mazeSize + 2);//初始化边界位置的数值for (int i = 0; i <= mazeSize + 1; i++){maze[i][0] = 1;maze[0][i] = 1;maze[i][mazeSize + 1] = 1;maze[mazeSize + 1][i] = 1;}//初始化迷宫for (int i = 1; i <= mazeSize; i++)for(int j = 1; j <= mazeSize; j++){int positionij;cout << "Please enter maze[" << i << "," << j << "]:";while (!(cin >> positionij)){cin.clear();//清空标志位while (cin.get() != '\n')//删除无效的输入continue;cout << "Please enter maze[" << i << "," << j << "]:";}maze[i][j] = positionij;}cout << "The maze = " << endl;traverse2dArray<int>(maze, mazeSize + 2, mazeSize + 2);
}
/*寻找迷宫路径入口(1,1),出口(size,size),如找到返回true,如没找到则返回false*/
bool findPath()
{path = stack<position>();//存储路径//初始化偏移量position offset[4];offset[0].row = 0; offset[0].col = 1;//右offset[1].row = 1; offset[1].col = 0;//下offset[2].row = 0; offset[2].col = -1;//左offset[3].row = -1; offset[3].col = 0;//上//入口position here;here.row = 1;here.col = 1;maze[1][1] = 1;//防止回到入口int option = 0;//下一步int lastOption = 3;//寻找一条路径while ((here.row != mazeSize) || (here.col != mazeSize)){int r, c;while (option <= lastOption){r = here.row + offset[option].row;c = here.col + offset[option].col;if (maze[r][c] == 0) break;option++;//下一个选择}// 相邻的下一步是否找到if (option <= lastOption){//移到maze[r][c]path.push(here);here.row = r;here.col = c;maze[r][c] = 1;//防止重复访问该节点option = 0;}else//如果没找到{if (path.empty())return false;position next = path.top();path.pop();if (here.row == next.row) // 说明是移动的左右option = 2 + next.col - here.col; // 如果是左的话,op = 3就是上;如果是右的话,op = 1,就是下else // 此时移动的是上下option = 3 + next.row - here.row; // 如果是上的话,op = 4;如果是下的话,op = 2,就是左here = next;}}path.push(here);return true;
}
/*输出迷宫路径*/
void outputPath()
{int i = 0;cout << "The path = ";stack<position> temp;while(!path.empty()){cout << path.top() << "->";temp.push(path.top());path.pop();}while(!temp.empty() && temp.size() > 1){cout << temp.top() << "->";temp.pop();}cout << temp.top() << endl;temp.pop();
}int main()
{cout << "RAT IN A MAZE********************" << endl;welcome();inputMaze();findPath();outputPath();return 0;
}

运行结果

C:\Users\15495\Documents\Jasmine\Work\coding\cmake-build-debug\coding.exe
RAT IN A MAZE********************
******Welcome To RAT IN A MAZE******
************Jasmine,2022************
Please enter the size of Maze-Matrix:3
Please enter maze[1,1]:0
Please enter maze[1,2]:0
Please enter maze[1,3]:0
Please enter maze[2,1]:1
Please enter maze[2,2]:1
Please enter maze[2,3]:0
Please enter maze[3,1]:1
Please enter maze[3,2]:1
Please enter maze[3,3]:0
The maze =1     1     1     1     11     0     0     0     11     1     1     0     11     1     1     0     11     1     1     1     1
The path = (3,3)->(2,3)->(1,3)->(1,2)->(1,1)->(1,1)->(1,2)->(1,3)->(2,3)->(3,3)Process finished with exit code 0

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

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

相关文章

正则表达式 Regular Expression学习

该文章内容为以下视频的学习笔记&#xff1a; 10分钟快速掌握正则表达式_哔哩哔哩_bilibili正则表达式在线测试工具&#xff1a;https://regex101.com/, 视频播放量 441829、弹幕量 1076、点赞数 19330、投硬币枚数 13662、收藏人数 26242、转发人数 2768, 视频作者 奇乐编程学…

【iptables 实战】07 iptables NAT实验

在上一节中&#xff0c;我们将两个网段的机器&#xff0c;通过中间机器的网络转发&#xff0c;能达到互通。再来回顾一下这个网络连接的图 上一节我们在防火墙实验中&#xff0c;设置了主机B的的转发规则&#xff0c;我们先清空主机B的转发规则 [rootlocalhost ~]# iptables…

飞桨EasyDL-Mac本地部署离线SDK-Linux集成Python

前言&#xff1a;本文对使用飞桨EasyDL桌面版实现本地部署物体检测做一下说明 一、训练模型 如何使用飞桨EasyDL桌面版这里就不再赘述&#xff0c;直接参照官方文档进行物体检测模型训练。 飞桨EasyDL桌面版-用零代码开发实现物体检测https://ai.baidu.com/ai-doc/EASYDL/Tl2…

基于监督学习的多模态MRI脑肿瘤分割,使用来自超体素的纹理特征(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

国庆作业 day1

C语言基础考题&#xff08;40&#xff09; 选择题 20分每题2分 1、已知字母A的ASCII码为十进制数值65&#xff0c;且S为字符型&#xff0c;则执行语句SA6-3&#xff1b;后S中的值为 ( ) A.D B.68 C.不确定的值 D.C 2、若有定义语句&#xff1a;int a12;&#xff0c;则执…

Linux配置命令

一&#xff1a;HCSA-VM-Linux安装虚拟机后的基础命令 1.代码命令 1.查看本机IP地址&#xff1a; ip addr 或者 ip a [foxbogon ~]$ ip addre [foxbogon ~]$ ip a 1&#xff1a;<Loopback,U,LOWER-UP> 为环回2网卡 2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP&g…

10个与AI相关的技术领域

**10个与AI相关的技术领域** 除了与各个科学领域相关的具体挑战之外&#xff0c;AI在科学领域还存在一些共同的技术挑战。特别是&#xff0c;我们确定了以下四个共同的技术挑战&#xff1a;超出分布的泛化、可解释性、由自监督学习提供支持的基础模型和不确定性量化。尽管这些…

28385-2012 印刷机械 锁线机 学习笔记

声明 本文是学习GB-T 28385-2012 印刷机械 锁线机. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了锁线机的型式、基本参数、要求、试验方法、检验规则、标志、包装、运输与贮存。 本标准适用于用线将书帖装订成书芯的锁线机。 …

K-Means(上):数据分析 | 数据挖掘 | 十大算法之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…

计算机毕业设计 基于微信小程序的学习资料销售平台的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Nginx之动静分离解读

目录 基本概念 基本入门 location匹配顺序 补充&#xff1a;URLRewrite 基本概念 动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来&#xff0c;动静资源做好了拆分以后&#xff0c;我们就可以根据静态资源的特点将其做缓存操作&#x…

计算机组成与结构

目录 一、计算机硬件组成 二、中央处理单元 1、功能 2、CPU的组成 三、校验码 四、体系结构的分类 1、按处理机数量分类 2、Flynn分类 五、指令系统 1、指令 2、寻址方式 3、指令系统 #CISC&#xff08;复杂指令集计算机&#xff09; RISC&#xff08;精简指令集…

JavaSE学习之--抽象类,接口,内部类

&#x1f495;"没有眼泪我们就会迷路&#xff0c;彻底变成石头&#xff0c;我们的心会变成冰凌&#xff0c;吻会变成冰块。"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;JavaSE学习之--抽象类&#xff0c;接口&#xff0c;内部类 目录 一.抽象…

OpenCV实现视频的读取、显示、保存

目录 1&#xff0c;从文件中读取视频并播放 1.2代码实现 1.3效果展示 2&#xff0c;保存视频 2.1 代码实现 2.2 结果展示 1&#xff0c;从文件中读取视频并播放 在OpenCV中我们需要获取一个视频&#xff0c;需要创建一个VideoCapture对象,指定你要读取的视频文件&am…

基于微信小程序的模拟考试小程序的设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

量化交易全流程(四)

本节目录 数据准备&#xff08;数据源与数据库&#xff09; CTA策略 数据源&#xff1a; 在进行量化分析的时候&#xff0c;最基础的工作是数据准备&#xff0c;即收集数据、清理数据、建立数据库。下面先讨论收集数据的来源&#xff0c;数据来源可分为两大类&#xff1a;免…

SLAM从入门到精通(tf的使用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 在ros的机器人学习过程中&#xff0c;有一件事情是肯定少不了的。那就是坐标系的转换。其实这也很容易理解。假设有一个机器人&#xff0c;它有一个…

推荐算法——Apriori算法原理

0、前言&#xff1a; 首先名字别读错&#xff1a;an pu ruo ao rui 【拼音发音】Apriori是一种推荐算法推荐系统&#xff1a;从海量数据中&#xff0c;帮助用户进行信息的过滤和选择。主要推荐方法有&#xff1a;基于内容的推荐、协同过滤推荐、基于关联规则的推荐、基于知识的…

Spring整合RabbitMQ——生产者

1.生产者整合步骤 添加依赖坐标&#xff0c;在producer和consumer模块的pom文件中各复制一份。 配置producer的配置文件 配置producer的xml配置文件 编写测试类发送消息

《HelloGitHub》第 90 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 https://github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 …