首页 > 试题广场 >

剪纸游戏

[编程题]剪纸游戏
  • 热度指数:1924 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}小蓝拿着一张 n \times m 的方格纸从中剪下若干不相连的图案;剪裁时只会沿着方格网线裁切,因此不会破坏任何一个完整的小方格。

\hspace{15pt}小灰灰只拿到了剩余的残缺纸张。若用 `'.'` 表示被剪去的小方格,`'*'` 表示仍保留的小方格,则他得到一张由 `'.'` 与 `'*'` 组成的矩阵。由于各个剪下的图案之间互不连通,小灰灰可以根据 `'.'` 的连通块反推出每一个被剪下来的图案。

\hspace{15pt}现在小灰灰想知道:在所有被剪下来的图案中,有多少个是长方形(正方形视为特殊的长方形)。

输入描述:
\hspace{15pt}第一行输入两个整数 n,m\left(1\leqq n,m\leqq 1000\right)——纸张的行数与列数。
\hspace{15pt}接下来 n 行,每行输入一个长度为 m 的由 `'.'` 与 `'*'` 组成的字符串,描述残缺纸张的形状:
\hspace{23pt}\bullet\,`'.'` 代表该方格已被剪去;
\hspace{23pt}\bullet\,`'*'` 代表该方格仍保留。


输出描述:
\hspace{15pt}输出一个整数,表示被剪下来的图案中长方形的数量。
示例1

输入

4 10
*.*.*...**
...***.*..
.**..*.*..
*..*****..

输出

4

说明


可以看出,图中恰有一个正方形,三个长方形,共计四个长方形。
这题用BFS是因为Python用DFS会超出最大深度除非用栈模拟递归
from collections import deque

n, m = map(int, input().split())

g = []
for _ in range(n):
    g.append(input())

visited = [[False] * m for _ in range(n)]
dirs = [(0,-1),(0,1),(-1,0),(1,0)]

def bfs(start_r, start_c):
    queue = deque([(start_r, start_c)])
    bound = [start_r, start_r, start_c, start_c]
    count = 0
    
    while queue:
        r, c = queue.popleft()  # BFS: take from front
        
        if r < 0&nbs***bsp;r >= n&nbs***bsp;c < 0&nbs***bsp;c >= m:
            continue
        
        if visited[r][c]&nbs***bsp;g[r][c] == '*':
            continue
        
        visited[r][c] = True
        count += 1
        
        bound[0] = min(bound[0], r)
        bound[1] = max(bound[1], r)
        bound[2] = min(bound[2], c)
        bound[3] = max(bound[3], c)
        
        for y, x in dirs:
            queue.append((r+y, c+x))
    
    return count, bound

ans = 0
for i in range(n):
    for j in range(m):
        if not visited[i][j] and g[i][j] == '.':
            cnt, bound = bfs(i, j)
            area = (bound[1] - bound[0] + 1) * (bound[3] - bound[2] + 1)
            if cnt == area:
                ans += 1

print(ans)


发表于 2026-02-09 22:06:24 回复(0)