深度优先搜索入门:POJ1164城堡问题(递归、用栈模拟递归)

将问题的各状态之间的转移关系描述
为一个图,则深度优先搜索遍历整个图的
框架为:
Dfs(v) {
if( v 访问过)
return;
将v标记为访问过;
对和v相邻的每个点u: Dfs(u);
}
int main() {
while(在图中能找到未访问过的点 k)
Dfs(k);
}

例题:

POJ1164 The Castle

Description

     1   2   3   4   5   6   7
   #############################
 1 #   |   #   |   #   |   |   #
   #####---#####---#---#####---#
 2 #   #   |   #   #   #   #   #
   #---#####---#####---#####---#
 3 #   |   |   #   #   #   #   #
   #---#########---#####---#---#
 4 #   #   |   |   |   |   #   #
   #############################
(Figure 1)

#  = Wall
|  = No wall
-  = No wall

Figure 1 shows the map of a castle.Write a program that calculates 
1. how many rooms the castle has 
2. how big the largest room is 
The castle is divided into m * n (m<=50, n<=50) square modules. Each such module can have between zero and four walls.

Input

Your program is to read from standard input. The first line contains the number of modules in the north-south direction and the number of modules in the east-west direction. In the following lines each module is described by a number (0 <= p <= 15). This number is the sum of: 1 (= wall to the west), 2 (= wall to the north), 4 (= wall to the east), 8 (= wall to the south). Inner walls are defined twice; a wall to the south in module 1,1 is also indicated as a wall to the north in module 2,1. The castle always has at least two rooms.

Output

Your program is to write to standard output: First the number of rooms, then the area of the largest room (counted in modules).

Sample Input

4
7
11 6 11 6 3 10 6
7 9 6 13 5 15 5
1 10 12 7 13 7 5
13 11 10 8 10 12 13

Sample Output

5
9

Source

IOI 1994

百练2815 城堡问题

描述

     1   2   3   4   5   6   7     ############################# 1 #   |   #   |   #   |   |   #   #####---#####---#---#####---# 2 #   #   |   #   #   #   #   #   #---#####---#####---#####---# 3 #   |   |   #   #   #   #   #   #---#########---#####---#---# 4 #   #   |   |   |   |   #   #   #############################           (图 1)

   #  = Wall      |  = No wall   -  = No wall

图1是一个城堡的地形图。请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大。城堡被分割成m?n(m≤50,n≤50)个方块,每个方块可以有0~4面墙。
输入程序从标准输入设备读入数据。第一行是两个整数,分别是南北向、东西向的方块数。在接下来的输入行里,每个方块用一个数字(0≤p≤15)描述。用一个数字表示方块周围的墙,1表示西墙,2表示北墙,4表示东墙,8表示南墙。每个方块用代表其周围墙的数字之和表示。城堡的内墙被计算两次,方块(1,1)的南墙同时也是方块(2,1)的北墙。输入的数据保证城堡至少有两个房间。输出城堡的房间数、城堡中最大房间所包括的方块数。结果显示在标准输出设备上。
样例输入

4
7
11 6 11 6 3 10 6
7 9 6 13 5 15 5
1 10 12 7 13 7 5
13 11 10 8 10 12 13 

样例输出

5
9

解题思路
? 对每一个 方块,深度优先搜索,从而给这个方
块能够到达的所有位置染色。最后统计一共用
了几种颜色,以及每种颜色的数量。
? 比如
1 1 2 2 3 3 3
1 1 1 2 3 4 3
1 1 1 5 3 5 3
1 5 5 5 5 5 3
? 从而一共有5个房间,最大的房间(1)占据9
个格子

 1 // By LYLtim
 2 // 2015.2.16
 3
 4 #include <iostream>
 5
 6 using namespace std;
 7
 8 int m, n, roomNum = 0, maxRoomAero = 0, curRoomAera;
 9 int map[50][50], color[50][50] = {0};
