这道题是一道非常典型的CCF-CSP认证前两题的题目,主要考察对二维坐标的标记和对标记的查询。
把输入的点全部利用数组存储起来,然后对所有的点进行位置标记。接着,我们去按顺序访问所有有垃圾的点(x,y),对于每个点,我们都有以下操作:
对于坐标点的存储,可以定义 P o i n t Point Point 结构体,也可以直接用C++ STL提供的 p a i r < i n t , i n t > pair
对于点的标记,可以考虑用C++ STL提供 s e t set set 或者 m a p map map,也可直接用数组顺序存储标记,但是每次查找都需要用 O ( n ) O(n) O(n) 的时间复杂度去遍历。
坑点:
#include
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e3 + 10;
struct Point {
int x, y;
} p[maxn];
set<pair<int, int> > vis;
int n, score[10];
/**
* 判断点(x, y)是否适合作为回收站
* 如果适合,就返回1;否则返回0
*/
int isSuit(int x, int y) {
if (!vis.count(pair<int , int>(x + 1, y))) return 0;
if (!vis.count(pair<int , int>(x - 1, y))) return 0;
if (!vis.count(pair<int , int>(x, y + 1))) return 0;
if (!vis.count(pair<int , int>(x, y - 1))) return 0;
return 1;
}
/**
* 计算点(x, y)作为回收站可以得到的评分
* 返回评分
*/
int getScore(int x, int y) {
int res = 0;
if (vis.count(pair<int , int>(x + 1, y + 1))) res++;
if (vis.count(pair<int , int>(x + 1, y - 1))) res++;
if (vis.count(pair<int , int>(x - 1, y + 1))) res++;
if (vis.count(pair<int , int>(x - 1, y - 1))) res++;
return res;
}
int main()
{
//freopen("2.txt", "r", stdin);
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d %d", &p[i].x, &p[i].y);
vis.insert(pair<int, int>(p[i].x, p[i].y));
}
for (int i = 1; i <= n; i++) {
if (isSuit(p[i].x, p[i].y)) {
score[getScore(p[i].x, p[i].y)]++;
}
}
for (int i = 0; i <= 4; i++)
printf("%d\n", score[i]);
return 0;
}