【csp201912-2】回收站选址
题目背景
开学了,可是校园里堆积了不少垃圾杂物。
热心的同学们纷纷自发前来清理,为学校注入正能量~
题目描述
通过无人机航拍我们已经知晓了n处尚待清理的垃圾位置,其中第i(1≤i≤n)处的坐标为(x,y),保证所有的坐标均为整数。
我们希望在垃圾集中的地方建立些回收站。具体来说,对于一个位置(x,y)是否适合建立回收站,我们主要考虑以下几点:
- (x,y)必须是整数坐标,且该处存在垃圾;
- 上下左右四个邻居位置,即(x,y+1)、(x,y-1)、(x+1,y)和(x-1,y)处,必须全部存在垃圾;
- 进一步地,我们会对满足上述两个条件的选址进行评分,分数为不大于4的自然数,表示在(x±1,y±1)四个对角位置中有几处存在垃圾。
现在,请你统计一下每种得分的选址个数。
输入格式
从标准输入读入数据。
输入总共有 n+1行。
第1行包含一个正整数,表示已查明的垃圾点个数。
第1+i行(1≤i≤n)包含由一个空格分隔的两个整数xi和yi,表示第i处垃圾的坐标。
保证输入的n个坐标互不相同。
输出格式
输出到标准输出。
输出共五行,每行一个整数,依次表示得分为0、1、2、3和4的回收站选址个数。
样例1输入
7
1 2
2 1
0 0
1 1
1 0
2 0
0 1
样例1输出
0
0
1
0
0
样例1解释
样例2输入
2
0 0
-100000 10
样例2输出
0
0
0
0
0
样例2解释
不存在可选地址。
样例3输入
11
9 10
10 10
11 10
12 10
13 10
11 9
11 8
12 9
10 9
10 11
12 11
样例3输出
0
2
1
0
0
样例3解释
1分选址:(10,10)和(12,10);
2 分选址:(11,9)。
数据范围
提示
本题中所涉及的坐标皆为整数,且保证输入的坐标两两不同
题解
用map标记有垃圾的坐标,遍历每一个有垃圾的点,检测8个方向的垃圾
对于上下左右4个方向,可以用二进制来标记每个方向是否有垃圾,有则二进制位为1,没有则为0,即,用1,2,4,8表示上下左右四个方向,变量s表示四个方向的总状态,初始为0,上面有垃圾则s+1,下面有垃圾则s+2,检测完四个方向若s的值为15则表示四个方向都有垃圾,可以作为回收站,否则不能作为回收站
对于四个角的方向,在检测时计算得分,检测完后将相应得分的地址数+1
1 #include <cstdio> 2 #include <map> 3 #define pa pair<int,int> 4 using namespace std; 5 const int dx[8]={-1,1,0,0,-1,-1,1,1}; 6 const int dy[8]={0,0,-1,1,-1,1,-1,1}; 7 int n,num[10]; 8 map<pa,bool> mp; 9 struct node{ 10 int x,y; 11 }a[1005]; 12 int main() 13 { 14 int i,j,x,y,xx,yy; 15 scanf("%d",&n); 16 for (i=1;i<=n;i++) 17 scanf("%d%d",&a[i].x,&a[i].y), 18 mp[make_pair(a[i].x,a[i].y)]=1; 19 int s,cnt; 20 for (int k=1;k<=n;k++) 21 { 22 x=a[k].x; 23 y=a[k].y; 24 for (s=i=0;i<4;i++) 25 { 26 xx=x+dx[i]; 27 yy=y+dy[i]; 28 if (mp[make_pair(xx,yy)]) 29 s|=(1<<i); 30 } 31 if (s<15) continue; 32 for (cnt=0,i=4;i<8;i++) 33 { 34 xx=x+dx[i]; 35 yy=y+dy[i]; 36 if (mp[make_pair(xx,yy)]) 37 cnt++; 38 } 39 num[cnt]++; 40 } 41 for (i=0;i<5;i++) 42 printf("%d\n",num[i]); 43 return 0; 44 }