题目描述
迷宫由n行m列单元格组成(n,m都小于50),每个单元格要么是空地,要么是障碍物。
1表示空地 2 表示障碍物
现请你找到一条从起点到终点的最短路径长度
输入格式
第一行输入n,m表示有n行m列
接下来输入1,2分别表示空地和障碍物
最后输入起点和终点的坐标
输出格式
输出从起点到终点的最短路径长度
输入样例
输出样例
解法一(DFS)
算法:
1.以起点为节点,按照右、下、左、上的顺序去搜索一个新节点
2.将新节点标记为已访问,以此节点为起点重复第一步,再将刚刚访问的节点标记为未访问(回溯时需要用到)
3.到达终点时,进行回溯。
注:新节点访问和遍历后,要将节点标记为未访问。
#include<cstdio>
using namespace std;
int m,n,endx,endy,min=999;
int a[100][100];//1表示空地 2 表示障碍物
int v[100][100];//0表示未访问 0表示访问
int dx[4]={0,1,0,-1};//四个方向,右,下,左,上
int dy[4]={1,0,-1,0};
void DFS(int x,int y,int step)
{
if(x==endx&&y==endy)
{
if(step<min)
min=step;
return;
}
//顺时针试探 按照 右 下 左 上 顺序去寻找
for(int k=0;k<=3;k++)
{
int tx,ty;
tx=x+dx[k];
ty=y+dy[k];
if(a[tx][ty]==1&&v[tx][ty]==0)
{
v[tx][ty]=1;
DFS(tx,ty,step+1);
v[tx][ty]=0;
}
}
}
int main()
{
int startx,starty;
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);//1表示空地 2 表示障碍物
}
}
scanf("%d%d%d%d",&startx,&starty,&endx,&endy);
v[startx][starty]=1;
DFS(startx,starty,0);
printf("%d",min);
return 0;
}
解法二(BFS)
算法
1.将起点入队
2.队首节点可移动的点入队
如果没有可以移动的点,将队首节点出队
3.在寻找可以移动的节点时,按照右,下,左,上的顺序入队
注:将每个节点设为结构体
已访问过的点不能再次被访问
以上图为例
初始时队列中(x,y,step)
(1,1,0)
当step=1时,将起始点作为节点,找出所有可移动的点进行入队,并将节点出队
(1,2,1)(2,1,1)
当step=2时,将每一个点作为节点找出可移动的点进行入队,并将节点出队
(2,2,2)(3,1,2)
当step=3时,与上步骤相同
(2,3,3)(3,2,3)(4,1,3)
当step=4时,与上步骤相同
(2,4,4)(5,1,4)
当step=5时,与上步骤相同
(3,4,5)(1,4,5)(5,2,5)
当step=6时,与上步骤相同
(4,4,6)(5,3,6)
当step=7时,与上步骤相同
(4,3,7)
#include<bits/stdc++.h>//BFS搜索
using namespace std;
int a[100][100];//1表示空地 2 表示障碍物
int v[100][100];//0表示未访问 0表示访问
struct point
{
int x;
int y;
int step;
};
queue<point> r;//申请队列
int dx[4]={0,1,0,-1};//四个方向,右,下,左,上
int dy[4]={1,0,-1,0};
int main()
{
//输入
int n,m,startx,starty,endx,endy;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
}
}
scanf("%d%d%d%d",&startx,&starty,&endx,&endy);//起点终点坐标
//BFS
point start;//起点是结构体类型
start.x=startx;
start.y=starty;
start.step=0;
r.push(start);//将起点入队
v[startx][starty]=1;
int flag=0;
while(!r.empty()){
int x=r.front().x;
int y=r.front().y;
if(x==endx&&y==endy)
{
flag=1;
printf("%d",r.front().step);
break;
}
for(int k=0;k<=3;k++)
{
int tx,ty;
tx=x+dx[k];
ty=y+dy[k];
if(a[tx][ty]==1&&v[tx][ty]==0)
{
//入队
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)
printf("no answer");
return 0;
}