从迷宫问题理解dfs

文章目录

  • 迷宫问题打印路径1
    • 思路
      • 定义一个结构体
      • 要保存所走的路径,就需要使用到栈
      • 遍历所有的可能性
      • 核心代码
    • 部分函数递归图
    • 源代码
  • 迷宫问题返回最短路径
    • 这里的思想同上面类似。
    • 源代码

迷宫问题打印路径1

定义一个二维数组 N*M ,如 5 × 5 数组下所示:

int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。

输入描述:
输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。

输出描述:
左上角到右下角的最短路径
输入:
5 5
0 1 0 0 0
0 1 1 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出:
(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)

思路

定义一个结构体

typedef struct pt {//行·int row;//列int col;
}PT;

要保存所走的路径,就需要使用到栈

  导入c++的 STL栈。
如果是c语言就需要自己手写栈。
c语言的栈

遍历所有的可能性

在这里插入图片描述

核心代码

  遍历上,右,左,下四个方向。先上核心代码。

bool isPath(int** a, int n, int m, PT pt)
{if (pt.row >= 0 && pt.row < n&& pt.col >= 0 && pt.col < m&& a[pt.row][pt.col] == 0){return true;}else {return false;}
}//这里只需要一条路,直接返回bool值
bool dfs(int** a, int n, int m, PT pt)
{st.push(pt);if (pt.row == n - 1 && pt.col == m - 1){//找到出口return true;}//标记走过的路为2a[pt.row][pt.col] = 2;//开始遍历四个方向//上PT next = pt;next.row -= 1;if (isPath(a, n, m, next)){if (dfs(a, n, m, next)){return true;}}//右next.row += 1;next.col += 1;if (isPath(a, n, m, next)){if (dfs(a, n, m, next)){return true;}}//下next.col -= 1;next.row += 1;if (isPath(a, n, m, next)){if (dfs(a, n, m, next)){return true;}}//左next.row -= 1;next.col -= 1;if (isPath(a, n, m, next)){if (dfs(a, n, m, next)){return true;}}st.pop();//四个方向都不行,则false;return false;
}

部分函数递归图

开始按照每个点的上,右,左,下开始前进,如果可以走,则进行标记为2,如果一个方向不可以走,则换另一个方向,直到四个方向都不可以走,则返回上一个正确的位置。
在这里插入图片描述

源代码

// https://www.nowcoder.com/practice/cf24906056f4488c9ddb132f317e03bc?tpId=37&tqId=21266&ru=/exam/oj#include <iostream>
using namespace std;
#include<stack>typedef struct pt {int row;int col;
}PT;stack<PT> st;bool isPath(int** a, int n, int m, PT pt)
{if (pt.row >= 0 && pt.row < n&& pt.col >= 0 && pt.col < m&& a[pt.row][pt.col] == 0){return true;}else {return false;}
}//这里只需要一条路,直接返回bool值
bool dfs(int** a, int n, int m, PT pt)
{st.push(pt);if (pt.row == n - 1 && pt.col == m - 1){//找到出口return true;}a[pt.row][pt.col] = 2;//开始遍历四个方向//上PT next = pt;next.row -= 1;if (isPath(a, n, m, next)){if (dfs(a, n, m, next)){return true;}}//右next.row += 1;next.col += 1;if (isPath(a, n, m, next)){if (dfs(a, n, m, next)){return true;}}//下next.col -= 1;next.row += 1;if (isPath(a, n, m, next)){if (dfs(a, n, m, next)){return true;}}//左next.row -= 1;next.col -= 1;if (isPath(a, n, m, next)){if (dfs(a, n, m, next)){return true;}}st.pop();//四个方向都不行,则false;return false;
}void Print(stack<PT> st)
{stack<PT> rt;while (!st.empty()){rt.push(st.top());st.pop();}while (!rt.empty()){cout << "(" << rt.top().row << "," << rt.top().col << ")" << endl;rt.pop();}
}int main() {int n, m;while (cin >> n >> m) { // 注意 while 处理多个 case//开辟一个动态二维数组int** tmp = (int**)malloc(sizeof(int*) * n);for (int i = 0; i < n; ++i){tmp[i] = (int*)malloc(sizeof(int) * m);}for (int i = 0; i < n; ++i){for (int j = 0; j < m; ++j){cin >> tmp[i][j];}}//定义结构体PT pt;pt.row = 0;pt.col = 0;bool flag = dfs(tmp, n, m, pt);if (flag == true){Print(st);}}}

迷宫问题返回最短路径

描述
小青蛙有一天不小心落入了一个地下迷宫,小青蛙希望用自己仅剩的体力值P跳出这个地下迷宫。为了让问题简单,假设这是一个n*m的格子迷宫,迷宫每个位置为0或者1,0代表这个位置有障碍物,小青蛙达到不了这个位置;1代表小青蛙可以达到的位置。小青蛙初始在(0,0)位置,地下迷宫的出口在(0,m-1)(保证这两个位置都是1,并且保证一定有起点到终点可达的路径),小青蛙在迷宫中水平移动一个单位距离需要消耗1点体力值,向上爬一个单位距离需要消耗3个单位的体力值,向下移动不消耗体力值,当小青蛙的体力值等于0的时候还没有到达出口,小青蛙将无法逃离迷宫。现在需要你帮助小青蛙计算出能否用仅剩的体力值跳出迷宫(即达到(0,m-1)位置)。
输入描述:
输入包括n+1行:
第一行为三个整数n,m(3 <= m,n <= 10),P(1 <= P <= 100)
接下来的n行:
每行m个0或者1,以空格分隔
输出描述:
如果能逃离迷宫,则输出一行体力消耗最小的路径,输出格式见样例所示;如果不能逃离迷宫,则输出"Can not escape!"。 测试数据保证答案唯一
输入4 4 10 1 0 0 1 1 1 0 1 0 1 1 1 0 0 1 1
[0,0],[1,0],[1,1],[2,1],[2,2],[2,3],[1,3],[0,3]

这里的思想同上面类似。

  但是也有略微区别,这里要求最短路径,我们怎么知道求出的答案就是最短的路劲呢?所以这里要遍历所有可以前进的路线。走的路径进行标记,不走的路劲标记过的要取消标记。

源代码

#include <iostream>
using namespace std;
#include<stack>//定义坐标typedef struct pt {int row;int col;
}PT;//普通路径
stack<PT> st;
//最短路径
stack<PT> minSt;//判断能否通过
bool isPath(int** tmp, int n, int m, PT pt)
{if (pt.row >= 0 && pt.row < n&& pt.col >= 0 && pt.col < m&& tmp[pt.row][pt.col] == 1){return true;}else {return false;}
}//这里我们要找到·所有路径,所以不用返回
void dfs(int** tmp, int n, int m, PT pt, int p)
{//每次进来先入栈st.push(pt);//走过的路标记为2tmp[pt.row][pt.col] = 2;if (p >= 0 && pt.row == 0 && pt.col == m - 1){//更新最短路径if (st.size() < minSt.size() ||minSt.empty()){minSt = st;}}//枚举所有方法PT next;//上next = pt;next.row -= 1;if (isPath(tmp, n, m, next)){dfs(tmp, n, m, next, p - 3);}//右next = pt;next.col += 1;if (isPath(tmp, n, m, next)){dfs(tmp, n, m, next, p - 1);}//下next = pt;next.row += 1;if (isPath(tmp, n, m, next)){dfs(tmp, n, m, next, p);}//左next = pt;next.col -= 1;if (isPath(tmp, n, m, next)){dfs(tmp, n, m, next, p - 1);}//都不能走,还原路径为1tmp[pt.row][pt.col] = 1;st.pop();//四个方向都不能走
}//进行对栈的打印
void Print(stack<PT> st)
{stack<PT> rt;while (!st.empty()){rt.push(st.top());st.pop();}while (rt.size() > 1){cout << "[" << rt.top().row << "," << rt.top().col << "]" << ",";rt.pop();}cout << "[" << rt.top().row << "," << rt.top().col << "]" << endl;rt.pop();
}int main() {int n, m, p;while (cin >> n >> m) { // 注意 while 处理多个 casecin >> p;//开辟二维数组int** tmp = (int**)malloc(sizeof(int*) * n);for (int i = 0; i < n; ++i){tmp[i] = (int*)malloc(sizeof(int) * m);}//输入for (int i = 0; i < n; ++i){for (int j = 0; j < m; ++j){cin >> tmp[i][j];}}PT pt;pt.row = 0;pt.col = 0;dfs(tmp, n, m, pt, p);if (!minSt.empty()){Print(minSt);}else {cout << "Can not escape!" << endl;}}
}

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

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

相关文章

十一、Yocto集成tcpdump等网络工具

文章目录 Yocto集成tcpdump等网络工具networking layer集成 Yocto集成tcpdump等网络工具 本篇文章为基于raspberrypi 4B单板的yocto实战系列的第十一篇文章&#xff1a; 一、yocto 编译raspberrypi 4B并启动 二、yocto 集成ros2(基于raspberrypi 4B) 三、Yocto创建自定义的lay…

ctf.show_web14

在switch中&#xff0c;case 里如果没有 break&#xff0c;则会继续向下执行 case。 过滤了information_schema.tables、information_schema.column、空格 information_schema.tables 或 .columns 用反引号 information_schema.tables 同时查3个字段 ?query-1/**/union/**/…

ssh免秘钥登录与时钟同步

ssh免秘钥登录及数据拷贝 ssh免秘钥登录及数据拷贝环境生成秘钥拷贝公钥到到远程服务器通过ssh-copy-id命令拷贝公钥到远程服务器通过手动拷贝公钥到远程服务器 非root用户远程拷贝公钥 设置编码方式临时设置编码永久设置方法一永久设置方法二 设置时钟同步使用 ntpdate 命令使…

血糖长期不降,乏力、视力模糊?可能治疗方向有误。

糖尿病能不能治愈&#xff0c;中医能不能治&#xff0c;这是很多人讨论的话题&#xff0c;现在全世界任何一家西医医院都会告诉你&#xff0c;糖尿病没办法治&#xff0c;给你的建议也是终身服药&#xff0c;或者打胰岛素治疗&#xff0c;但是我告诉你&#xff0c;其实这都是治…

Jmeter04:关联

1 Jmeter组件&#xff1a;关联 概括&#xff1a;2个请求之间不是独立的&#xff0c;一个请求响应的结果是作为另一个请求提交的数据&#xff0c;存在数据交互 1.1 是什么&#xff1f; 就是一个请求的结果是另一个请求提交的数据&#xff0c;二者不再是独立 1.2 为什么&#x…

深入理解Java IO流:字符流

深入理解Java IO流&#xff1a;字符流 引言 在Java中&#xff0c;IO&#xff08;输入/输出&#xff09;操作是程序与外部世界交互的重要方式。 其中&#xff0c;File类是进行文件操作的基础&#xff0c;而字节流和字符流则是数据传输的两种主要方式。 本文将深入探讨这些概念及…

【Redis 神秘大陆】004 高可用集群

四、Redis 高可用和集群 当你发现这些内容对你有帮助时&#xff0c;为了支持我的工作&#xff0c;不妨给一个免费的⭐Star&#xff0c;这将是对我最大的鼓励&#xff01;感谢你的陪伴与支持&#xff01;一起在技术的路上共同成长吧&#xff01;点击链接&#xff1a;GitHub | G…

算法总结篇 —— dfs(搜索、递归、回溯)

有些事情本来很遥远&#xff0c;你争取&#xff0c;它就会离你越来越近 概念 名词解释如何理解递归 dfs 回溯类问题蓝桥杯——飞机降落 dfs 迷宫搜索类问题蓝桥杯——岛屿个数 概念 名词解释 递归是指在一个函数的定义中调用自身的过程&#xff0c;有些复杂问题可以划分为多…

c++的学习之路:26、AVL树

摘要 本章主要是说一下AVL树的实现&#xff0c;这里说的是插入的底层原理 目录 摘要 一、原理 二、四种旋转 1、左单旋 2、右单旋 3、左右双旋 4、右左双旋 三、代码实现 1、节点创建 2、插入 3、旋转 4、判断是否平衡 5、测试 四、代码 一、原理 前面说了搜索…

为啥转化为可编辑面片后有这么多点和线

可以删一下 按住alt按移除可以删掉 选择你要删的那些线 按住alt点移除

eBay、亚马逊自养号测评如何避免风控账号关联选择合适网络IP环境

在自养号下单中选择适合的网络环境至关重要。经过多次实践与测试&#xff0c;积累了大量的经验&#xff0c;希望能够与大家分享&#xff0c;帮助大家避开陷阱&#xff0c;顺利前行。 市面上的网络环境种类繁多&#xff0c;从纯IP类的Luminati、Rola&#xff0c;到纯环境类的VM…

编写Spark独立应用程序

执行本文之前&#xff0c;先搭建好spark的开发环境&#xff0c;我目前只搭建了standalone模式&#xff0c;参考链接 &#xff1a; Spark Standalone模式部署-CSDN博客 1. 安装sbt 1&#xff09;下载sbt 网址&#xff1a;https://www.scala-sbt.org/download.html &#xff0c…

【云原生 • Docker】 ELK 8.4.3 docker 保姆级安装部署详细步骤

文章目录 ELK简介二、版本说明三、安装部署3.1 创建docker网络3.2 Elasticsearch拉取docker镜像,版本:8.4.3第一次执行docker脚本可以看到控制台的信息,找到这个信息并保存下来创建Elasticsearch挂载目录给创建的文件夹授权将容器内的文件复制到主机上删除容器修改docker脚本…

【GPTs分享】GPTs分享之Image Recreate | img2img​

简介 该GPT是一个专门用于图像编辑、重建和合并的工具。它通过详细的自动图像描述和生成&#xff0c;帮助用户从源图像中重现或修改图像。此工具设计用于为视障用户提供图像内容的详细描述&#xff0c;并生成全新的图像&#xff0c;以满足特定的视觉需求。 主要功能 \1. 图像…

Unity开发holoLens2应用时的ProjectSettings配置

正确的进行Unity工程配置&#xff0c;才能进行后续的【发布】和【部署】操作… 本案例开发环境说明&#xff1a; Unity2021.3.18Win10VS2022HoloLens2 一、平台设置 二、Quality画面质量设置 三、Player玩家设置 四、XR-Plug设置 五、环境测试 导入一个官方demo&#xff0c…

ORAN C平面 Section Extension 23

ORAN C平面Section扩展23用于任意symbol模式的调制压缩参数。此section扩展允许为一个或多个“SymPrbPatterns”指定多组“mcScaleReMask、csf和mcScaleOffset”值。“SymPrbPattern”用于指定一组PRB&#xff0c;这些PRB可以跨越使用prbPattern指定的整个PRB范围&#xff08;频…

重生奇迹mu坐骑怎么升级

重生奇迹mu坐骑怎么升级 1、前期&#xff0c;都是主线任务&#xff0c;我们必须要跟着主线任务走&#xff0c;前面的话升级一次需要的经验很少的&#xff0c;一天下来可以升级100级是轻轻松松的&#xff0c;主线任务是比较多的&#xff0c;我们跟着任务一直做差不多可以到150级…

dspbuilder中使用signalcompiler时报错Error during compilation: Fitter failed,如何解决?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

计算机组成原理【CO】Ch7 I/O大题

目录 I/O大题解题方法 I/O接口 各种I/O方式的特点 I/O端口编址 程序查询方式 中断控制方式 DMA控制方式 程序中断的工作流程 程序中断的工作流程 DMA方式和中断方式的区别 I/O大题解题方法 CPU 程序查询中断DMA I/O接口的类型 按字传输&#xff1a;每次传输一个字 程…

【C++】日期类Date(详解)

&#x1f525;个人主页&#xff1a;Forcible Bug Maker &#x1f525;专栏&#xff1a;C 目录 前言 日期类 日期类实现地图 获取某年某月的天数&#xff1a;GetMonthDay 检查日期合法&#xff0c;构造函数&#xff0c;拷贝构造函数&#xff0c;赋值运算符重载及析构函数…