洛谷-B3625迷宫寻路-DFS与BFS解法
洛谷B3625 迷宫寻路 BFS与DFS双解法及其对比
题目描述
机器猫被困在一个矩形迷宫里。
迷宫可以视为一个 n*m矩阵,每个位置要么是空地,要么是墙。机器猫只能从一个空地走到其上、下、左、右的空地。
机器猫初始时位于 (1, 1)的位置,问能否走到 (n, m) 位置。
输入格式
第一行,两个正整数 n,m。
接下来 n 行,输入这个迷宫。每行输入一个长为 m 的字符串,#
表示墙,.
表示空地。
输出格式
仅一行,一个字符串。如果机器猫能走到 (n, m),则输出 Yes
;否则输出 No
。
样例 #1
样例输入 #1
3 5
.##.#
.#...
...#.
样例输出 #1
Yes
1. DFS解法
DFS模板参见 DFS
#include <bits/stdc++.h>
using namespace std;
char Map[101][101];
int done[101][101]={0}; //在地图上走的问题,都必须加上done这类标记数组,避免重复走导致程序死循环
int dy[4]={0,1,0,-1}; //(dx,dy)对应了上下左右四个方向
int dx[4]={1,0,-1,0};
bool flag = false; //标记是否到达终点,若到达变为true,方便后面剪枝优化
int n,m;
int check(int x, int y)
{
if(done[x][y]==1) //已经走过该格子,不能再走上去
return 0;
if(Map[x][y]=='#') //迷宫的墙,不能走
return 0;
return 1;
}
void dfs(int x, int y)
{
if(x==n&&y==m) //判断是否到达终点
{
flag = true;
}
if(flag)
return ;
if(x<1 || x>n ||y<1 || y>m) //判断边界
return ;
for(int i=0;i<4;i++) //遍历上下左右四个方向
{
int nowx = dx[i] + x; //定义当前(接下来)要走的格子
int nowy = dy[i] + y;
if(check(nowx,nowy))
{
done[x][y]=1; //把先前的格子设为"已走过"
dfs(nowx,nowy);
//此处不用回溯done[x][y]=0,不然会超时。
//但是,如果题目问"从某点出发到某点走过路径的最大值",那就需要回溯了
}
}
}
int main()
{
// 输入部分
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
cin>>Map[i][j];
}
//题目给出从(1,1)走
dfs(1,1);
//输出部分
if(flag)
cout<<"Yes";
else
cout<<"No";
return 0;
}
2. BFS解法
BFS模板参见BFS
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
queue<PII> q;
PII temppair;
char Map[101][101];
int done[101][101]={0};
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int n,m;
bool flag=false;
int check(int x,int y)
{
if(x<1||x>n||y<1||y>m)
return 0;
if(done[x][y]==1)
return 0;
if(Map[x][y]=='#')
return 0;
return 1;
}
void bfs()
{
while(!q.empty())
{
if(q.front().first==n&&q.front().second==m) //判断当前点是否是终点(n,m)
flag = true;
if(flag)
return ;
temppair = q.front(); //从这往下是标准的BFS模板
q.pop();
for(int i=0;i<4;i++)
{
int nowx=temppair.first+dx[i];
int nowy=temppair.second+dy[i];
if(check(nowx,nowy))
{
q.push({nowx,nowy});
done[nowx][nowy]=1;
}
}
}
return ;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>Map[i][j];
q.push({1,1}); //将起点(1,1)压入队列
bfs();
if(flag)
cout<<"Yes";
else
cout<<"No";
return 0;
}
3.对比
由于这道题不需要回溯
,用DFS时如果硬套模板,会导致部分评测TLE。
在代码书写复杂度上,DFS>BFS;
在程序运行时间、占用内存上 未剪枝的DFS>剪枝的DFS≈BFS。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 VR小杰
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果