BFS:走出迷宫并输出最小步数

本文介绍了如何利用广度优先搜索(BFS)算法解决一个经典的迷宫问题,从起点S到终点T寻找最短路径。在给定的n*m迷宫中,每个节点可以向上、下、左、右四个方向移动,遇到墙壁则无法通行。通过BFS,我们可以记录每一步的层数,从而找到最短步数。在示例中,给出了一个具体的迷宫和解决方案,最后详细展示了BFS的实现代码。文章强调了在BFS过程中结点结构体的重要性,以及判断函数和增量数组在矩阵问题中的作用。
摘要由CSDN通过智能技术生成

目录

背景

描述

例子

思路

完整代码

收获总结

背景

描述

给定一个n*m大小的迷宫,其中*代表不可通过的墙壁,而“.”代表墙壁,S表示起点,T代表重点。移动过程中,如果当前位置是(x,y)(下标从0开始),且每次只能前往上下左右(x,y+1),(x,y-1),(x-1,y),(x+1,y)四个位置的平地,求从起点S到达终点T的最少步数。

例子

. . . . .
. * . * .
. * S * .
. * * * .
. . . T *

上面的例子中,起点S的坐标是(2,2),终点T的坐标是(4,3),最少步数为11。

思路

由于BFS是通过层次顺序来遍历,可以从起点开始记遍历的层数,到终点时遍历的层数即为步数。

完整代码

#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<cstring>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>

using namespace std;

const int maxn = 100;

struct Node{
	int x,y;//坐标(x,y)
	int step = 0;//是层数也是步数 
}S,T,node;//分别是起点、终点、临时结点

int n,m;//行和列
char maze[maxn][maxn];//存放迷宫的路况
bool inq[maxn][maxn] = {false};//是否已经入过BFS的队列 
int X[4] = {0,0,-1,1};//增量数组 
int Y[4] = {1,-1,0,0};

//判断当前位置是否能够入队
bool judge(int x,int y){
	//越界,不行
	if(x<0||x>=n||y<0||y>=m)return false;
	//碰壁,也不行
	if(maze[x][y]=='*')return false;
	//已经入过了,不行
	if(inq[x][y])return false;
	
	return true; 
}

//BFS函数的任务是返回到达终点所走步数,如果到达不了就返回-1
int BFS(){
	queue<Node> que;//定义队列
	que.push(S);//起点入队
	while(!que.empty()){
		Node top = que.front();//取出队首元素
		que.pop();//队首元素出队
		if(top.x == T.x&&top.y == T.y)return top.step;//抵达了终点,返回步数 
		
		for(int i=0;i<4;i++){
			int newX = top.x + X[i];
			int newY = top.y + Y[i];
			if(judge(newX,newY)){//判断是否能够入队 
				node.x = newX;
				node.y = newY;
				node.step = top.step+1;//因为node是top的下一层结点 
				que.push(node);//node入队
				inq[newX][newY] = true;//设置node已经入队 
			}
		}
	}
	return -1; 
} 


int main(){
	
	scanf("%d%d",&n,&m);
	getchar();//吸收换行符
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			scanf("%c",&maze[i][j]);
			getchar();
		}
	}
	scanf("%d%d%d%d",&S.x,&S.y,&T.x,&T.y);
	printf("%d\n",BFS());
	 
	return 0;
}

收获总结

1. 要知道把最少步数和BFS联系在一起,并在结点结构体里加层数(也是步数)step属性

2. BFS必备:队列,判断函数

3. 矩阵题必备:增量数组,判断函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CSU迦叶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值