Dfs迷宫入门-简简单单理解dfs

绘制一个n*m的迷宫,例如:
3x3的迷宫,迷宫为:
1 1 1
1 2 3
1 1 1
假设1为可通行,其他均为不可,可上下左右四个方向行走,默认(0,0)为起点,设置(2,2)为终点
那么dfs走迷宫的方式就为:

在这里插入图片描述
可能这个憨憨图画的不是很好,简单来说dfs就是试探四个方向,能走就走,不能走就回溯,一直走到能到终点为止,并且能找到所有能到终点的路径
方向为上下左右:
在这里插入图片描述
由于可以找所有人路径,所以我们设置一个值来存放最小的步数就可以啦,理论好理解,主要是代码:

#include  "stdio.h"
#include  "iostream"
using namespace std;
typedef long long ll;
ll n, m; //n*m的迷宫
ll end_x, end_y;
ll start_x, start_y;
ll the_min = 9999999;
ll the_map[100][100];//1为可行
ll v[100][100]; //相当于草稿纸,拿来画出当前的(x,y)的标记,没走过为0,走过为1
void dfs(ll x, ll y, ll step)
{
	if (x == end_x && y == end_y){ //首先判断停止条件
		if (step < the_min)
			the_min = step;
		return ; //这一条路走到终点了,回溯
	}
	if (v[x][y + 1] != 1&&the_map[x][y+1]==1){//向下试探,(x,y)是图中的没走过点
		v[x][y + 1] = 1; //走进(x,y+1)这个点,并将其标记为走过
		dfs(x, y + 1, step + 1);//进入(x,y+1)该走的路,进了一趟鬼门关
		v[x][y + 1] = 0;//(x,y+1)重生啦,他已经从上面的dfs走到终点过了,现在重生了可以试其他路了
	}
	if(v[x+1][y]!=1&&the_map[x+1][y]==1){//向右试探
		v[x+1][y] = 1;
		dfs(x+1, y, step + 1);
		v[x+1][y] = 0;
	}
	if(v[x-1][y]!=1&&the_map[x-1][y]==1){//向左
		v[x-1][y] = 1;
		dfs(x-1, y, step + 1);
		v[x-1][y] = 0;
	}
	if(v[x][y-1]!=1&&the_map[x][y-1]==1){//向上
		v[x][y-1] = 1;
		dfs(x, y-1, step + 1);
		v[x][y-1] = 0;
	}
}
int main()
{
    cin>>n>>m;//设置迷宫大小
	for (ll i = 0; i < n; i++){
		for (ll j = 0; j < m; j++){
			cin>>the_map[i][j];//绘制迷宫
		}
	}
	cin>>end_x>>end_y;//输入终点的坐标
	v[0][0]=1;//将起点设为走过,因为我们当前就在起点
	dfs(0,0,0);//默认(0,0)为起点,当前步数为0
	cout<<the_min<<endl;
	return 0;
}

当然这样写的话,如果有很多方向怎么办,难道还是要一个一个if来判断吗?
于是我们可以用数组来表示走的方向,然后用循环来实现试探路径。

int dir[5][2] = { {-1,0},{1,0},{0,-1},{0,1} };
void dfs(ll x, ll y, ll step) {//写出返回值类型,传入参数是什么
    if (x==end_x&&y==end_y) {//退出条件
        the_min = min(step, the_min);
        return ;
    }
    for (int i = 0; i < 4; i++) {//循环四个方向
        int new_x = x + dir[i][0];
        int new_y = y + dir[i][1];
        if (the_map[new_x][new_y] == 1 && vis[new_x][new_y] == 0) {
            vis[new_x][new_y] = 1;
            dfs(new_x, new_y, step + 1);
            vis[new_x][new_y] = 0;
        }
    }
}
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值