# 2132. 用邮票贴满网格图

## Link

{% embed url="<https://leetcode.cn/problems/stamping-the-grid>" %}

## Problem

给你一个 m x n 的二进制矩阵 grid ，每个格子要么为 0 （空）要么为 1 （被占据）。

给你邮票的尺寸为 stampHeight x stampWidth 。我们想将邮票贴进二进制矩阵中，且满足以下 限制 和 要求 ：

覆盖所有 空 格子。 不覆盖任何 被占据 的格子。 我们可以放入任意数目的邮票。 邮票可以相互有 重叠 部分。 邮票不允许 旋转 。 邮票必须完全在矩阵 内 。 如果在满足上述要求的前提下，可以放入邮票，请返回 true ，否则返回 false 。

示例 1：

![](https://1992890748-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0qYY1ILl1K1crNjGMFmh%2Fuploads%2FLL6buBdrP9tWHBUsVwB8%2Fimage.png?alt=media\&token=8f6d9568-a0bc-449c-81b0-39c39611ec54)

{% code overflow="wrap" %}

```
输入：grid = [[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0]], stampHeight = 4, stampWidth = 3
输出：true
解释：我们放入两个有重叠部分的邮票（图中标号为 1 和 2），它们能覆盖所有与空格子。
```

{% endcode %}

示例2：

{% code overflow="wrap" %}

```
输入：grid = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]], stampHeight = 2, stampWidth = 2 
输出：false 
解释：没办法放入邮票覆盖所有的空格子，且邮票不超出网格图以外。
```

{% endcode %}

提示：

* m == grid.length&#x20;
* n == grid\[r].length
* 1 <= m, n <= 10^5&#x20;
* 1 <= m \* n <= 2 \* 10^5&#x20;
* grid\[r]\[c] 要么是 0 ，要么是 1&#x20;
* 1 <= stampHeight, stampWidth <= 105

## Solution

{% tabs %}
{% tab title="Go" %}

```go
func possibleToStamp(grid [][]int, stampHeight int, stampWidth int) bool {
    m, n := len(grid), len(grid[0])
    s := make([][]int, m+1)
    d := make([][]int, m+1)
    cnt := make([][]int, m+1)

    for i := range s {
        s[i] = make([]int, n+1)
        d[i] = make([]int, n+1)
        cnt[i] = make([]int, n+1)
    }

    for i, row := range grid {
        for j, v := range row {
            s[i+1][j+1] = s[i+1][j] + s[i][j+1] - s[i][j] + v
        }
    }

    for i, row := range grid {
        for j, v := range row {
            if v == 0 {
                x, y := i + stampHeight, j + stampWidth
                if x <= m && y <= n && s[x][y]-s[i][y]-s[x][j] + s[i][j] == 0 {
                    d[i][j]++
                    d[i][y]--
                    d[x][j]--
                    d[x][y]++
                }
            }
        }
    }

    for i, row := range grid {
        for j, v := range row {
            cnt[i+1][j+1] = cnt[i+1][j] + cnt[i][j+1] -cnt[i][j] + d[i][j]
            if v == 0 && cnt[i+1][j+1] == 0 {
                return false
            } 
        }
    } 
    return true
}
```

{% endtab %}

{% tab title="C++" %}

```cpp
```

{% endtab %}
{% endtabs %}
