【算法与数据结构】——最经典的走迷宫最短路径算法(广度优先搜索BFS的典型实例)

迷宫的最短路径

问题描述
给定一个大小为N×M的迷宫。迷宫由通道和墙壁组成,每一步可以向邻接的上下左右四个的通道移动。请求出从起点到终点所需的最小步数。请注意,本题假定从起点一定可以移动到终点。(N,M≤100)
(‘#’, ‘.’ , ‘S’, 'G’分别表示墙壁、通道、起点和终点)

样例输入:
10 10

#S######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#...G#

样例输出:
22



—— 分割线 ——



分析:
首先说明,本题其实是在为蓝桥杯 算法提高 学霸的迷宫这道题做一个铺垫
这道题放在《算法与数据结构》专栏里面是因为其实这是一个很很很很经典的迷宫问题,前面的概论只是介绍了BFS(还有DFS)的原理,但是毕竟实践才是检验真理的唯一标准。而这道题,个人感觉是任何想要深入了解搜索算法的人的必修课(也是所有初学者必须看的第一题)。
我相信当你在解决了这个问题之后,将会对广度优先搜索算法有一个十分深刻的认识,并且之后对于那些涉及到迷宫问题或者说图的遍历问题时,你将更加的熟练
废话不多说,直接开整!!!

变量声明:len[x][y]表示从图的起点到坐标为x,y的点的距离。
解决迷宫问题的大致思路如下:
① 从起点开始,将当前点加入队列,并设置len[start_x][start_y]为0
② 先进入一个判断队列是否为空的while循环,然后再从队列首端取出元素p(即队列中的第一个点)
③ 接着再进入一个for循环,该循环用来遍历当前点的四个移动方向是否合法,合法的我们标记该位置为已走,并且把len[该点x][该点y]=len[p.x][p.y]+1,最终在将要退出for循环前,判断该点坐标是否等于出口坐标,是则退出循环输出结果,否则就把这个当前点添加进队列,然后再进行下一次循环
④ 当四次循环都结束后(即四个方向走走遍后),转②(前提是上面的循环是正常退出的,即i==4)。否则就表示找到了出口,由于这是深度优先,是一级一级走的,故当找到终点时,当前步数一定会是最短的。

注:其实上面第3步的目的就是把每个可前进点都放进队列中,并且统计好该点的距离信息,然后对于while循环而言,下一次取出的p点就是之前走过的某个点了,你又进行下面的步骤其实就是在不断的发散该点可能的途径,就像在宽度优先搜索的图论介绍中的“分身”概念。然后这个被取出的p点不断的更换不断的发散,最后总能到达目的地(如果存在)

下面给出本题的完整代码:


—— 分割线 ——


#include<iostream>
#include<queue>
using namespace std;

const int MAX_X=105,MAX_Y=105;				//图的最大规格 
const int INF=1000000;						//预设一个很大的不会取到或出现的值来作为未走过的标记 
char map[MAX_X][MAX_Y];						//图 
int n,m;									//对某次而言的规格 
int start_x,start_y; 						//起始地点(入口) 
int goal_x,goal_y;							//目标地点(出口) 
int len[MAX_X][MAX_Y];						//len[x][y]的含义:入口到坐标为x,y的点的距离 
int move[4][2]={{1,0},{0,-1},{0,1},{-1,0}};//视为向量(以(0,0)点为出发点)四种移动方式分别是{'D','L','R','U'} 

struct Point{								//结构体(点的抽象实现) 
	int x,y;
	Point(int a,int b){	x=a,y=b; }
};

void bfs()
{
	queue<Point> q;
	for(int i=0;i<n;i++)					// 初始化所有的点为未走过 
    {
        for(int j=0;j<m;j++)
            len[i][j]=INF;
    }
	q.push(Point(start_x,start_y));
	len[start_x][start_y]=0;			    //入口标记为0,表示已经走过了 
	
	while(!q.empty())					    //题目保证有终点,故可以这么设置循环条件 
	{
		Point p=q.front();q.pop();			//取第一个队列元素进行发散,并将其推出 
		int i;
		for(i=0;i<4;i++)		  			//分别判断四种行走方式 
		{
			int new_x=p.x+ move[i][0];
			int new_y=p.y+ move[i][1];
			if(new_x>=0&&new_x<n&&new_y>=0&&new_y<m				  //判断未出边界 
				&&map[new_x][new_y]!='#'&&len[new_x][new_y]==INF)//判断可移动并且未走过 
			{
				q.push(Point(new_x,new_y));				//入队列 
				len[new_x][new_y]=len[p.x][p.y]+ 1;		//赋值为前一个路程长度加1 
				if(new_x==goal_x && new_y==goal_y) break;//如果已经到了终点则直接退出循环 
			}
		}
		if(i!=4) break;	//对于上面的退出作是否是非法退出的判断,是则表示找到了出口,直接退出全过程 
	}
}

int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++) cin>>map[i];
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
		{
			if(map[i][j]=='S')
				start_x=i,start_y=j;
			if(map[i][j]=='G')
				goal_x=i,goal_y=j;
		 } 
	bfs();
	cout<<len[goal_x][goal_y]<<endl;
	return 0; 
}


