蓝桥杯题型——深度搜索(dfs)

   dfs常用于求解迷宫中有几条可以走到终点,哪一条是最短的等这类问题,他的基本思想是首先明确起点终点,以及这个图是几行几列(二维数组),然后从起点出发,如果不是终点,那么就调用dfs(递归),调用前标记已访问,调用后再标记未访问(回溯),随着这么每一步step不断记录下来,比上一次的step小,就记作min,最终输出min。

一、例题示范

已知起点是(1,1),终点是(4,3),有障碍和无障碍的地方均在图中体现,(这里我们可以创建一个二维数组,把这个图数字化(1代表空地,2代表有障碍物),求最短步数。

1 1 2 1

1 1 1 1

1 1 2 1

1 2 1 1 

1 1 1 2 

#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>

int p, q;
int m, n;
int min = 999999999;
int a[100][100];//1表示空地,2表示障碍物
int v[100][100];//1表示访问,0表示未访问
void dfs(int x, int y, int step)
{
	if (x == p && y == q)
	{
		if (step < min)
		{
			min = step;
		}
			return;
	}
	//顺时针试探
	//右
	if (a[x][y+1] == 1 && v[x][y+1] == 0)
	{
		v[x][y + 1] = 1;
		dfs(x, y + 1, step + 1);
		v[x][y + 1] = 0;
	}
	//下
	if (a[x + 1][y] == 1 && v[x + 1][y ] == 0)
	{
		v[x + 1][y ] = 1;
		dfs(x + 1, y, step + 1);
		v[x + 1][y] = 0;
	}
	//左
	if (a[x][y - 1] == 1 && v[x][y- 1] == 0)
	{
		v[x][y - 1] = 1;
		dfs(x, y - 1, step + 1);
		v[x][y - 1] = 0;
	}
	//上
	if (a[x-1][y] == 1 && v[x-1][y] == 0)
	{
		v[x-1][y ] = 1;
		dfs(x-1, y, step + 1);
		v[x-1][y] = 0;
	}
	return;
}
int main()
{
	
	scanf("%d%d", &m, &n);
	for (int i = 1; i <= m; i++)
	{ 
		for (int j = 1; j <= n; j++)
		{
			scanf("%d", &a[i][j]);
		}
	}
	int startx, starty;
	scanf("%d%d%d%d", &startx, &starty,&p,&q);//起点和终点
	v[startx][starty] = 1;
	dfs(startx, starty, 0);
	printf("%d", min);
	return 0;
}

运行后得出最短路径7。

二、代码优化

可以将我们的顺时针试探的那四段代码进行优化。

我们通过发现上下左右,他们都是对x和y做变化,那么把这些变化放到一个数组里面,就可以利用一个循环for,进行顺时针试探。

int dx[4] = { 0,1,0,-1 };
int dy[4] = { 1,0,-1,0 };
void dfs(int x, int y, int step)
{
	if (x == p && y == q)
	{
		if (step < min)
		{
			min = step;
		}
		return;
	}
	//顺时针试探
	for (int k = 0; k <= 3; k++)
	{
		int tx, ty;
		tx = x + dx[k];
		ty = y + dy[k];
		if (a[tx][ty] == 1 && v[tx][ty] == 0)
		{
			v[tx][ty] = 1;
			dfs(tx, ty, step + 1);
			v[tx][ty] = 0;
		}
	}
	
	return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值