湖师计信学科小组之DFS走迷宫问题

目录

一、情景导入   

二、问题描述

 三、解决思路 

一、情景导入   

今天我们来学习一下DFS-深度优先探索的经典问题---DFS解决走迷宫的问题,希望我们能在解决问题的过程中去理解DFS算法。

那么什么是DFS?

通俗点说从一个顶点开始,沿着一条路径一直搜索到该路径的尽头(即无法再搜索下去),然后回溯到上一个顶点,继续搜索下一条路径,直到所有路径都被遍历完,其实也就是一种递归加回溯的思想。

那么这就是是DFS的伪代码

那么我们可以清楚的看到DFS的设计步骤包括

  1. 确定该题目的状态(包括边界)

  2. 找到状态转移方式

  3. 找到问题的出口,计数或者某个状态

  4. 设计搜索

二、问题描述

下面我们通过一个例题来学习一下DFS在走迷宫问题中的经典

处于起点(1,1)的小明想去寻找二维迷宫中处于终点(p,q)的小红,二维迷宫中有许多的障碍物,请你设计一种算法,使得小明可以绕过这些障碍物最终找到小红,并且最后输出小明走最少的步数;

现在输入要求如下:

第一行输入n*m大小的二维迷宫大小;

第二行输入小红的终点坐标;

第三行输入二维迷宫的地图;(用0表示可以通行,1表示不能通行)

 三、解决思路

这类题很明显可以用上我们的DFS去解决,我们去遍历小明走过路径的所有选择,将错误的路径回溯,直到找到正确的路径为止。

我们先来准备工作:

tips:使用全局变量在许多问题中会很方便,因为它的生存周期长,不用在主函数传入所写的DFS()中

解释一下:

1.#include<bits/stdc++.h>---c++的万能头文件,相当于一个很大的集合,不过用的时候得注意,其中包含的标识符可能会与你定义的变量名冲突。

2.using namespace std----它告诉编译器你想要在当前的作用域(通常是源文件或函数)中使用std(标准)命名空间中的名称,而不需要每次都加上std::前缀。

3.方向数组是为了让小明在面临每一次选择时能上下左右去考虑

主函数:

解释一下:

1.在C++中,我们经常使用标准库中的cout与cin对象来输出\输入信息到控制台,其实可以理解为printf()与scanf(),不过可以使你的输入输出更加简洁

DFS()算法:

 过程分析:

1.DFS()函数接收三个形参,前两个是小明的当前坐标x,y,后一个是小明当前所走的步数,因为小明的起始坐标固定在(1,1),所以我们将book这个用来记录小明走过的路径的二维数组的起点也设置为1,防止小明在选择时走回原路。

2.if()的dp判断是每一次小明递归的首先检查条件,检查小明的坐标当前是否满足终点坐标(p,q),这是每一次递归的最优先,不能将它移位

3.临时变量tx,ty的生存周期就在DFS中,其主要作用是通过方向数组,赋予小明下一步是向左,还是向右,向上还是向下,因为方向数组用for()循环推动,所以在当前step中不会重复

4.check()条件就是if()中的边界判断,判断tx、ty是否越界,如果越界就不执行下面的语句,从而重新执行方向数组的for()语句,从而选择另一个不满足check(),也就是我们期望的下一步去探寻终点坐标

5.book数组理解:book 数组用于标记在深度优先搜索(DFS)过程中哪些格子已经被访问过。这种机制对于防止DFS重复访问相同的格子以及进行“回溯”至关重要它包括:

  1. 访问格子

    • 当DFS函数dfs(int x, int y, int step)访问一个格子(x, y)时,它首先会检查book[x][y]是否为0。如果是,则标记该格子为已访问(book[x][y] = 1),然后递归地探索从该格子出发的所有可能路径。
  2. 递归探索

    • 在递归探索过程中,DFS会尝试所有四个方向(上、下、左、右)。对于每个方向,它都会计算新的坐标(tx, ty),并检查这些坐标是否有效(即没有越界且该格子未被访问过,并且该格子在迷宫中是可通行的,即ans[tx][ty] == 0)。
    • 如果满足这些条件,DFS会再次调用自身,继续探索从(tx, ty)出发的路径。
  3. 回溯

    • 当从(tx, ty)出发的所有可能路径都已经被探索过后(即所有四个方向都已经尝试过),DFS会返回到(x, y)。此时,为了避免在下一次从(x, y)出发时再次探索(tx, ty),需要将(tx, ty)标记为未访问(book[tx][ty] = 0)。这就是所谓的“回溯”。
    • 通过将已访问的格子标记为未访问,DFS可以确保在下一次从(x, y)出发时能够探索其他未访问的格子

最后的答案如下:

                                                                                         湖北师范大学计算机信息与工程学院-马列

                                                                                                                            湖师计信学科小组    

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值