首页 > 试题广场 >

挡住洪水

[编程题]挡住洪水
  • 热度指数:2950 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}吴铭市近日洪水肆虐,洪水从地图外部渗入。市政部门在若干方格上砌起围墙,用 `*` 表示。若某片空地区域不与地图边界四联通(上下左右方向),则不会被洪水淹没,视为安全空地。

\hspace{15pt}地图用大小为 x \times y 的字符矩阵描述:`'*'` 表示围墙,`'0'` 表示空地。所有相互四联通的 `'0'` 构成一个区域。请统计所有安全空地格子的数量之和(即所有不与边界四联通的 `'0'` 的总数)。

输入描述:
\hspace{15pt}第一行输入两个整数 x,y\left(1\leqq x,y\leqq 500\right)
\hspace{15pt}接下来 x 行,每行 y 个字符,组成围墙建设图,仅含 `'*'` 与 `'0'`。


输出描述:
\hspace{15pt}输出一个整数,表示所有安全空地格子的总数。
示例1

输入

2 2
**
**

输出

0
package main

/* 
    先把边界为'0'的地方都BFS标记一次(会被淹没的'0')
    然后再次BFS_未被标记的'0',计算安全的'0'的个数
 */

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

    dist:= [][]int{{0,1}, {0,-1}, {1,0}, {-1,0}}
    
    var cur Node
    var queue []Node
    var result, ni, nj int
    var BFS func(i, j int)

    BFS = func(i, j int){ // 标记会被淹没的'0'
        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
                queue = append(queue, Node{ni,nj})
            }
        }
    }

    var BFS_ func(i, j int) // 累计安全的'0'的个数
    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
                result++
                queue = append(queue, Node{ni,nj})
            }
        }
    }

    // 标记会被淹没的区域
    for i:=0;i<n;i++{
        if k[i][0] == '0' && !v[i][0] {
            v[i][0] = true
            BFS(i,0)
        }
        if k[i][m-1] == '0' && !v[i][m-1]{
            v[i][m-1] = true
            BFS(i,m-1)
        }
    }
    for i:=0;i<m;i++{
        if k[0][i] == '0' && !v[0][i] {
            v[0][i] = true
            BFS(0,i)
        }
        if k[n-1][i] == '0' && !v[n-1][i]{
            v[n-1][i] = true
            BFS(n-1,i)
        }
    }

    for i:=0;i<n;i++{
        for j:=0;j<m;j++{
            if k[i][j] == '0' && !v[i][j]{
                v[i][j] = true
                result++
                BFS_(i,j)
            }
        }
    }
    fmt.Print(result)
}


发表于 2025-09-07 19:32:50 回复(0)