首页 > 试题广场 >

剪纸游戏

[编程题]剪纸游戏
  • 热度指数: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

说明


可以看出,图中恰有一个正方形,三个长方形,共计四个长方形。
import sys
from collections import deque

for line in sys.stdin:
    data = line.split()
    n = int(data[0])
    m = int(data[1])
    break

mat = []
for line in sys.stdin:
    data = line.split()
    mat.append(data[0])

direction = [(1,0),(-1,0),(0,1),(0,-1)]
flag = [[0 for _ in range(m)] for _ in range(n)]

def check(i,j):
    if_rectangle = 1
    temp = deque()
    temp.append([i,j])
    flag[i][j] = 1
    u = i
    d = i
    l = j
    r = j
    while temp:
        now = temp.popleft()
        for dir in direction:
            x = now[0] + dir[0]
            y = now[1] + dir[1]
            if 0<=x<n and 0<=y<m and mat[x][y]=='.' and flag[x][y]==0:
                temp.append([x,y])
                flag[x][y] = 1
                # 每更新一个点就更新边界
                u = min(u,x)
                d = max(d,x)
                l = min(l,y)
                r = max(r,y)
    # 检查边界内部是否有'*'
    for i in range(u, d+1):
        for j in range(l, r+1):
            if mat[i][j] =='*':
                if_rectangle = 0
    return if_rectangle
count = 0
for i in range(n):
    for j in range(m):
        if mat[i][j] == '.' and flag[i][j] == 0:
            count += check(i,j)
print(count)

发表于 2026-03-12 19:05:45 回复(0)