844 走迷宫-增改版

给定一个n*m的二维整数数组,用来表示一个迷宫,数组中只包含0或1,其中0表示可以走的路,1表示不可通过的墙壁。

最初,有一个人位于左上角(1, 1)处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。

请问,该人从左上角移动至右下角(n, m)处,至少需要移动多少次。

数据保证(1, 1)处和(n, m)处的数字为0,且一定至少存在一条通路。

输入格式

第一行包含两个整数n和m。

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

输出格式
从出口处一直倒着输出走过的路线坐标。
再一个整数,表示从左上角移动至右下角的最少移动次数。

数据范围

1≤n,m≤1001≤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

输出样例:

4 4
3 4
2 4
2 3
2 2
2 1
2 0
1 0
8

实现思路:

经典问题-迷宫问题,因为距离等为1,很好地运用bfs算法来实现。

AC代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N=110;
int n,m,G[N][N],d[N][N];//d用于记录到达每个可走坐标的距离 
typedef pair<int,int> PII;
queue<PII> q;
PII pre[N][N];

int bfs() {
	q.push({0,0});//入队初始坐标 
	memset(d,-1,sizeof(d));
	d[0][0]=0;//初始化初始距离为0			 	  b
	int dx[4]= {-1,0,1,0},dy[4]= {0,1,0,-1};// a  o  c   通过dx dy实现坐标上下左右的移动
	while(!q.empty()) {						//    d
		PII p=q.front();
		q.pop();
		for(int i=0; i<4; i++) {
			int x=p.first+dx[i],y=p.second+dy[i];
			if(x>=0&&x<n&&y>=0&&y<m&&G[x][y]==0&&d[x][y]==-1) {//如果是可走的道路并且未走到过
				d[x][y]=d[p.first][p.second]+1;//距离+1
				pre[x][y]=p;//记录当前道路的之前一个道路点的坐标 
				q.push({x,y});
			}
		}
	}
	int a=n-1,b=m-1;
	while(a||b) {//当a和b都大于0的时候才是合法下标 输出坐标(x,y) 
		cout<<a<<" "<<b<<endl;
		auto t=pre[a][b];
		a=t.first,b=t.second;
	}
	return d[n-1][m-1];//返回到达出口的最短距离 
}

int main() {
	cin.tie(0);
	cin>>n>>m;
	for(int i=0; i<n; i++) {
		for(int j=0; j<m; j++) {
			cin>>G[i][j];
		}
	}
	cout<<bfs()<<endl;
	return 0;
}
posted @ 2021-02-18 22:21  coderJ_ONE  阅读(40)  评论(0编辑  收藏  举报