ARC-061D - Snuke's Coloring - 思维

题解链接

https://www.lucien.ink/archives/231/


题目链接

https://arc061.contest.atcoder.jp/tasks/arc061_b


题目

Problem Statement

We have a grid with H rows and W columns. At first, all cells were painted white.

Snuke painted N of these cells. The i -th ( 1 i N ) cell he painted is the cell at the a i -th row and b i -th column.

Compute the following:

For each integer j ( 0 j 9 ) , how many subrectangles of size 3 × 3 of the grid contains exactly j black cells, after Snuke painted N cells?

Constraints

3 H 10 9
3 W 10 9
0 N m i n ( 10 5 , H × W )
1 a i H ( 1 i N )
1 b i W ( 1 i N )
( a i , b i ) ( a j , b j ) ( i j )

Input

The input is given from Standard Input in the following format:

H W N
a 1 b 1
:
a N b N

Output

Print 10 lines. The ( j + 1 ) -th ( 0 j 9 ) line should contain the number of the subrectangles of size 3 × 3 of the grid that contains exactly j black cells.


题意

  有一个HW列的矩阵,其中有N个方格会被涂黑,第 i 个被涂黑的方格的坐标是 a i b i ,问对于每一个 3 × 3 的小矩阵,有多少个小矩阵中有i格被涂黑了,输出 10 行,为i0~9的答案。


思路

  对于每个 3 × 3 的小矩形,我们可以只关心它的中心点(第二行第二列的点)被其它点八连通地覆盖了多少次就可以正确地统计答案,于是对于每个被涂黑的方块,他会影响到周围的9 3 × 3 的小矩形(八连通加上这个点本身),然后统计每个点即可, 0 的情况用总的小矩形数减一下 1 9 的情况即可。


实现

#include <bits/stdc++.h>
const int maxn = int(1e5) + 7;
int x, y, h, w, n;
long long ans[17], base = int(1e9) + 7, zero, node[maxn << 4], tot_node;
int main(void) {
    scanf("%d%d%d", &h, &w, &n);
    zero = 1ll * (h - 2) * (w - 2);
    while (n--) {
        scanf("%d%d", &x, &y);
        for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++)
                if (1 <= x - i && x - i <= h - 2 && 1 <= y - j && y - j <= w - 2)
                    node[tot_node++] = base * (x - i) + (y - j);
    }
    std::sort(node, node + tot_node);
    for (int i = 0, cnt = 1; i < tot_node; i++) {
        if (node[i] == node[i + 1]) cnt++;
        else ans[cnt]++, cnt = 1, zero--;
    }
    printf("%lld\n", zero);
    for (int i = 1; i < 10; i++) printf("%lld\n", ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xs18952904/article/details/80387130