zoukankan      html  css  js  c++  java
  • 深度优先搜索-城堡问题

    城堡问题:
    右图是一个城堡的地形图。请你编写一个程序,计算城堡一共有多少房间,
    最大的房间有多大。城堡被分割成m×n(m≤50,n≤50)个方块,每个方块可
    以有0~4面墙。

    输入
     程序从标准输入设备读入数据。
     第一行是两个整数,分别是南北向、东西向的方块数。
     在接下来的输入行里,每个方块用一个数字(0≤p≤50)描述。用一个数
    字表示方块周围的墙, 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个格子

    python算法实现:

     1 # 当前房屋的值
     2 rooms = []
     3 # 方块是否染色过的标记
     4 color = []
     5 """
     6 [[0, 0, 0, 0, 0, 0, 0, 0],
     7 [0, 1, 1, 2, 2, 3, 3, 3],
     8 [0, 1, 1, 1, 2, 3, 4, 3],
     9 [0, 1, 1, 1, 5, 3, 5, 3],
    10 [0, 1, 5, 5, 5, 5, 5, 3]]
    11 """
    12 # 最大的房间面积,当前房间面积,当前房间数量
    13 maxRoomArea, roomArea, roomNum = 0, 0, 0
    14 
    15 
    16 def Dfs(i, j):
    17     global color, roomArea, roomNum, rooms
    18     # 说明该点已经访问过
    19     if color[i][j] != 0:
    20         return
    21     roomArea = roomArea + 1
    22     # 标记该房间是哪一组的
    23     color[i][j] = roomNum
    24     # 向西走 1-0001
    25     if (rooms[i][j] & 1) == 0:
    26         Dfs(i, j-1)
    27     # 向北 2-0010
    28     if (rooms[i][j] & 2) == 0:
    29         Dfs(i-1, j)
    30     # 向东 4-0100
    31     # 比如11-1011,与4的二进制做与运算,计算结果是0,说明东墙是空的,可以走
    32     if (rooms[i][j] & 4) == 0:
    33         Dfs(i, j+1)
    34     # 向南 8-1000
    35     if (rooms[i][j] & 8) == 0:
    36         Dfs(i+1, j)
    37     return
    38 
    39 
    40 def main():
    41     global rooms, color, roomNum, roomArea, maxRoomArea
    42     tempList = []
    43     # r-行,c-列
    44     r, c = map(int, input().split())
    45     # 从把每个房间的值储存从位置1开始,方便后续计算
    46     rooms = [[0 for j in range(c)] for i in range(r+1)]
    47     color = [[0 for j in range(c+1)] for i in range(r+1)]
    48     # 初始化二维列表
    49     for i in range(1, r+1):
    50         tempList = list(map(int, input().split()))
    51         # 因为输入的数有7个,为了计算方便,凑够8列,所以在0位置补个0
    52         tempList.insert(0, 0)
    53         rooms[i] = tempList
    54     # [[0, 0, 0, 0, 0, 0, 0],
    55     #  [0, 11, 6, 11, 6, 3, 10, 6],
    56     #  [0, 7, 9, 6, 13, 5, 15, 5],
    57     #  [0, 1, 10, 12, 7, 13, 7, 5],
    58     #  [0, 13, 11, 10, 8, 10, 12, 13]]
    59     for i in range(1, r+1):
    60         for j in range(1, c+1):
    61             # 遍历所有没有访问过的点
    62             if color[i][j] == 0:
    63                 # 每次访问新的点,说明该点与访问过的点是不连通的,相互不能走通
    64                 # 不是同一个roomNum,因此最大面积置0,重新开始计算
    65                 roomArea = 0
    66                 # 因为不是同一组,房间号在原来的基础上新增1,以表示不同的房间号
    67                 roomNum = roomNum + 1
    68                 Dfs(i, j)
    69                 maxRoomArea = max(roomArea, maxRoomArea)
    70     print("一共有%d个房间,最大的房间面积%d" % (roomNum, maxRoomArea))
    71     return 0
    72 
    73 
    74 if __name__ == '__main__':
    75     main()
  • 相关阅读:
    ubuntu安装mysql并使用Navicat连接
    二叉树基础知识点
    Javascript 16进制转有符号的10进制整数
    Node.js 学习笔记(二)
    API测试如何演变为应用程序开发的常规部分
    API在线文档
    API文档自动生成的方法
    快速对比API版本
    如何使用OPENAPI进行质量检查
    【分享】什么是API网关?大公司为什么都有API网关?
  • 原文地址:https://www.cnblogs.com/an-wl/p/13226280.html
Copyright © 2011-2022 走看看