蓝桥杯-走迷宫(BFS)

0.题目

给定一个 n×m 的二维整数数组,用来表示一个迷宫,数组中只包含 0 或 1,其中 0 表示可以走的路,1 表示不可通过的墙壁。
最初,有一个人位于左上角 (1,1) 处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。
请问,该人从左上角移动至右下角 (n,m) 处,至少需要移动多少次。
数据保证 (1,1) 处和 (n,m) 处的数字为 0,且一定至少存在一条通路。

输入格式

第一行包含两个整数 n 和 m。
接下来 n 行,每行包含 m 个整数(0 或 1),表示完整的二维数组迷宫。

输出格式

输出一个整数,表示从左上角移动至右下角的最少移动次数。

数据范围
1≤n,m≤100

输入样例:
5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

输出样例:
8

1.题解

1.1 BFS搜索

思路

这里为何使用BFS搜索呢?由于我们求得是最短路径,BFS广度优先多种情况齐头并进,必然有一种情况最先到达终止条件,这时我们直接终止搜索即可,不像DFS深度搜索一种情况不对还要进行回溯,造成大量重复计算.
这里使用BFS搜索,我们依旧要考虑终止条件,边界条件,以及构建BFS搜索.
1.终止条件(check函数):到达终点(x2,y2); 如果BFS搜索结束(while循环结束)还没有找到,就输出-1
2.边界条件(pd函数): 不可超出边界,不可重复走,不可走有障碍的路径
3.BFS搜索:

  • 3.1 初始化
  • 3.2 外层while循环
  • 3.3 内层使用简单图论+for训话,表示向四周移动; 使用队列实现BFS搜索
  • 3.4 使用vis数组记录到达当前位置步数. 1.不会重复,pd函数中有专门判断 2.一定是最小,由于是BFS搜索,肯定是先记录到较小步数,之后其他较大步数不会记录

注意:
1.这里我使用x1,y1,x2,y2作为初始坐标,发生了报错:mathcalls.h 中已经定义了 double y1(double),后改为使用pair对直接表示
2.不要使用map关键字作为标识符!!!

代码

#include<bits/stdc++.h>
using namespace std;
int n, m;
int Map[101][101];
int vis[101][101] = {0};
pair<int, int> Start, End;

int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};

// 路径检测
bool pd(int x, int y) {
	// 超出边界
	if(x < 1 || x > n || y < 1 || y > m) {
		return false;
	}
	// 已经走过了
	if(vis[x][y] >= 1) {
		return false;
	}
	// 不是路径不能走
	if(Map[x][y] != 1) {
		return false;
	}
	return true;
}

// 终点检测
bool check(int x, int y) {
	if(x == End.first && y == End.second) {
		cout << vis[x][y];
		return true;
	}
	return false;
}


void BFS() {
	// 初始化
	queue<pair<int, int>> q;
	q.push(make_pair(Start.first, Start.second));
//	vis[x1][y1] = 1;

	// BFS总循环
	while(!q.empty()) {
		pair<int, int> tempNode = q.front();
		int x = tempNode.first;
		int y = tempNode.second;
		q.pop();
		// 进行BFS扩展
		for(int i = 0; i < 4; i++) {
			int newX = x + dx[i];
			int newY = y + dy[i];
			// 通过路径检测
			if(pd(newX, newY)) {
				// 更新vis值 
				vis[newX][newY] = vis[x][y] + 1;
				
				// 进行结果检测
				if(check(newX, newY)) {
					exit(0);
				}
				
				// 不是最终点,更新队列
				q.push(make_pair(newX, newY)); 
			}
		}
	}
	cout << -1;
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= m; j++) {
			cin >> Map[i][j];
		}
	}
	cin >> Start.first >> Start.second >> End.first >> End.second;
	BFS();
}
posted @   DawnTraveler  阅读(69)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示