zoukankan      html  css  js  c++  java
  • 深度优先搜索入门: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

    百练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 }
  • 相关阅读:
    js数据类型转换与字面量
    CSS精灵图与字体图标
    CSS元素的显示与隐藏
    .net core依赖注入学习
    WebAPI 参数问题
    .net EF code first 注意事项
    C#面向对象
    家用电信光纤内网IP改为公网IP
    页面JS引用添加随机参数避免页面缓存
    JS处理URL中的中文
  • 原文地址:https://www.cnblogs.com/LYLtim/p/4295672.html
Copyright © 2011-2022 走看看