wyh的迷宫

涉及知识点:求迷宫能否到达终点的,而不是求路径数的,用bfs时可以不用重置状态数组(回溯)。

题目描述

给你一个n*m的迷宫,这个迷宫中有以下几个标识:

s代表起点

t代表终点

x代表障碍物

.代表空地

现在你们涵哥想知道能不能从起点走到终点不碰到障碍物(只能上下左右进行移动,并且不能移动到已经移动过的点)。

输入描述:

复制代码
输入第一行一个整数T(1<=T<=10)
接下来有T组测试数据,对于每一组测试数据,第一行输入2个数n和m(1<=n,m<=500)
接下来n行,每行m个字符代表这个迷宫,每个字符都是上面4个中的一种
数据保证只有一个起点和一个终点

输出描述:

复制代码
对于每一组测试数据,如果可以的话输出YES,不可以的话输出NO

示例1

输入

复制1 3 5 s...x x...x ...tx

复制代码
1
3 5
s...x
x...x
...tx

输出

复制YES

复制代码
YES

想法:

用dfs求,结果超时了。毕竟都500层了......

代码:

#include<bits/stdc++.h>

using namespace std;

int n,m;

int ans;

char mg[510][510];

int a,b;//终点

int dx[]={0,0,1,-1};

int dy[]={1,-1,0,0};

int st[510][510];

void dfs(int x,int y){

for(int i=0;i<4;i++){

int xx=dx[i]+x;

int yy=dy[i]+y;

if(xx<1||yy<1||xx>n||yy>m) continue;

if(mg[xx][yy]=='x') continue;

if(st[xx][yy]) continue;

if(xx==a&&yy==b) {ans++; return;}

st[xx][yy]=1;

dfs(xx,yy);

st[xx][yy]=0;

}

}

int main(){

int t;

cin>>t;

while(t--){

memset(st,0,sizeof(st));

ans=0;

cin>>n>>m;

int x,y;

for(int i=1;i<=n;i++){

for(int j=1;j<=m;j++){

cin>>mg[i][j];

if(mg[i][j]=='s') { x=i,y=j;}

if(mg[i][j]=='t') { a=i,b=j;}

}

}

dfs(x,y);

if(ans) cout<<"YES"<<endl;

else cout<<"NO"<<endl;

}

return 0 ;

}

想法:

今天看网课,讲到bfs的时间复杂度要比dfs小(其实是回溯了的dfs时间复杂度才比bfs大很多),所以就试试bfs的写法,过了。还学到了一个小技巧,队列中的坐标的存储可以不用数对pair,用一个数值表示。

代码:

#include<bits/stdc++.h>

using namespace std;

int n,m;

int ans;

char mg[510][510];

int dx[]={0,0,1,-1};

int dy[]={1,-1,0,0};

int st[510][510];

queue <int> q;

void bfs(int x,int y){

q.push(x*m+y);

while(!q.empty()){

int a=q.front()/m;

int b=q.front()%m;

q.pop();

for(int i=0;i<4;i++){

int xx=a+dx[i];

int yy=b+dy[i];

if(mg[xx][yy]=='x') continue;

if(mg[xx][yy]=='t') { ans=1;break;}//到终点

if(st[xx][yy]) continue;

if(xx>=n||xx<0||yy<0||yy>=m) continue;

st[xx][yy]=1;

q.push(xx*m+yy);

}

if(ans==1) return ;

}

}

int main(){

int t;

cin>>t;

while(t--){

memset(st,0,sizeof(st));

ans=0;

cin>>n>>m;

int x,y;

for(int i=0;i<n;i++){

for(int j=0;j<m;j++){

cin>>mg[i][j];

if(mg[i][j]=='s') { x=i,y=j;}

}

}

st[x][y]=1;

bfs(x,y);

if(ans) cout<<"YES"<<endl;

else cout<<"NO"<<endl;

}

return 0 ;

}

事情到这并没有结束,我写完就去翻了一下别人的题解,发现其实也可以用dfs写出来,我们不需要具体路径,只需要知道起点终点是否连通(我本来想用连通块写的,但感觉还是会超时,就否决了),因此,本题不用回溯也不可以回溯,回溯会超时。这么做时间复杂度和上一个bfs的时一样的,就是全部格子都搜了一遍,时间复杂度为O(n*m)。

代码:

#include<bits/stdc++.h>

using namespace std;

int n,m;

int ans;

char mg[510][510];

int a,b;//终点

int dx[]={0,0,1,-1};

int dy[]={1,-1,0,0};

int st[510][510];

void dfs(int x,int y){

for(int i=0;i<4;i++){

int xx=dx[i]+x;

int yy=dy[i]+y;

if(xx<1||yy<1||xx>n||yy>m) continue;

if(mg[xx][yy]=='x') continue;

if(st[xx][yy]) continue;

if(xx==a&&yy==b) {ans++; return;}

st[xx][yy]=1;

dfs(xx,yy);

//st[xx][yy]=0;

}

}

int main(){

int t;

cin>>t;

while(t--){

memset(st,0,sizeof(st));

ans=0;

cin>>n>>m;

int x,y;

for(int i=1;i<=n;i++){

for(int j=1;j<=m;j++){

cin>>mg[i][j];

if(mg[i][j]=='s') { x=i,y=j;}

if(mg[i][j]=='t') { a=i,b=j;}

}

}

dfs(x,y);

if(ans) cout<<"YES"<<endl;

else cout<<"NO"<<endl;

}

return 0 ;

}

嗐,其实还是感觉怪怪的,再想想吧。

相关推荐
DKPT14 分钟前
数据结构之快速排序、堆排序概念与实现举例
java·数据结构·算法
Hiweir ·28 分钟前
机器翻译之创建Seq2Seq的编码器、解码器
人工智能·pytorch·python·rnn·深度学习·算法·lstm
star数模41 分钟前
2024“华为杯”中国研究生数学建模竞赛(E题)深度剖析_数学建模完整过程+详细思路+代码全解析
python·算法·数学建模
Tak1Na43 分钟前
2024.9.19
算法
sjsjs111 小时前
【数据结构-扫描线】力扣57. 插入区间
数据结构·算法·leetcode
王哈哈嘻嘻噜噜1 小时前
数据结构中线性表的定义和特点
数据结构·算法
一杯茶一道题1 小时前
LeetCode 260. 只出现一次的数字 III
算法·leetcode
MogulNemenis1 小时前
力扣415周赛
java·数据结构·算法·leetcode
Rense11 小时前
常用的基于无线射频( UWB)室内定位技术的原理与算法
算法
zzhnwpu1 小时前
代码随想录算法训练营第三七天| 动态规划:完全背包理论基础 518.零钱兑换II 377. 组合总和 Ⅳ 322. 零钱兑换
算法·leetcode·动态规划