题目描述

一个网格迷宫由n行m列的单元格组成,每个单元格要么是空地(用1表示)要么是障碍物
(用0表示)。任务是找一条从起点到终点的最短移动序列,其中UDLR代表上下左右移动到
相邻单元格。任何时候都不能在障碍物格中,也不能走到迷宫之外。起点和终点保证是空地
n,m<=100;
BFS走迷宫

思路

从迷宫的入口开始,进行层次优先遍历(BFS,我更喜欢称之为层次优先遍历,因为这样更形象)。BFS遍历的关键就是需要用到一个队列,在这道题中,只需要从入口点出发,依次看下它的上下左右四个结点是否可以走,如果可以走,就立即把这个结点push到队列尾部,然后每次找的时候就是从队头取出一个点,依次看它的上下左右四个方向。

遍历的路径的时候注意是从出口往入口找,所以需要用到一个栈保存一下路径。

其实这题难度不大,网上也有很多同志提供了代码,代码思路也基本和上述一样,不过有些注释是错误的!于是我分享一下我的code,如下:

#include<iostream>
#include<queue>
#include<stack>
using namespace std;
struct Node
{
	int row;
	int col;
};
#define MAXN 100
#define MAXM 100
int visit[MAXN][MAXM];
Node father[MAXN][MAXM];
queue<Node> q;
char* direction="UDLR";  // 四个方向
int dx[4] = {-1,1,0,0};	 // 四个方向对应的x方向增量
int dy[4] = {0,0,-1,1 };  // 四个方向对应的y方向增量
int maze[MAXN][MAXM];	// 迷宫各个点是否能走
int dist[MAXN][MAXM];	// 每个点到入口的最短距离
int last_dir[MAXN][MAXM];	// 每个点是从其父节点的经过何种方向走到的
int ROW,COL, xs , ys,  xt , yt; // 程序输入的行数、列数、开始点横纵坐标、终止点横纵坐标
void bfs(int row, int col)
{
/*从第row行第col列开始进行bfs遍历,,注意,改点为入口点*/
	Node n;
	n.row=row;
	n.col=col;
	visit[row][col]=1;	// 设置已被访问
	father[row][col]=n;	// 设置父亲节点为自己
	q.push(n);
	while (!q.empty())
	{
		Node front=q.front(); // 从队列头取出一个节点
		q.pop();
		// 依次遍历该结点的四个方向,是否走的通
		for (int i = 0;i < 4;i++)
		{
			int x=front.row+dx[i];
			int y= front.col + dy[i];
			// 如果某个方向的一点没出界,且没访问过,并且可以走
			if (x >= 0 && x<ROW && y >= 0 && y < COL && !visit[x][y] && maze[x][y])
			{
				Node node;
				node.row=x;
				node.col=y;
				visit[x][y]=1;
				father[x][y]=front;
				dist[x][y]=dist[front.row][front.col]+1;  // 到入口最短距离为其父节点到入口最短距离+1
				last_dir[x][y]=i;	
				q.push(node); // 把改点推入队列
			}
		}
	}

}

void print_path(int row, int col)
{
	stack<char> path;		// 用来保存输出路径
	/*从第row行第col列开始往前进行路径遍历,注意,改点为出口点*/
	while (true)
	{
		int father_row = father[row][col].row;
		int father_col = father[row][col].col;
		// 遍历的终止条件为到了入口点,还记得吗?入口点的父亲节点就是自己 ==> Line 27
		if (father_row == row && father_col == col)  //到了入口点
		{
			break;
		}
		else //没到入口点
		{
			path.push(direction[last_dir[row][col]]); // 记录该点是怎么从父亲节点过来的
			row=father_row;
			col=father_col;
		}
	}
	while (!path.empty())  // 输出路径
	{
		cout<<path.top();
		path.pop();
	}
}

int main()
{
	cin >> ROW >> COL >> xs >> ys >> xt >> yt;
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL ;j++) {
			cin >> maze[i][j];
		}
	}
	memset(visit, 0, sizeof(visit)); 
	bfs(xs,ys);
	cout << endl;
	print_path(xt,yt);
	cout << endl;
	return 0;
}

测试数据

样例输入:6行5列,入口(0,0),出口(0,4)

6 5 0 0 0 4     
1 1 0 1 1
1 0 1 1 1
1 0 1 0 0
1 0 1 1 1
1 1 1 0 1
1 1 1 1 1

输出:
BFS走迷宫

相关文章:

  • 2021-03-31
  • 2022-12-23
  • 2021-12-09
  • 2021-06-17
  • 2021-07-03
  • 2021-07-01
  • 2021-11-14
  • 2021-09-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-10
  • 2021-11-04
  • 2021-09-24
  • 2022-02-18
相关资源
相似解决方案