10
11 void dfs(int i, int j) {
12     color[i][j] = roomNum;
13     curRoomAera++;
14     if (((map[i][j] & 1) == 0) && (j > 0) && !color[i][j-1]) dfs(i, j-1);
15     if (((map[i][j] & 2) == 0) && (i > 0) && !color[i-1][j]) dfs(i-1, j);
16     if (((map[i][j] & 4) == 0) && (j+1 < n) && !color[i][j+1]) dfs(i, j+1);
17     if (((map[i][j] & 8) == 0) && (i+1 < m) && !color[i+1][j]) dfs(i+1, j);
18 }
19
20 int main()
21 {
22     cin >> m >> n;
23     for( int i = 0; i < m; i++)
24         for (int j = 0; j < n; j++)
25             cin >> map[i][j];
26     for( int i = 0; i < m; i++)
27         for (int j = 0; j < n; j++)
28             if (!color[i][j]) {
29                 roomNum++;
30                 curRoomAera = 0;
31                 dfs(i, j);
32                 if (curRoomAera > maxRoomAero)
33                     maxRoomAero = curRoomAera;
34             }
35     cout << roomNum << endl << maxRoomAero;
36 }

用栈模拟递归

 1 // By LYLtim
 2 // 2015.2.17
 3
 4 #include <iostream>
 5 #include <stack>
 6
 7 using namespace std;
 8
 9 int m, n, roomNum = 0, curRoomAera;
10 int map[50][50], color[50][50] = {0};
11
12 struct Room
13 {
14     int x, y;
15     Room(int x, int y):x(x),y(y) {}
16 };
17
18 void dfs(int startX, int startY) {
19     stack<Room> stack;
20     stack.push(Room(startX, startY));
21     int x, y;
22     while (!stack.empty()) {
23         Room topRoom = stack.top();
24         x = topRoom.x;
25         y = topRoom.y;
26         if (color[x][y])
27             stack.pop();
28         else {
29             curRoomAera++;
30             color[x][y] = roomNum;
31             if (((map[x][y] & 1) == 0) && (y > 0) && !color[x][y-1])
32                 stack.push(Room(x, y-1));
33             if (((map[x][y] & 2) == 0) && (x > 0) && !color[x-1][y])
34                 stack.push(Room(x-1, y));
35             if (((map[x][y] & 4) == 0) && (y+1 < n) && !color[x][y+1])
36                 stack.push(Room(x, y+1));
37             if (((map[x][y] & 8) == 0) && (x+1 < m) && !color[x+1][y])
38                 stack.push(Room(x+1, y));
39         }
40     }
41 }
42
43 int main()
44 {
45     int maxRoomAero = 0;
46     cin >> m >> n;
47     for( int i = 0; i < m; i++)
48         for (int j = 0; j < n; j++)
49             cin >> map[i][j];
50     for( int i = 0; i < m; i++)
51         for (int j = 0; j < n; j++)
52             if (!color[i][j]) {
53                 roomNum++;
54                 curRoomAera = 0;
55                 dfs(i, j);
56                 if (curRoomAera > maxRoomAero)
57                     maxRoomAero = curRoomAera;
58             }
59     cout << roomNum << endl << maxRoomAero <<;
60 }
时间: 2024-08-01 10:45:30

深度优先搜索入门:POJ1164城堡问题(递归、用栈模拟递归)的相关文章

深度优先搜索(dfs),城堡问题

题目链接:http://poj.org/problem?id=1164 1.深搜,每个点都访问一次,没有标记的话,就做深搜,同时标记. #include <iostream> #include <algorithm> #include <cstring> using namespace std; int r,c; int rooms[60][60],color[60][60]; int MAX=0,NUM=0; int area; void dfs(int i,int

使用栈模拟递归过程