http://www.niftyadmin.cn/n/1038405.html

相关文章

LateX——TeX的安装与使用

首先LaTeX有多个版本&#xff0c;从网上搜了一下&#xff0c;下了一个TeX Live&#xff0c;感觉这个就像python.exe&#xff0c;里面也自带编译器TeXworks edtior&#xff0c;写完编译一下就能在当前目录生成一个PDF。TeXstudio就像是Pycharm&#xff0c;图形化界面做的肯定要比…

【蓝桥杯】 算法提高 学霸的迷宫(深度优先搜索、BFS)

算法提高 学霸的迷宫 问题描述 学霸抢走了大家的作业&#xff0c;班长为了帮同学们找回作业&#xff0c;决定去找学霸决斗。但学霸为了不要别人打扰&#xff0c;住在一个城堡里&#xff0c;城堡外面是一个二维的格子迷宫&#xff0c;要进城堡必须得先通过迷宫。因为班长还有妹…

2020年美赛E题翻译

2020 ICM Weekend 1 Problem E: Drowning in Plastic 自1950年代以来&#xff0c;由于其用途广泛&#xff0c;例如食品包装&#xff0c;消费品&#xff0c;医疗设备和建筑业&#xff0c;塑料制造业呈指数增长。尽管有很大的好处&#xff0c;但与增加塑料生产相关的负面影响值得…

【蓝桥杯】 2018年决赛C/C++B组 #2 激光样式(动态规划、DFS)

2018决赛真题C/CB组 激光样式 问题描述 x星球的盛大节日为增加气氛&#xff0c;用30台机光器一字排开&#xff0c;向太空中打出光柱。 安装调试的时候才发现&#xff0c;不知什么原因&#xff0c;相邻的两台激光器不能同时打开&#xff01; 国王很想知道&#xff0c;在目前这种…

2020美赛D题翻译

Problem D: Teaming Strategies 随着社会之间的联系越来越紧密&#xff0c;他们面临的挑战也越来越复杂。我们依靠具有不同专业知识和不同见解的跨学科团队来解决许多最具挑战性的问题。在过去的50多年中&#xff0c;我们对团队成功的概念性理解有了很大进步&#xff0c;从而使…

【蓝桥杯】 2018年决赛C/C++B组 #4 调手表 (BFS、模拟)

2018决赛真题C/CB组 调手表 问题描述 小明买了块高端大气上档次的电子手表&#xff0c;他正准备调时间呢。 在M78星云&#xff0c;时间的计量单位和地球上不同&#xff0c;M78星云的一个小时有n分钟。 大家都知道&#xff0c;手表只有一个按钮可以把当前的数加一。在调分钟的时…

2020美赛A题翻译

1 Problem A: Moving North 全球海洋温度影响某些海洋生物的栖息地质量。当温度变化太大以至于无法继续生长时&#xff0c;这些物种便开始寻找其他更适合其现在和将来的生活和生殖成功的栖息地。在美国缅因州的龙虾种群中就可以看到一个例子&#xff0c;该种群正缓慢地向北迁移…

【蓝桥杯】 2017年决赛C/C++B组 #2 磁砖样式 (DFS、集合去重)

2017决赛真题C/CB组 磁砖样式 问题描述 小明家的一面装饰墙原来是 3╳10 的小方格。 现在手头有一批刚好能盖住2个小方格的长方形瓷砖。 瓷砖只有两种颜色&#xff1a;黄色和橙色。 小明想知道&#xff0c;对于这么简陋的原料&#xff0c;可以贴出多少种不同的花样来。 小明有…