1098 城堡问题(flood fill、二进制移位)

1. 问题描述:

图1是一个城堡的地形图。请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大。城堡被分割成 m∗n个方格区域,每个方格区域可以有0~4面墙。注意:墙体厚度忽略不计。

输入格式

第一行包含两个整数 m 和 n,分别表示城堡南北方向的长度和东西方向的长度。接下来 m 行,每行包含 n 个整数,每个整数都表示平面图对应位置的方块的墙的特征。每个方块中墙的特征由数字 P 来描述,我们用1表示西墙,2表示北墙,4表示东墙,8表示南墙,P 为该方块包含墙的数字之和。例如,如果一个方块的 P 为3,则 3 = 1 + 2,该方块包含西墙和北墙。城堡的内墙被计算两次,方块(1,1)的南墙同时也是方块(2,1)的北墙。输入的数据保证城堡至少有两个房间。

输出格式

共两行,第一行输出房间总数,第二行输出最大房间的面积(方块数)。

数据范围

1 ≤ m,n ≤ 50,
0 ≤ P ≤ 15

输入样例:

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
来源:https://www.acwing.com/problem/content/description/1100/

2. 思路分析:

分析题目可以知道每一个联通块属于一个房间,房间中的格子数量就是房间的面积,我们需要求解出房间的数量和最大房间的面积,题目中的输入其实是每一个格子对应的上下左右四个方向的墙的情况,四个方向中墙的情况使用一个整数表示,对应四位二进制位,1表示有墙,0表示没墙,所以本质上是连通块的计数问题,可以使用dfs或者bfs,下面使用的是bfs,可以使用一个表示四个方向的数组pos,其中pos对应左上右下四个方向,这样在进行移位判断是否有墙的时候其实是一一对应的,如果发现下一个位置没墙那么直接走过去即可。

3. 代码如下:

import collections
from typing import List


class Solution:
    def bfs(self, x: int, y: int, m: int, n: int, g: List[List[int]], st: List[List[int]]):
        q = collections.deque([(x, y)])
        st[x][y] = 1
        area = 0
        # 左上右下方向必须与后面的移位运算是对应的
        pos = [[0, -1], [-1, 0], [0, 1], [1, 0]]
        while q:
            a, b = q.popleft()
            area += 1
            for i in range(4):
                x0, y0 = a + pos[i][0], b + pos[i][1]
                if x0 < 0 or x0 >= m or y0 < 0 or y0 >= n: continue
                # 已经访问过了直接跳过
                if st[x0][y0]: continue
                # 判断当前位置是否有墙, 有墙说明需要跳过, 与pos中的位置顺序是对应的
                if g[a][b] >> i & 1: continue
                st[x0][y0] = 1
                q.append((x0, y0))
        return area

    def process(self):
        m, n = map(int, input().split())
        # 图中的元素表示每一个格子对应的墙的情况
        g = list()
        for i in range(m):
            g.append(list(map(int, input().split())))
        # count表示房间的数量, area表示房间的最大面积
        count = area = 0
        st = [[0] * (n + 10) for i in range(m + 10)]
        for i in range(m):
            for j in range(n):
                if st[i][j] == 0:
                    area = max(area, self.bfs(i, j, m, n, g, st))
                    count += 1
        print(count)
        print(area)


if __name__ == '__main__':
    Solution().process()

猜你喜欢

转载自blog.csdn.net/qq_39445165/article/details/121593302
今日推荐