AtCoder Beginner Contest 045--D - Snuke‘s Coloring(思维)

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 ai​-th row and bi​-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≤min(10^5,H×W)
  • 1≤ai​≤H (1≤i≤N)
  • 1≤bi​≤W (1≤i≤N)
  • (ai​,bi​)≠(aj​,bj​) (i≠j)

Input

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

H W N
a1​ b1
:
aN​ bN​

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.

题意:你有一个H*W的网格,初始全都是白色,然后你会把其中N个方格染色为黑色,问最后整个方格图中有多少个3*3矩阵里恰好包含 j 个黑色方格(0<=j<=9),输出10行。

解析:因为数据范围很大,不能开数组记录每个方格的颜色,因此暴力不行,其实我们发现对于一个方格被染成了黑色,对于哪些3*3矩阵有影响,我们可以取3*3方格的左上角作为统计点,对于(x,y)被染成黑色,那么它其实对i->[x-2,x],j->[y-2,y]这些3*3矩阵都是1,因此我们可以开个map记录每个收到影响的位置,最后统计即可。

#include 
using namespace std;
typedef long long ll;
typedef pair PII;
void solve()
{
    map cnt;//对于(x,y)这个3*3中有多少个黑方格
    int H,W,N;
    scanf("%d%d%d",&H,&W,&N);
    while(N--)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        for(int i=x-2;i<=x;i++)
            for(int j=y-2;j<=y;j++)
            {
                if(i>=1&&j>=1&&i<=H-2&&j<=W-2) cnt[{i,j}]++;//注意判断边界
            }
    }
    printf("%lld\n",(ll)(H-2)*(W-2)-cnt.size());
    //不包含黑色的需要特殊处理,纯白应该是所有的3*3个数减去包含黑色的3*3
    //同时注意纯白方格个数会有爆int的情况,需要long long
    for(int i=1;i<=9;i++)
    {
        int ans=0;
        for(auto it:cnt) ans+=it.second==i;
        printf("%d\n",ans);
    }
}
int main()
{
    int t=1;
    //scanf("%d",&t);
    while(t--) solve();
    return 0;
}

你可能感兴趣的:(算法,数据结构,c语言,c++)