function Stack() { this.dataStore = []; this.top = 0;//top的值等同于数组内的元素个数 this.push = push; this.pop = pop; } function push(element) { this.dataStore[this.top++] = element; } function pop() { return this.dataStore[--this.top]; } function fact(n) { var

蒟蒻之栈模拟递归

书上的例子 1 #include <iostream> /*顺序栈*/ 2 using namespace std; 3 #define size 50 4 typedef struct node 5 { 6 int data[size][2]; /*每一层参数+当前返回值*/ 7 int top; 8 }stacknode; 9 int main() 10 { 11 int n; 12 stacknode s; 13 s.top=0; 14 while(cin>>n) 15 {

汉诺塔(Tower of Hanoi)问题的求解——利用栈与递归

汉诺塔(Tower of Hanoi)问题的求解--利用栈与递归 1. 汉诺塔问题的提法 汉诺塔问题是使用递归解决问题的经典范例. 传说婆罗门庙里有一个塔台,台上有3根标号为A.B.C的用钻石做成的柱子,在A柱上放着64个金盘,每一个都比下面的略小一点.把A柱上的金盘全部移到C柱上的那一天就是世界末日. 移动的条件是:一次只能移动一个金盘,移动过程中大金盘不能放在小金盘上面.庙里的僧人一直在移个不停,移动的最少总次数是264?1次,如果每秒移动一次的话,需要500亿年. 2. 求解汉诺塔问题的算

数据结构——30行代码实现栈和模拟递归

本文始发于个人公众号:TechFlow,原创不易,求个关注 栈的定义 原本今天想给大家讲讲快速选择算法的,但是发现一连写了好几篇排序相关了,所以临时改了题目,今天聊点数据结构,来看看经典并且简单的数据结构--栈. 栈这个结构我想大家应该都耳熟能详,尤其是在很多地方将和堆并列在一起,称作"堆栈"就更广为人知了.但其实堆和栈本质上是两种不同的数据结构,我们不能简单地混为一谈.让我们先从比较简单的栈开始. 栈和队列的本质其实都是数组(严格地说是线性表).只不过我们在数组上增加了一些限制,使得

二叉树遍历,递归,栈,Morris

一篇质量非常高的关于二叉树遍历的帖子,转帖自http://noalgo.info/832.html 二叉树遍历(递归.非递归.Morris遍历) 2015年01月06日 |  分类:数据结构 |  标签:二叉树遍历 |  评论:8条评论 |  浏览:6,603次 二叉树遍历是二叉树中最基本的问题,其实现的方法非常多,有简单粗暴但容易爆栈的递归算法,还有稍微高级的使用栈模拟递归的非递归算法,另外还有不用栈而且只需要常数空间和线性时间的神奇Morris遍历算法,本文将对这些算法进行讲解和实现. 递归

castle problem——(深度优先搜索,递归实现和stack实现)

将问题的各状态之间的转移关系描述为一个图,则深度优先搜索遍历整个图的框架为:Dfs(v) {if( v 访问过)return;将v标记为访问过;对和v相邻的每个点u: Dfs(u);}int main() {while(在图中能找到未访问过的点 k)Dfs(k);} 4例题:百练2815 城堡问题? 右图是一个城堡的地形图.请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大.城堡被分割成m×n(m≤50,n≤50)个方块,每个方块可以有0~4面墙.5输入输出? 输入? 程序从标准输入设备

【算法入门】深度优先搜索(DFS)

深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念. 你可以跳过第二节先看第三节,:) 2.深度优先搜索VS广度优先搜索 2.1演示深度优先搜索的过程还是引用上篇文章的样例图,起点仍然是V0,我们修改一下题目意思,只需要让你找出一条V0到V6的道路,而无需最短

图论 深度优先搜索 广度优先搜索的非递归实现

深度优先遍历 1.深度优先遍历的递归定义 假设给定图G的初态是所有顶点均未曾访问过.在G中任选一顶点v为初始出发点(源点),则深度优先遍历可定义如下:首先访问出发点v,并将其标记为已访问过:然后依次从v出发搜索v的每个邻接点w.若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止.若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止. 图的深度优先遍历类似于树的