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 <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
void solve()
{
map<PII,int> 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;
}