题面
样例
思路
我们要求的是从起点到终点的最短距离,那么我们每次可以记录一下这个点到起点的距离是多少,最后在直接输出最后一个点的这个值即可,所以我们想到了用一个数组来完成这个任务.因为地图上有些店是不可以走的,所以我们用一个二维数组来存储这个地图,从开始分别向它所能走的所有方向开始前进,然后遍历这些可以走的路,最后遍历到重点输出即可.
代码
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N=110;
typedef pair<int,int> PII;
// map用来存储地图,这个点是1还是0
// mark用来标记这个点是否走过,并且可以顺带记录最短距离(这恰恰是我们需要的)
int map[N][N],mark[N][N];
// dx dy代表x y两个方向上的向量。用循环来遍历就可以保证这个点搜索了所有他相邻的点
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1},n,m;
void bfs()
{
// 初始化保证所有的点都没有走过
memset(mark,-1,sizeof mark);
// q用来存储当前点(现在走到哪里了)
queue<PII>q;
q.push({0,0});
mark[0][0]=0;
// 当队列不空
while(!q.empty())
{
//把队头拿出来 扩展队头(所四个方向搜索)
PII top=q.front();
for(int i=0;i<4;i++)
{
int nex=top.first+dx[i],ney=top.second+dy[i];
// {nex,ney}这个点要在范围内并且没走过并且可以走再把它放进队列
if(nex>=0&&nex<n&&ney>=0&&ney<m&&mark[nex][ney]==-1&&map[nex][ney]==0)
{
mark[nex][ney]=mark[top.first][top.second]+1;
q.push({nex,ney});
}
}
q.pop();
}
cout<<mark[n-1][m-1];
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%d",&map[i][j]);
}
}
bfs();
}
tips
因为要存储所有的的点到起点的距离,那么这个mark数组我们也可以顺便完成记录这个点是否走过的任务,因为如果这个点已经走过了,我们就不需要再去走了,因为你走了回头路一定不是最短距离.
我们用队列来存储走的点,是因为我们需要把一开始那些距离近的点(离起点近的)"抛"出去,因为我们最终只需要得到最后一个点到起点的距离,搜索到最后一个点的时候就会停止搜索了,并且我们每一次放入新的点要与上一个有联系,更新的时候把mark数组要进行+1,是在上一个点的基础上+1,所以我们用队列存储.
我们把一个点可以走的四个方向(上下左右)用数组存储起来可以节省代码量,就不用写四个if了
当队列为空便遍历完了(要么走到终点,要么走不下去了两种情况),走不下去就不在满足if判断,所以输出的时候一定输出的是终点到起点的距离.