百炼3752:走迷宫--栈实现dfs
Posted NickYoung;
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了百炼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的主要内容,如果未能解决你的问题,请参考以下文章