题目描述
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)
输入
The input is given from Standard Input in the following format:
H W N
a1 b1
:
aN bN
输出
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.
样例输入 Copy
4 5 8 1 1 1 4 1 5 2 3 3 1 3 2 3 4 4 4
样例输出 Copy
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.
这个题特点就是数据特别大,输入的点达到了1e6,范围达到了1e9;
所以这个题我们可以转换思路,不再把所有的点表示出来,而是只表示涂过的空间
同时点也不用二维数组存储(防止占用空间过大),转为一维数组,同时为了防止x与y混淆,我们将x*1e9+y表示此点的坐标
同时因为是一个点影响其余8个所以我们着重去研究中心点,用一个中心点表示3*3的矩阵
代码实现:
#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
typedef long long ll;
const int N = (1e5) + 5;
ll res[10];
//存储输出结果
ll e = 1e9;
//单位量,存储一(#`O′维数组时用
ll node[N *10], tot_node = 0;
//因为每有一个点都会影响周围8个以及自身,同时防止问题,我们故意开大点
//tot_node表示一共多少个点受影响
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
ll h, w, n;
cin >> h >> w >> n;
ll node_zero = (h - 2) * (w - 2);
//我们先默认所有点都是0,node_zero就表示所有中心点的数量(即所有矩阵的数量)
int x, y;
while (n--)
{
cin >> x >> y;
for (int i = -1; i < 2; i++)
for (int j = -1; j < 2; j++)
//因为这个点会影响3*3矩阵,所以相邻的中心点也会受影响
{
if (2 <= x + i && x + i <= h - 1 && y + j >= 2 && y + j <= w - 1)
//这个中心点在中心点的范围内,是有效的
{
node[tot_node] = e * (x - i) + (y - j);
//二维点一位化
tot_node++;
}
}
}
sort(node, node + tot_node);
//对所有的点排列,这样相同的点就会靠近在一起(也可以用set)
for (int i = 0, num = 1; i < tot_node; i++)
{
if (node[i] == node[i + 1])num++;
//表示这个点重复,所以这个中心点的数量+1;
else
{
res[num]++;
num = 1;
node_zero--;
}
}
cout << node_zero << '\n';
for (int i = 1; i < 10; i++)
{
cout << res[i] << '\n';
}
}