すぬけ君の塗り絵 / Snuke's Coloring(AtCoder-2068)

Problem Description

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≤iN ) 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≤109
  • 3≤W≤109
  • 0≤Nmin(105,H×W)
  • 1≤aiH (1≤iN)
  • 1≤biW (1≤iN)
  • (ai,bi)≠(aj,bj) (ij)

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.

Example

Sample Input 1

4 5 8
1 1
1 4
1 5
2 3
3 1
3 2
3 4
4 4

Sample Output 1

0
0
0
2
4
0
0
0
0
0

There are six subrectangles of size 3×3. Two of them contain three black cells each, and the remaining four contain four black cells each.

Sample Input 2

10 10 20
1 1
1 4
1 9
2 5
3 10
4 2
4 7
5 9
6 4
6 6
6 7
7 1
7 3
7 7
8 1
8 5
8 10
9 2
10 4
10 9

Sample Output 2

4
26
22
10
2
0
0
0
0
0

Sample Input 3

1000000000 1000000000 0

Sample Output 3

999999996000000004
0
0
0
0
0
0
0
0
0

题意:给一个长为 H 宽为 W 的网状矩形,开始时所有的格子都是白色的,现在给出 n  个格子的坐标,要把他们涂黑,将格子涂黑后,依次输出有多少个 3*3 大小的子矩形包含 0~9 个黑色格子

思路:

由于 h、w 极大,暴力一定会超时,注意到要涂黑的 n 个格子最大为 1E5,那么可以从涂黑的格子考虑

注意到每个涂黑的格子在以其为中心的 3*3 矩形中贡献了 1 个黑色,那么可以枚举所有的黑色格子,统计其贡献度,即以其为中心 3*3 的矩形贡献度+1,然后再去枚举所有涉及到的格子,由于 n 最大为 1E5,那么最坏情况下只需枚举 1E5*9 个格子

可以发现,对于给定的 h、w 的矩形,其有 (h-2)*(w-2) 个 3*3 的矩形,即小矩形的中心不可能在矩形的边上,故当统计完贡献度后,枚举所有不在矩形边上的格子,将其贡献度记录到桶中,并记录所有涉及到的总数,就是 3*3 矩形中存在 1~9 个格子的个数

最后再用总的矩形个数减去 1~9 个黑格个数就是 0 个黑格个数

由于要统计出现过的格子的坐标,使用 map+pair 极为方便

Source Program

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 1000000+5;
const int dx[] = {0,0,-1,1,-1,-1,1,1};
const int dy[] = {-1,1,0,0,-1,1,-1,1};
using namespace std;
LL bucket[10];
pair<int,int> node[N];
map<pair<int,int>,int> mp;
int main(){
    LL h,w,n;
    scanf("%lld%lld%lld",&h,&w,&n);
    for(int i=1;i<=n;i++){
        int x,y;
        scanf("%d%d",&node[i].first,&node[i].second);
        mp[node[i]]=1;//涂黑的格子贡献度为1
    }

    for(int i=1;i<=n;i++){
        for(int j=0;j<8;j++){//统计涂黑的格子周围格子的贡献度
            int nx=node[i].first+dx[j];
            int ny=node[i].second+dy[j];
            if(nx>=1&&nx<=h&&ny>=1&ny<=w){//越界判断
                pair<int,int> temp(nx,ny);
                mp[temp]++;
            }
        }
    }

    LL sum=0;
    LL tot=(h-2)*(w-2);//总共的矩形数
    map<pair<int,int>,int>::iterator it;
    for(it=mp.begin();it!=mp.end();it++){//枚举所有涉及到的格子
        int x=it->first.first;
        int y=it->first.second;
        int val=it->second;
        if(x>=2&&x<=h-1&&y>=2&y<=w-1){//统计除去最外一圈的格子
            bucket[val]++;
            sum++;
        }
    }
    bucket[0]=tot-sum;//为0的数量是总共的矩形减去所有非零的矩形

    for(int i=0;i<=9;i++)
        printf("%lld\n",bucket[i]);

    return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值