惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
量子位
MongoDB | Blog
MongoDB | Blog
N
Netflix TechBlog - Medium
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
B
Blog
A
About on SuperTechFans
腾讯CDC
The GitHub Blog
The GitHub Blog
云风的 BLOG
云风的 BLOG
雷峰网
雷峰网
Last Week in AI
Last Week in AI
H
Help Net Security
WordPress大学
WordPress大学
博客园 - 司徒正美
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Tailwind CSS Blog
博客园 - 【当耐特】
S
SegmentFault 最新的问题
美团技术团队
M
MIT News - Artificial intelligence
L
LangChain Blog
博客园 - 聂微东

博客园 - StudyNLP

python把中文汉字转拼音,存储到excel表格 算法结束篇 贪心-钓鱼问题 贪心-放置雷达 贪心-Stall Reservations 贪心-电影节 贪心-圣诞老人的礼物 广度优先搜索-八数码问题 广度优先搜索-鸣人和佐助 广度优先搜索-迷宫问题 广度优先搜索-抓住那头牛 深度优先搜索-生日蛋糕 深度优先搜索-Roads 深度优先搜索-踩方格 动态规划-分蛋糕V2 动态规划-分蛋糕V1 动态规划-滑雪 动态规划-0-1背包问题 动态规划-神奇的口袋V2
深度优先搜索-城堡问题
StudyNLP · 2020-07-02 · via 博客园 - StudyNLP

城堡问题:
右图是一个城堡的地形图。请你编写一个程序,计算城堡一共有多少房间,
最大的房间有多大。城堡被分割成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个格子

 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()