百炼3752:走迷宫--栈实现dfs
3752:走迷宫
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
- 一个迷宫由R行C列格子组成,有的格子里有障碍物,不能走;有的格子是空地,可以走。
给定一个迷宫,求从左上角走到右下角最少需要走多少步(数据保证一定能走到)。只能在水平方向或垂直方向走,不能斜着走。 - 输入
- 第一行是两个整数,R和C,代表迷宫的长和宽。( 1<= R,C <= 40)
接下来是R行,每行C个字符,代表整个迷宫。
空地格子用'.'表示,有障碍物的格子用'#'表示。
迷宫左上角和右下角都是'.'。 - 输出
- 输出从左上角走到右下角至少要经过多少步(即至少要经过多少个空地格子)。计算步数要包括起点和终点。
- 样例输入
-
5 5
..###
#....
#.#.#
#.#.#
#.#.. - 样例输出
-
9
【分析】 本题用递归实现起来不方便,因此用一个结构模拟走迷宫的过程:1 struct node {
2 int x,y; //节点坐标
3 int step; //到达该节点需要的步数
4 node(int x,int y,int step) : x(x),y(y),step(step) {};
5 };此处,node表示迷宫中的一个“节点”。
用栈实现dfs走迷宫的思想:(1) 将起始节点入栈;
(2) 将起始节点出栈,作为“当前所在的节点”;
(3) 将“当前所在的节点”所能到达的所有节点入栈(这便是下一步所有的路);
(4) 栈顶节点出栈,作为下一步的“当前所在的节点”。
(5) 重复上述过程,直到走到终点。
由于栈后进先出的特点,因此每一个出栈作为“当前所在的节点”的节点一定是上一步刚刚入栈的节点(即上一步的“当前所在的节点”所能直接到达的某个下一
步的节点),因此栈实现的是dfs(而非bfs)。
【代码】1 #include <iostream>
2 #include <stack>
3 using namespace std;
4
5 const int maxr = 45;
6 const int maxc = 45;
7 char board[maxr][maxc];
8 bool visited[maxr][maxc];
9 int R,C;
10 int mov[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
11
12 struct node {
13 int x,y; //节点坐标
14 int step; //到达该节点需要的步数
15 node(int x,int y,int step) : x(x),y(y),step(step) {};
16 };
17
18 bool check(int x,int y)
19 {
20 if( x <= R && x >= 1 && y <= C && y >= 1 && board[x][y] == '.'
21 && !visited[x][y] )
22 return true;
23 return false;
24 }
25
26 int dfs(int x,int y)
27 {
28 stack<node> s;
29 node start(x,y,1);
30 s.push(start);
31
32 //栈仅是工具,真正的动态dfs过程从while循环中才开始,
33 //从栈中取出一个节点,相当于确定了目前所在的节点
34 while( !s.empty() ) {
35 node cur = s.top();
36 s.pop();
37
38 //以下for循环把当前能到达的所有点入栈
39 for( int i=0; i<4; i++ ) {
40 int ix = cur.x + mov[i][0];
41 int iy = cur.y + mov[i][1];
42 if( !check(ix,iy) ) continue;
43
44 node nxt(ix,iy,cur.step+1); //创造下一个合法节点
45
46 //判断:如果已经到目标点直接返回答案
47 if( nxt.x == R && nxt.y == C ) {
48 return nxt.step; //(1)
49 }
50 visited[nxt.x][nxt.y] = true; //不加这句,会导致已走过的节点多次入栈,造成死循环
51 //入栈了的节点今后一定都能访问到,因此不用担心漏掉"可走的路"
52 s.push(nxt);
53 }
54 }
55
56 return -1; //若栈中所有节点都已经取出,程序走到了此处(而不是在(1)处返回),
57 //说明终点无法走到
58 }
59
60 int main()
61 {
62 cin >> R >> C;
63 for( int i=1; i<=R; i++ ) {
64 for( int j=1; j<=C; j++ ) {
65 cin >> board[i][j];
66 }
67 getchar(); //除行尾回车
68 }
69 int ans = dfs(1,1);
70
71 cout << ans << endl;
72 return 0;
73 }本题使用bfs实现也可以,只需要把栈换成队列就行了。
百炼3752:走迷宫--栈实现dfs的更多相关文章
- 数据结构之 栈与队列--- 走迷宫(深度搜索dfs)
走迷宫 Time Limit: 1000MS Memory limit: 65536K 题目描述 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m),每次可以向上下左右四个方 ...
- SDUT-2449_数据结构实验之栈与队列十:走迷宫
数据结构实验之栈与队列十:走迷宫 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 一个由n * m 个格子组成的迷宫,起 ...
- sdut 2449走迷宫【最简单的dfs应用】
走迷宫 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_ 题目描述 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m) ...
- NYOJ306 走迷宫(dfs+二分搜索)
题目描写叙述 http://acm.nyist.net/JudgeOnline/problem.php?pid=306 Dr.Kong设计的机器人卡多非常爱玩.它经常偷偷跑出实验室,在某个游乐场玩之不 ...
- HDU 2102 A计划(BFS/DFS走迷宫)
A计划 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- C语言动态走迷宫
曾经用C语言做过的动态走迷宫程序,先分享代码如下: 代码如下: //头文件 #include<stdio.h> #include<windows.h>//Sleep(500)函 ...
- 洛谷P1238 走迷宫
洛谷1238 走迷宫 题目描述 有一个m*n格的迷宫(表示有m行.n列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这m*n个数据和起始点.结束点(起始点和结束点都是用两个 ...
- BZOJ 2707: [SDOI2012]走迷宫( tarjan + 高斯消元 )
数据范围太大不能直接高斯消元, tarjan缩点然后按拓扑逆序对每个强连通分量高斯消元就可以了. E(u) = 1 + Σ E(v) / degree(u) 对拍时发现网上2个程序的INF判断和我不一 ...
- BZOJ 2707: [SDOI2012]走迷宫 [高斯消元 scc缩点]
2707: [SDOI2012]走迷宫 题意:求s走到t期望步数,\(n \le 10^4\),保证\(|SCC| \le 100\) 求scc缩点,每个scc高斯消元,scc之间直接DP 注意每次清 ...
随机推荐
- Java虚拟机栈和PC寄存器
PC Register介绍 JVM中的程序计数寄存器(Program Counter Register)中,Register 的命名源于CPU的寄存器,寄存器存储指令相关的现场信息.CPU只有把数据装 ...
- ES系列(五):获取单条数据get处理过程实现
前面讲的都是些比较大的东西,即框架层面的东西.今天咱们来个轻松点的,只讲一个点:如题,get单条记录的es查询实现. 1. get语义说明 get是用于搜索单条es的数据,是根据主键id查询数据方式. ...
- golang:Channel协程间通信
channel是Go语言中的一个核心数据类型,channel是一个数据类型,主要用来解决协程的同步问题以及协程之间数据共享(数据传递)的问题.在并发核心单元通过它就可以发送或者接收数据进行通讯,这在一 ...
- [刷题] 343 Integer Break
要求 给定一个正数n,可将其分割成多个数字的和,求让这些数字乘积最大的分割方法(至少分成两个数) 示例 n=2,返回1(2=1+1) n=10,返回36(10=3+3+4) 实现 回溯遍历(n^2,超 ...
- fedora21 桌面用户自动登录lightdm.conf -20190520 方法
修改 /etc/lightdm/lightdm.conf 步骤:1解除注释#autologin-user=root 2等号 =后面是root或者普通用户的用户名 例如:root用户自动登录 autol ...
- CPU缓存是位于CPU与内存之间的临时数据交换器,它的容量比内存小的多但是交换速度却比内存要快得多。CPU缓存一般直接跟CPU芯片集成或位于主板总线互连的独立芯片上
一.什么是CPU缓存 1. CPU缓存的来历 众所周知,CPU是计算机的大脑,它负责执行程序的指令,而内存负责存数据, 包括程序自身的数据.在很多年前,CPU的频率与内存总线的频率在同一层面上.内存的 ...
- debian用户手册-20200317
https://www.debian.org/doc/manuals/debian-reference/ 文档与使用手册在每一个操作系统中都是很重要的一部份,是描述程序操作和使用的技术手册.正由于说明 ...
- python3 使用random函数批量产生注册邮箱
'''你是一个高级测试工程师,现在要做性能测试,需要你写一个函数,批量生成一些注册使用的账号. 1.产生的账号是以@163.com结尾,长度由用户输,产生多少条也由用户输入,2.用户名不能重复,用户名 ...
- 测试开发:从0到1学习如何测试API网关
本文来自我的一名学员分享 日常工作中,难免会遇到临危受命的情况,虽然没有这么夸张,但是也可能会接到一个陌生的任务,也许只是对这个概念有所耳闻.也许这个时候会感到一丝的焦虑,生怕没法完成领导交给的测试任 ...
- python 如何让俩个对象相等及如何让俩个对象具有相同的id值