迷宫最短路径
题目描述
设计一个算法找一条从迷宫入口到出口的最短路径。
输入
迷宫的行和列m n
迷宫的布局
输出
最短路径
样例输入
6 8
0 1 1 1 0 1 1 1
1 0 1 0 1 0 1 0
0 1 0 0 1 1 1 1
0 1 1 1 0 0 1 1
1 0 0 1 1 0 0 0
0 1 1 0 0 1 1 0
样例输出
(6,8)(5,7)(4,6) (4,5)(3,4) (3,3) (2,2)(1,1)
这是一道比较简单练习广搜的题,然后我刚开始写这题时并没有学习广搜,只是初步接触了一下深搜,故一开始使用深搜,显然,时间超限,后面学习广搜才成功解决,然后我把深搜和广搜的代码都写一下,正好练习一下。首先贴出深搜代码。
#include <iostream>
#include<stdio.h>
using namespace std;
int m,n,Min=98769954;
int a[1005][1005];
int vis[1005][1005];
typedef struct point
{
int x3,y3;
} Point;
Point path[100010];
Point shortest_path[10010];
int moves[8][2]= {{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1}};
void dfs(int x,int y,int step)
{
if(x==m&&y==n)
{
if(step<Min)
{
Min=step;
for(int i=0;i<step;i++)
{
shortest_path[i]=path[i];
}
}
return ;
}
for(int i=0; i<8; i++)
{
int nx=x+moves[i][0];
int ny=y+moves[i][1];
if(nx<1||nx>m||ny<1||ny>n) continue;
if(vis[nx][ny]==0&&a[nx][ny]==0)
{
vis[nx][ny]=1;
path[step].x3=nx;
path[step].y3=ny;
dfs(nx,ny,step+1);
vis[nx][ny]=0;
}
}
return ;
}
int main()
{
scanf("%d%d",&m,&n);
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++)
{
scanf("%d",&a[i][j]);
}
vis[1][1]=1;
path[0]={1,1};
dfs(1,1,1);
for(int i=Min-1;i>=0;i--)
{
printf("(%d,%d) ",shortest_path[i].x3,shortest_path[i].y3);
}
return 0;
}
这个深搜代码,比较容易写出来,就是时间复杂性高。提交的时候只能过一部分数据,后面一部分时间就超限了。
接下来是广搜代码
#include <iostream>
#include<stdio.h>
#include<queue>
using namespace std;
typedef pair<int,int> PI;
int maze[1005][1005];
int vis[1005][1005];
PI pre[1005][1005];
int moves[8][2]= {{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1}};
int m,n;
void bfs()
{
vis[1][1]=1;
pre[1][1]={-1,-1};
queue<PI>q;
q.push({1,1});
while(q.size())
{
PI k;
k=q.front();
q.pop();
for(int i=0;i<8;i++)
{
int x=k.first+moves[i][0];
int y=k.second+moves[i][1];
if(x>=1&&x<=m&&y>=1&&y<=n&&maze[x][y]==0&&vis[x][y]==0)
{
vis[x][y]=1;
q.push({x,y});
pre[x][y]={k.first,k.second};
}
}
}
int x=m,y=n;
while(x!=-1&&y!=-1)
{
printf("(%d,%d)\n",x,y);
PI t=pre[x][y];
x=t.first;
y=t.second;
}
}
int main()
{
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
scanf("%d",&maze[i][j]);
bfs();
return 0;
}
这个广搜成功通过。
总结一下深搜和广搜,深搜我看别人比较好的理解方式就是深搜就是“不撞南墙不回头”,意思就是我向前试探一步,然后会一直往前向符合条件的地方试探,也就是比如这题一点位置有八个方向,我先从一个方向开始走,下一次位置又从那个方向开始走,一直走看符不符合退出条件,当走到底时,走不通,撞到南墙时,返回上一个位置,从下一个方向开始走,又走到底,然后走不通时,又返回你走到底的上一个位置。这样可想而知,时间复杂度巨大。因为目前我还是小白,叙述可能有点不清,想更容易理解一下可以搜搜其他的博客,应该讲述的比我好。然后广搜你可以这样理解就是一个石头丢进水中,然后会产生一个波浪,你就可以理解那个波浪的最外层最早碰到终止条件时停止。这样我们搜索最短路径的话就第一次符合终止条件的那一次搜索就是最短路径。讲述可能有点不清楚,由于本人也是刚开始学,也正在学习中,想要讲解更清楚的可以搜搜其他广搜深搜的博客,应该会比我讲的清晰许多。