一、题意
从一个迷宫中找出起点到终点的最短的路径
第一行输入迷宫的大小
接下来输入迷宫各个方格的障碍情况1表示该方格上没有障碍物,2表示该方格上有障碍物
输入完迷宫各个方格的障碍物情况之后输入4个数据,前两个数据表示起点坐标,后两个数据表示终点的坐标。
然后显示起点到终点最少步数是多少
例如输入
5 4
1 1 2 1
1 1 1 1
1 1 2 1
1 2 1 1
1 1 1 2
1 1 4 3
//则输出
7
二、代码
1.代码的实现
代码如下(示例):
#include<bits/stdc++.h>
using namespace std;
int a[50][50],v[50][50];
struct point{
int x;
int y;
int step;
};
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
queue<point> r;//申请队列 队列中元素的类型为尖括号里面的 队列名称为r
//定义队列的模板是 queue<元素类型> 队列名称;
int main()
{
int n,m,startx,starty,p,q;//输入棋盘大小开始起点和终点
cin>>n>>m;//n对应i m对应j
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
cin>>startx>>starty>>p>>q;
//bfs
point start;
start.x = startx;
start.y = starty;
start.step = 0;
r.push(start);//将起点start入队
v[startx][starty]=1;//用来标记已经访问过的点
int flag = 0;//表示是否有可行路径
while(!r.empty())//如果队列不为空
{
int x=r.front().x;
int y=r.front().y;
if(x==p && y==q)
{
flag = 1;//说明找到了终点
cout<<r.front().step;
break;
}
for(int k=0;k<=3;k++)
{
int tx;
int ty;
tx = x+dx[k];
ty = y+dy[k];
if(a[tx][ty]==1 && v[tx][ty]==0)//如果a是空地,并且未访问过
{
//入队
point temp;//新创建一个临时point结构体变量,然后把temp入队
temp.x = tx;
temp.y = ty;
temp.step = r.front().step + 1;
r.push(temp);
v[tx][ty] = 1;//则设置为已经访问
}
}
r.pop();//拓展完了需要将队首元素出队
}
if(flag==0)//找不到终点
{
cout<<"没有答案";
}
}
2.读入数据
代码如下(示例):
5 4//表示迷宫的大小
1 1 2 1//1表示空地,2表示障碍物
1 1 1 1
1 1 2 1
1 2 1 1
1 1 1 2
1 1 4 3//1,1表示起点的坐标 4,3表示终点的坐标
7//改行为输出的结果为7
//下面图片来自bilibili麦克老师讲算法
设当前点为x,y则要上下左右移动时需进行如图所示的计算方式
三、总结
bfs(广度优先搜索)求解思路:将队首节点和可以拓展的点入队,如果没有可以拓展的点,将队首节点出队,重复以上步骤,知道到达目标位置或者队列为空时。bfs搜索到的结果一定是最短的,bfs运用到了队列。
dfs(深度优先搜索)求解思路:从某点出发沿着一个方向往下试探,当找到目标位置时,还需回溯,以便于找到所有的路径,再比较最短的路径,比较盲目,效率低于bfs,dfs使用到了栈。