题目描述
给定一个N*M的网格迷宫G。G的每个格子要么是道路,要么是障碍物(1是道路,0是障碍)
已知迷宫的入口位置为(x1,y1),出口位置为(x2,y2)。问从入口走到出口,最少要多少个格子。
输入描述
输入第1行包含两个正整数N,M,分别表示迷宫的大小。
接下来输入一个N*M的矩阵。若Gi,j=1表示为道路,否则表示其为障碍物。
最后一行输入四个整数x1,y1,x2,y2,表示入口位子和出口位置。
1<=N,M<10^2
输出描述
一个整数,表示最短的路径
若无法到达出口,则输出-1
正片开始
特殊情况1:看到无法到达出口输出-1的时候,立马想到当出口位置刚好是0的情况,那么直接cout<<-1就行了
特殊情况2:当然还有一种特殊情况,就是出口和入口的位置相同,那就是cout<<0了(题目问的是入口走到出口)
那么接下来,就是bfs的内容了,我们直接边看代码边看注释理解吧
#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node{
int x;
int y;
int dis; //路径距离
};
node rk,ck;
int dir[4][2]={ //一般都是按左,上,右,下的顺序进行
{0,-1}, //左移 {行,列}
{-1,0},//上移
{0,1},//右移
{1,0}//下移
};
int n,m,mg[105][105];
bool check(int x,int y){
return x>=0&&x<n&&y>=0&&y<m;
}
int bfs(int x,int y){
queue<node>q;
node start;
start.x=x; //初始化
start.y=y;
start.dis=0;//距离初始化0
q.push(start);
while(!q.empty()){
node next;
start=q.front(); //取出当前路径
q.pop(); //删除当前路径,准备下一个路径
for(int i=0;i<4;i++){ //执行左,上,右,下的移动
next.x=start.x+dir[i][0];
next.y=start.y+dir[i][1];
next.dis=start.dis;
if(next.x==ck.x-1&&next.y==ck.y-1){//找到出口了
return ++next.dis;//这个++是出口本身也算一个距离
}
else if(check(next.x,next.y)&&mg[next.x][next.y]==1){ //没有超过迷宫范围&&当前的路是可走的
mg[next.x][next.y]=0;//走过了,不走了,标记为障碍物
next.dis++;//当前的距离+1;
q.push(next); //保存当前路径
}
}
}
return -1;//bfs全找遍了,也找不到出口,说明路是不通的,那就返回-1;
}
signed main(){
cin>>n>>m;
for(int i=0;i<n;i++){ //从0开始,即0代表1,n-1代表n
for(int j=0;j<m;j++){
cin>>mg[i][j];
}
}
cin>>rk.x>>rk.y>>ck.x>>ck.y;
if(mg[ck.x-1][ck.y-1]==0){ //出口本身是障碍,出不去
cout<<-1;
return 0;
}
if(rk.x==ck.x&&rk.y==ck.y) { //入口和出口重合,那也不用判断了,直接0步
cout<<0;
return 0;
}
//正片开始
int num=bfs(rk.x-1,rk.y-1); //这里要-1,因为mg是从0开始的
cout<<num;
}
代码可能看得很多,因为我故意换行了,这样看得清楚点,但其实里面的原理很简单的。看不懂的,去康康BFS地图搜索的相关文章
但其实BFS和DFS的原理和区别是这样的
(BFS类似多个老鼠朝不同的方向(方向:左、上、右、下)一起找出口(他们的动作是同步的),第一个老鼠先出去的就是最短路径)
(DFS类似一个老鼠找出口,遇到障碍返回之前的路口,然后继续往别的方向继续找(方向:左、上、右、下),直到找到出口)