首页 > 试题广场 >

剪纸游戏

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

说明


可以看出,图中恰有一个正方形,三个长方形,共计四个长方形。
/*
    for n // 从左往右
        for m // 从上往下
            BFS(i,j) 

    BFS(i,j)时,k[i][j]应该是长方形的左上角,记录最右的下标max_i、最下的下标max_j和'.'的数量num,判断(max_i+1-i)*(max_j+1-j) == num,但是有部分样例没通过。
    后面加上记录 min_i,min_j,然后判断(max_i+1 -min_i)*(max_j+1 -min_j) == num就都通过了。
*/
package main

import (
	"fmt"
)

type Node struct{
    i,j int
}

func main() {
    var n, m int
    fmt.Scanf("%d %d", &n, &m)
    var k = make([][]byte, n)
    var v = make([][]bool, n)
    var s string
    for i:=0;i<n;i++{
        k[i] = make([]byte, m)
        v[i] = make([]bool, m)
        fmt.Scanf("%s", &s)
        k[i] = []byte(s)
    }

    var result, num, max_i, max_j, ni, nj, min_i, min_j int
    var queue []Node
    var cur Node
    dist := [][]int{{1,0}, {-1,0}, {0,1}, {0,-1}}

    var BFS func(i, j int)
    BFS = func(i,j int){
        queue = []Node{{i,j}}
        for len(queue) > 0{
            cur = queue[0]
            queue =queue[1:]

            for _, d := range dist{
                ni = cur.i + d[0]
                nj = cur.j + d[1]
                if ni<0 || ni>=n ||nj<0||nj>=m||v[ni][nj]||k[ni][nj]=='*'{
                    continue
                }
                v[ni][nj] = true
                num++
                queue = append(queue, Node{ni,nj})
                if ni > max_i {
                    max_i = ni
                }
                if ni < min_i {
                    min_i = ni
                }
                if nj > max_j {
                    max_j = nj
                }
                if nj < min_j{
                    min_j = nj
                }
            }
        }
    }
    for i:=0;i<n;i++{
        for j:=0;j<m;j++{
            if k[i][j] == '.' && !v[i][j]{
                v[i][j] = true
                max_i = i
                max_j = j
                min_i = i
                min_j = j
                num = 1
                BFS(i,j)
                if (max_i+1 -min_i)*(max_j+1 -min_j) == num {
                    result++
                }
            }
        }
    }
    fmt.Print(result)
}

发表于 2025-09-07 20:05:02 回复(0)