算法基础③--DFS解决迷宫问题入门
迷宫问题
通过深度优先搜索(DFS)方法实现。
迷宫问题一
一天蒜头君掉进了一个迷宫里面,蒜头君想逃出去,可怜的蒜头君连迷宫是否有能逃出去的路都不知道。
看在蒜头君这么可怜的份上,就请聪明的你告诉蒜头君是否有可以逃出去的路。
输入格式
第一行输入两个整数 nn 和 mm,表示这是一个 n \times mn×m 的迷宫。
接下来的输入一个 nn 行 mm 列的迷宫。其中 'S' 表示蒜头君的位置,'*'表示墙,蒜头君无法通过,'.'表示路,蒜头君可以通过'.'移动,'T'表示迷宫的出口(蒜头君每次只能移动到四个与他相邻的位置——上,下,左,右)。
输出格式
输出一个字符串,如果蒜头君可以逃出迷宫输出"yes",否则输出"no"。
数据范围
1 \le n, m \le 101≤n,m≤10。
输出时每行末尾的多余空格,不影响答案正确性
样例输入1复制
3 4
S**.
..*.
***T
样例输出1复制
no
样例输入2复制
3 4
S**.
....
***T
样例输出2复制
yes
题解
我们读入所有数据,然后获得起点S的坐标。然后深度优先遍历,在迷宫问题中进入DFS后,要先判断是否到中点,在判断是否是障碍物,然后标记该点访问过了。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=15;
int n,m;
char g[N][N];
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
bool st[N][N];
bool dfs(int x,int y){
if(g[x][y]=='T'){
return true;
}
if(g[x][y]=='*') return false;
st[x][y]=true;
for(int i=0;i<4;i++){
int a=x+dx[i],b=y+dy[i];
if(a>n||a<=0||b<=0||b>m)continue;
if(st[a][b])continue;
if(dfs(a,b)){
return true;
}
}
return false;
}
int main(){
cin>>n>>m;
int x,y;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>g[i][j];
if(g[i][j]=='S'){
x=i;
y=j;
}
}
}
if(dfs(x,y)){
cout<<"yes"<<endl;
}else{
cout<<"no"<<endl;
}
return 0;
}
迷宫问题二
蒜头君在你的帮助下终于逃出了迷宫,但是蒜头君并没有沉浸于喜悦之中,而是很快的又陷入了思考,从这个迷宫逃出的最少步数是多少呢?
输入格式
第一行输入两个整数 nn 和 mm,表示这是一个 n \times mn×m 的迷宫。
接下来的输入一个 nn 行 mm 列的迷宫。其中 'S' 表示蒜头君的位置,'*'表示墙,蒜头君无法通过,'.'表示路,蒜头君可以通过'.'移动,'T'表示迷宫的出口(蒜头君每次只能移动到四个与他相邻的位置——上,下,左,右)。
输出格式
输出整数,表示蒜头君逃出迷宫的最少步数,如果蒜头君无法逃出迷宫输出 -1−1。
数据范围
1 \le n, m \le 101≤n,m≤10。
输出时每行末尾的多余空格,不影响答案正确性
样例输入1复制
3 4
S**.
..*.
***T
样例输出1复制
-1
样例输入2复制
3 4
S**.
....
***T
样例输出2复制
5
题解
本题要求判断是否可以到达并且要计算出最短路径,其实用宽度优先搜索更为合适,因为宽度优先搜索第一次到达目的地就是最短路径,但是我们使用深度优先也可以实现,我们定义一个最短量来储存最短的路径,当每一次到达目的点就比较一下与最短路的大小,交换最短路径长度,因此我们要遍历所有的可行路径,所以就要回溯访问状态,所以在一个遍历后就要复原,将一个点置为未访问,额额额,在 这道题中,我开始忘了读入n和m所以出现了segment段错误,还检查了好久没查到。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=15;
char g[N][N];
bool st[N][N];
int Min=99999;
int m,n;
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
void dfs(int x,int y,int stmp){
if(stmp>Min) return ;
if(g[x][y]=='T'){
Min=min(Min,stmp);
return;
}
st[x][y]=true;
if(g[x][y]=='*') return ;
for(int i=0;i<4;i++){
int a=x+dx[i],b=y+dy[i];
if(a>n||a<=0||b>m||b<=0) continue;
if(st[a][b]) continue;
if(g[a][b]=='*') continue;
dfs(a,b,stmp+1);
st[a][b]=false;
}
}
int main(){
cin>>n>>m;
int a,b;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>g[i][j];
if(g[i][j]=='S'){
a=i,b=j;
}
}
}
dfs(a,b,0);
if(Min==99999){
cout<<-1<<endl;
}else{
cout<<Min<<endl;
}
return 0;
}
迷宫问题三
经过思考蒜头君终于解决了怎么计算一个迷宫的最短路问题,于是蒜头君找到一个新的迷宫图,来验证自己是否真的会计算一个迷宫的最短路。
为了检验自己计算的是否正确,蒜头君特邀你一起来计算。
输入格式
第一行输入两个整数 nn 和 mm,表示这是一个 n \times mn×m 的迷宫。
接下来的输入一个 nn 行 mm 列的迷宫。其中'@'表示蒜头君的位置,'#'表示墙,蒜头君无法通过,'.'表示路,蒜头君可以通过'.'移动,所有在迷宫最外围的'.'都表示迷宫的出口(蒜头君每次只能移动到四个与他相邻的位置——上,下,左,右)。
输出格式
输出整数,表示蒜头君逃出迷宫的最少步数,如果蒜头君无法逃出迷宫输出 -1−1。
数据范围
1 \le n,m \le 151≤n,m≤15。
输出时每行末尾的多余空格,不影响答案正确性
样例输入1复制
9 13
#############
#@..........#
#####.#.#.#.#
#...........#
#.#.#.#.#.#.#
#.#.......#.#
#.#.#.#.#.#.#
#...........#
#####.#######
样例输出1复制
11
样例输入2复制
4 6
#.####
#.#.##
#...@#
######
样例输出2复制
5
题解
该迷宫问题与第二个迷宫问题类似,我们也要求出最短路径,所以一样要使用minn记录短的路径。
但是这个题要注意到达的条件,和第二个迷宫终点判断不一样,这个题要观察迷宫的构造,判断终止条件。所以这道题尽量从1开始存储迷宫图。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=20;
int n,m;
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
char g[N][N];
bool st[N][N];
int minn=99999;
void dfs(int x,int y,int stmp){
if(stmp>minn)return ;
if(x==0||y==0||x==n+1||y==m+1){
minn=min(minn,stmp);
return ;
}
st[x][y]=true;
for(int i=0;i<4;i++){
int a=x+dx[i],b=y+dy[i];
if(g[a][b]=='#')continue;
if(st[a][b])continue;
dfs(a,b,stmp+1);
st[a][b]=false;
}
}
int main(){
cin>>n>>m;
int x,y;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>g[i][j];
if(g[i][j]=='@'){
x=i;y=j;
}
}
}
dfs(x,y,0);
if(minn==99999){
cout<<-1<<endl;
}else{
cout<<minn-1<<endl;
}
return 0;
}
好了,dfs递归就先写到这里,之后图论的时候我们在聊。
递推
算法基础③--DFS解决迷宫问题入门的更多相关文章
- BFS 、DFS 解决迷宫入门问题
问题 B: 逃离迷宫二 时间限制: 1 Sec 内存限制: 128 MB提交: 12 解决: 5[提交][状态][讨论版] 题目描述 王子深爱着公主.但是一天,公主被妖怪抓走了,并且被关到了迷宫. ...
- 算法基础-dfs
最近在学dfs(深度优先搜索),dfs与树的遍历差不多,就是先从一个点开始一直搜索,直到走不动为止.现在推荐一个简单的dfs题, 百炼的2815, ########################## ...
- 有关dfs、bfs解决迷宫问题的个人见解
可以使用BFS或者DFS方法解决的迷宫问题! 题目如下: kotori在一个n*m迷宫里,迷宫的最外层被岩浆淹没,无法涉足,迷宫内有k个出口.kotori只能上下左右四个方向移动.她想知道有多少出口是 ...
- 算法基础:BFS和DFS的直观解释
算法基础:BFS和DFS的直观解释 https://cuijiahua.com/blog/2018/01/alogrithm_10.html 一.前言 我们首次接触 BFS 和 DFS 时,应该是在数 ...
- 用深度优先搜索(DFS)解决多数图论问题
前言 本文大概是作者对图论大部分内容的分析和总结吧,\(\text{OI}\)和语文能力有限,且部分说明和推导可能有错误和不足,希望能指出. 创作本文是为了提供彼此学习交流的机会,也算是作者在忙碌的中 ...
- 《Java基础复习》—常识与入门
突然发现自己Java基础的底子不到位,复习! 所记知识会发布在CSDN与博客网站jirath.cn <Java基础复习>-常识与入门 一.Java语言的知识体系图 分为三部分 编程语言核心 ...
- 2020牛客寒假算法基础集训营1 J题可以回顾回顾
2020牛客寒假算法基础集训营1 这套题整体来说还是很简单的. A.honoka和格点三角形 这个题目不是很难,不过要考虑周全,面积是1,那么底边的长度可以是1也可以是2, 注意底边1和2会有重复的, ...
- DFS 深搜专题 入门典例 -- 凌宸1642
DFS 深搜专题 入门典例 -- 凌宸1642 深度优先搜索 是一种 枚举所有完整路径以遍历所有情况的搜索方法 ,使用 递归 可以很好的实现 深度优先搜索. 1 最大价值 题目描述 有 n 件物品 ...
- 解读Raft(一 算法基础)
最近工作中讨论到了Raft协议相关的一些问题,正好之前读过多次Raft协议的那paper,所以趁着讨论做一次总结整理. 我会将Raft协议拆成四个部分去总结: 算法基础 选举和日志复制 安全性 节点变 ...
随机推荐
- [SPDK/NVMe存储技术分析]004 - SSD设备的发现
源代码及NVMe协议版本 SPDK : spdk-17.07.1 DPDK : dpdk-17.08 NVMe Spec: 1.2.1 基本分析方法 01 - 到官网http://www.spdk.i ...
- Acwing 社交距离 分类讨论+贪心
一种新型疾病,COWVID-19,开始在全世界的奶牛之间传播. Farmer John 正在采取尽可能多的预防措施来防止他的牛群被感染. Farmer John 的牛棚是一个狭长的建筑物,有一排共 N ...
- 平衡树:为什么Redis内部实现用跳跃表
摘要:Redis使用跳跃表(skiplist)作为有序集合(zset)的底层实现之一. 本文分享自华为云社区<5分钟了解Redis的内部实现跳跃表(skiplist)>,作者:万猫学社. ...
- STM32芯片去除读写保护 | 使用ST-Link Utility去除STM32芯片读写保护
1.使用ST-LINK V2下载器连接到STM32芯片, 点击Connect: 2.存在读保护: 3.修改选项字节(Option Bytes... ): 4.将读保护修改为Disabled. 5.打钩 ...
- VT 入门番外篇——初识 VT
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...
- react核心?
虚拟DOM, Diff算法, 遍历key值 react-dom: 提供了针对DOM的方法,比如:把创建的虚拟DOM,渲染到页面上 或 配合ref来操作DOM react-router
- Java 中 sleep 方法和 wait 方法的区别?
虽然两者都是用来暂停当前运行的线程,但是 sleep() 实际上只是短暂停顿,因为它不会释放锁,而 wait() 意味着条件等待,这就是为什么该方法要释放锁,因为只有这样,其他等待的线程才能在满足条件 ...
- 创建POJO
创建一个名为student.java的POJO. 第一步,在包里面创建一个student类,右键点击包,点击新建,再点击创建一个类. 第二步,输入类名,点击完成. 第三步,输入数据类型和主键名,再写一 ...
- 学习zabbix(九)
一.Zabbix环境准备 [root@linux-node1 ~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) [roo ...
- 如何将springboot工程打包成war包并且启动
将项目打成war包,放入tomcat 的webapps目录下面,启动tomcat,即 可访问. 1.pom.xml配置修改 <packaging>jar</packaging> ...