迷宫之深搜回溯算法(B站)

迷宫之深搜回溯算法

题目描述

在这里插入图片描述


核心思路

用char Map0 [ 9 ] [ 9 ] [9][9] [9][9]来存储题目给定的地图,由于是它的数组下标是从0开始的,但是我们想把点的坐标从1开始,所以我们可以对原地图做出转换,得到新地图char Map [ 9 ] [ 9 ] [9][9] [9][9]

其实这个转换意义不大,只不过说从1开始比较符合常理而已。

由于需要记录路径,所以我们需要两个数组来记录路径, P a t h X [ ] PathX[] PathX[]数组用来记录横坐标, P a t h Y [ ] PathY[] PathY[]用来记录纵坐标。

我们还需要一个判重数组来判断某个点是否已经被访问过了,给这个点打上封条,用bool数组 V i s i t e d [ ] Visited[] Visited[]来记录某个点是否已经被走过。

由于需要记录路径,我们还需要一个变量step,用来记录当前遍历的这个点是在递归树中的第几层。

问题:能不能把xx>=1&&xx<=m&&yy>=1&&yy<=n删去呢?

可以!因为我们已经对原地图做出转换得到了新地图Map,那么Map0中有的全都被映射到新地图Map中了。但是由于新地图Map它是全局数组,初始化为0,当原地图被映射到新地图后,只占用了新地图的第1行到第m行,第1列到第n列,然而并没有用到第0行和第m+1行,第0列到第n+1列。也就是说,相当于给地图加了一圈“空墙”,这些空墙全都是空格,而不是.或者#

所以可以去掉这个判断,因为即使它走出了边界,但是由于此时 M a p [ x x ] [ y y ] Map[xx][yy] Map[xx][yy]的值是空格,不是.或者#,因此不满足 M a p [ x x ] [ y y ] = = ′ . ′ Map[xx][yy]=='.' Map[xx][yy]==.这个语句,也进不去语句内部。

在这里插入图片描述

问题:能否把step+1改为++step呢?

不能!!!因为假设根节点是第一层,从根节点开始DFS,那么根节点的step=1,假设我们用了++step这个语句,那么由于这个语句的特性,此时step变为了2,但是此时还没有再次递归调用进入DFS函数,那么意义就变为了step=2,也就是根节点是处在第二层了,然后递归进入DFS函数,访问根节点的孩子节点,那么由于递归进入DFS函数了,此时step为2,也就是说孩子节点是处在第二层。但是根节点竟然和孩子节点都处于同一层!!!这是不允许的,所以不能写成++step。

我们应该写成step+1,因为此时step=1,表明根节点是处于第一层,但是它这个step+1语句的结果是会当再次递归进入DFS函数时,它才变为2,也就是说step=2会属于他的孩子节点,而不会属于根节点。

能否不用判重数组Visited呢?

可以!因为我们在新地图中,用.表示可以走,用#表示不可以走,那么当走过了 ( x , y ) (x,y) (x,y)这个点后,我们就可以把这个点设置为#,表示不可以走,即 M a p [ x ] [ y ] = Map[x][y]= Map[x][y]=#。然后再回溯时,再把这个点设置为可走,即 M a p [ x ] [ y ] = ′ . ′ Map[x][y]='.' Map[x][y]=.

在这里插入图片描述

画出递归树和路径如下:

在这里插入图片描述

能否只做 V i s i t e d [ x ] [ y ] = t r u e Visited[x][y]=true Visited[x][y]=true而不恢复现场 V i s i t e d [ x x ] [ y y ] = f a l s e Visited[xx][yy]=false Visited[xx][yy]=false呢?

不能!!!!分析如下:

在这里插入图片描述


代码

在这里插入图片描述

#include<iostream>
using namespace std;
char Map0[9][9]={{".#..."},
                 {".#.#."},
                 {"....."},
                 {".#.#."}
                };
char Map[9][9];
int m=4,n=4;	//m是行数  n是列数
int SouX=3,SouY=1;
int DesX=m,DesY=n;
int PathX[9*9];
int PathY[9*9];
bool Visited[9][9];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};

void ChangeMap()
{
    for(int i=1;i<=m;i++)
        for(int j=1;j<=n;j++)
            Map[i][j]=Map0[i-1][j-1];
}

void Print(int step)
{
    printf("Path:");
    for(int i=1;i<=step;i++)
        printf("%d,%d ",PathX[i],PathY[i]);
    cout <<endl;
}

void DFS(int x,int y,int step)
{
    printf("%d,%d step=%d\n",x,y,step);
    PathX[step]=x;
    PathY[step]=y;
    Visited[x][y]=true;
    if(x==DesX&&y==DesY)
        print(step);
    for(int i=0;i<4;i++)
    {
        int xx=x+dx[i];
        int yy=y+dy[i];
        if(Map[xx][yy]=='.'&&!Visited[xx][yy])
        {
            DFS(xx,yy,step+1);
            Visited[xx][yy]=false;
        }
    }
}
int main()
{
    ChangeMap();
    DFS(SouX,SouY,step);
    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷心菜不卷Iris

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值