【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

#include <cstdio>
#include <map>
#define pa pair<int,int>
using namespace std;
const int dx[8]={-1,1,0,0,-1,-1,1,1};
const int dy[8]={0,0,-1,1,-1,1,-1,1};
int n,num[10];
map<pa,bool> mp;
struct node{
	int x,y;
}a[1005];
int main()
{
	int i,j,x,y,xx,yy;
	scanf("%d",&n);
	for (i=1;i<=n;i++)
	  scanf("%d%d",&a[i].x,&a[i].y),
	  mp[make_pair(a[i].x,a[i].y)]=1;
	int s,cnt;
	for (int k=1;k<=n;k++)
	{
		x=a[k].x;
		y=a[k].y;
		for (s=i=0;i<4;i++)
		{
			xx=x+dx[i];
			yy=y+dy[i];
			if (mp[make_pair(xx,yy)])
			  s|=(1<<i);
		}
		if (s<15) continue;
		for (cnt=0,i=4;i<8;i++)
		{
			xx=x+dx[i];
			yy=y+dy[i];
			if (mp[make_pair(xx,yy)])
			  cnt++;
		}
		num[cnt]++;
	}
	for (i=0;i<5;i++)
	  printf("%d\n",num[i]); 
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值