理解与感悟:
1、BFS适合寻找最短的路径,因为是按层一层层找的,第一个符合条件的就是最短的路径。
2、走迷宫一般使用delta_x,delta_y,就是左上右下,或者上右下左的二组变量常数,在蛇形排列中,还强调了四个方向的初始化方向,在走迷宫时,不强调顺序,哪个方向先来都是一样的。
3、距离数组一般初始化为-1,表示未探索的位置。有时其它题中也表示不可以走的墙,具体问题再具体分析。
memset(d,-1,sizeof d);
4、利用一个栈,将反着遍历出来的路径打印出来,是一个很巧妙的办法:
//输出路径
stack<PII> s1; //利用一个栈,把路径掉过来
int x = n - 1, y = m - 1; //出口
while (x || y) {
s1.push({x, y});
auto t = Prev[x][y];
x = t.first, y = t.second;
}
//加入出发节点
s1.push({0, 0});
while (!s1.empty()) {
auto t = s1.top();
cout << t.first << ' ' << t.second << endl;
s1.pop();
}
C++ 代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
const int N=110;
int g[N][N],d[N][N]; //g[N][N]装入原始的地图数据 , d[i][j]记录的是i,j这个位置离出发点的最短路径是多长
typedef pair<int,int> PII;
//左上右下四个方向
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
queue<PII> q;
PII Prev[N][N];//记录每个节点是从哪个节点过来的
int n,m;
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>g[i][j];
memset(d,-1,sizeof d);
d[0][0]=0;
q.push({0,0});
while(!q.empty()){
auto t=q.front();
q.pop();
for(int i=0;i<4;i++){
int x=t.first+dx[i],y=t.second+dy[i];
if(x>=0 && x<n && y>=0 && y<m && g[x][y]==0 && d[x][y]==-1){
q.push({x,y});
d[x][y]=d[t.first][t.second]+1;
//x,y这个点是来自哪个点
Prev[x][y] = t;
}
}
}
//输出路径
stack<PII> s1; //利用一个栈,把路径掉过来
int x = n - 1, y = m - 1; //出口
while (x || y) {
s1.push({x, y});
auto t = Prev[x][y];
x = t.first, y = t.second;
}
//加入出发节点
s1.push({0, 0});
while (!s1.empty()) {
auto t = s1.top();
cout << t.first << ' ' << t.second << endl;
s1.pop();
}
printf("%d ",d[n-1][m-1]);
return 0;
}