题目描述:
小信有一个n行m列的棋盘,小友在上面放了k颗棋子。小信想知道对于 i 从 0 到 9 ,有多少个3×3的子棋盘包含恰好 i 颗棋子。
输入格式:
第一行包含三个整数 n,m 和 k,表示棋盘大小和棋子数量。
接下来k行包含 k 对整数 xi 和 yi,表示棋子在棋盘上的坐标 。
输出格式:
对于 i 从 0 到 9 ,每行输出一个整数表示答案。
样例1输入:
4 5 8 4 4 1 1 1 4 1 5 3 4 3 2 3 1 2 3
样例1输出:
0 0 0 2 4 0 0 0 0 0
约定与提示:
对于100%的数据,3≤n,m≤10^9,0≤k≤min(105,n×m),
1≤xi≤n,1≤yi≤m (1≤i≤k),(xi, yi)≠(xj, yj) (i ≠ j)
一看本题,首先的第一反应是老老实实地开一个地图数组,但是由于10^9就算是bool也开不下。
所以换个思路,从较小的K入手,围绕着K展开。
从黑块入手,在四周的九宫格内加1.
下附AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f;
map<pair<ll, ll>, ll> mp;
ll f[15],n,m,k;
ll tx[9] = {0, 0, 0, 1, 1, 1, -1, -1, -1};
ll ty[9] = {0, 1, -1, 0, 1, -1, 0, 1, -1};
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> k;
for (ll i = 1; i <= k;i++){
ll x, y;
cin >> x >> y;
for (ll k = 0; k < 9;k++){
if(x+tx[k]>1&&x+tx[k]<n&&y+ty[k]>1&&y+ty[k]<m)
mp[{x + tx[k], y + ty[k]}]++;
}
}
for(auto &i:mp){
f[i.second]++;
}
cout << (n - 2) * (m - 2) - mp.size() << "\n";
for (ll i = 1; i <= 9;i++){
cout << f[i] << "\n";
}
}