标签:BFS,DFS
时间限制: 1 Sec 内存限制: 128 MB
题目描述
当你站在一个迷宫里的时候,往往会被错综复杂的道路弄得失去方向感,如果你能得到迷宫地图,事情就会变得非常简单。
假设你已经得到了一个n×m的迷宫的图纸,请你找出从起点到出口的最短路。
输入
第一行是两个整数n和m,表示迷宫的行数和列数。
接下来n行,每行一个长为m的字符串,表示整个迷宫的布局。字符.表示空地,#表示墙,S表示起点,T表示出口。
输出
输出从起点到出口最少需要走的步数。
样例输入
3 5
T..##
#.#.S
#...#
样例输出
7
提示
对于100%的数据,保证1≤n,m≤100,保证从起点出发一定能到达出口。
解题思路一、DFS,把所有的方案走完,找到最小值
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <vector>
#include <queue>
#include <ctime>
#define ll long long
#define inf 0x3f3f3f3f
//#define local
using namespace std;
const int N = 105;
int n,m,bx,by,ex,ey,ans=inf;
char a[N][N];
int dir[4][2]= {1,0,-1,0,0,1,0,-1};
void dfs(int x,int y,int num)
{
if(x==ex&&y==ey)
{
ans=min(num,ans);
return ;
}
for(int i=0; i<4; i++)
{
x+=dir[i][0];
y+=dir[i][1];
if((a[x][y]=='.'||a[x][y]=='T')&&x>=1&&y>=1&&x<=n&&y<=m)
{
a[x][y]='#';
dfs(x,y,num+1);
a[x][y]='.';
}
x-=dir[i][0];
y-=dir[i][1];
}
}
int main()
{
#ifdef local
freopen("input.txt","r",stdin);
#endif // local
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
cin>>a[i][j];
if(a[i][j]=='S')
bx=i,by=j;
if(a[i][j]=='T')
ex=i,ey=j;
}
}
dfs(bx,by,0);
printf("%d",ans);
return 0;
}
DFS,又可理解为回溯算法,就是要在递归之前作出选择,之后撤销选择,直到找出min/max的值,就像一条路一条路的进行尝试,遍历完所有的选择之后,才能得出结果,往往时间复杂度很高,所以这道题,在意料之外又在情理之中的TLE了。
解题思路二、BFS
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <vector>
#include <queue>
#include <ctime>
#define ll long long
#define inf 0x3f3f3f3f
//#define local
using namespace std;
const int N = 105;
int n,m,bx,by,ex,ey,ans=0;
char a[N][N];
int vis[N][N];
int dir[4][2]= {1,0,-1,0,0,1,0,-1};
struct node
{
int x,y,s;
};
void bfs(int u,int v)
{
node temp,nex;
temp.x=u;
temp.y=v;
temp.s=0;
queue<node> q;
q.push(temp);
while(!q.empty())
{
temp=q.front();
q.pop();
for(int i=0; i<4; i++)
{
nex.x=temp.x+dir[i][0];
nex.y=temp.y+dir[i][1];
nex.s=temp.s+1;
if(nex.x<0||nex.x>n||nex.y<0||nex.y>m||a[nex.x][nex.y]=='#'||vis[nex.x][nex.y]==1)
continue;
vis[nex.x][nex.y]=1;
if(a[nex.x][nex.y]=='T')
{
ans=nex.s;
return;
}
q.push(nex);
}
}
}
int main()
{
#ifdef local
freopen("input.txt","r",stdin);
#endif // local
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
cin>>a[i][j];
if(a[i][j]=='S')
bx=i,by=j;
if(a[i][j]=='T')
ex=i,ey=j;
}
}
memset(vis,0,sizeof(vis));
bfs(bx,by);
printf("%d",ans);
return 0;
}
BFS,通常会借助于队列这种数据结构,这种方法找到的路径一定是最短路径。BFS借助队列做到一次一步,“齐头并进”,是可以在不完全遍历的情况下就得出最短路径的。但是相比于DFS,空间复杂度较高。
参考:
https://www.cnblogs.com/lipu123/p/12805950.html