洛谷 3625(B) 迷宫寻路
DFS版
思路
实现方法
- 当前位置是 \((x,y)\)
- 如果已经到达终点,直接输出
Yes
。
- 如果没到,就向上下左右四个方向分别走一次,然后又执行一次上述操作。
代码
#include<cstdio>
#include<iostream>
#include<cstdlib>
using namespace std;
char arr[105][105];
int vis[105][105];
int n,m;
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
void dfs(int x,int y){
if(x==n&&y==m){
puts("Yes");
exit(0);
}
for(int i=0;i<4;i++){//注意点2
int tx=x+dx[i],ty=y+dy[i];
if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&vis[tx][ty]==0&&arr[tx][ty]!='#'){//注意点3
vis[tx][ty]=1;
dfs(tx,ty);
//注意点1
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>arr[i][j];
}
}
dfs(1,1);
puts("No");
return 0;
}
注意事项
- 在只需要求是否可行的本题中,不用回溯,不然会
TLE
。只有在需要求方案数的那些题里,才需要回溯,不然后来的方案就会误判。
- 循环遍历 \(4\) 种行走方案,不是 \(n\) 种。
- 注意判断是否是障碍物再通行。
BFS版
思路
实现方法
- 对于当前走到的 \((x,y)\) ,
- 如果到达终点,直接输出
Yes
。
- 否则将四周的坐标都加入队列。
代码
#include<queue>
#include<cstdio>
#include<iostream>
using namespace std;
struct node{int x,y;};
char arr[105][105];
int vis[105][105];
queue<node> que;
int n,m;
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
void bfs(int x,int y){
que.push({x,y});
while(!que.empty()){
node tp=que.front();
que.pop();
if(tp.x==n&&tp.y==m){
puts("Yes");
exit(0);
}
for(int i=0;i<4;i++){
int tx=tp.x+dx[i],ty=tp.y+dy[i];
if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&arr[tx][ty]!='#'&&vis[tx][ty]==0){
vis[tx][ty]=1;
que.push({tx,ty});
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>arr[i][j];
}
}
bfs(1,1);
puts("No");
return 0;
}
/*
3 5
.##.#
.##..
...#.
*/