Radar Installation

R a d a r   I n s t a l l a t i o n Radar\ Installation Radar Installation

题目链接:POJ 1328

题目大意

在平面直角坐标系上有 n n n个小岛,现在让你在 x x x轴上布置雷达,每个雷达可以侦测以它为原心,半径为 m m m的半环内的所有小岛(半环位于平面直角坐标系的一二象限),现在问侦测完这 n n n个小岛最少要多少个雷达?
(如果无论如何都侦测不完这 n n n个小岛,则答案为 − 1 -1 1

样例输入

3 2
1 2
-3 1
2 1

1 2
0 2

0 0

样例输出

Case 1: 2
Case 2: 1

思路

这道题用贪心来做。
我们可以通过小岛的坐标计算出 x x x轴上一端能检测它的区间。
那么,我们可以将问题转化为:给 N N N个区间,在 x x x轴上放置最小的点,使得每个区间包含至少一个点。

我们可以把所有区间按最右端点从小到大排序,然后枚举每个区间,如果其左端点大于前一个区间的右端点,就多加一个点(雷达),放在这个区间的最右端点。
最后,我们统计出点(雷达)的数量,就是最终的答案了。
(记得,如果小岛在第三第四象限或者 y y y坐标大于 m m m,则无法检测到,答案要变成 − 1 -1 1

代码

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct building
{
	double min,max;
}a[1001];
int n,d,c,ans;
double x,y,right;
bool no;
bool cmp(building x,building y)
{
	return x.max<y.max;
}
int main()
{
	scanf("%d%d",&n,&d);//读入
	while (n&&d)
	{
		if (n==0&&d==0) break;//判断是否结束
		no=0;ans=1;//初始化
		for (int i=1;i<=n;i++)
		{
			scanf("%lf%lf",&x,&y);//读入
			if ((y>d||y<0)&&!no) no=1;//不能侦测到这个小岛
			else if (!no)
			{
				double l=sqrt((double)(d*d)-y*y);
				a[i].min=x-l;//求出最左端点
				a[i].max=x+l;//求出最右端点
			}
		}
		if (no) 
		{
			printf("Case %d: -1\n",++c);//不能侦测到所有的小岛
			scanf("%d%d",&n,&d);//读入
			continue;
		}
		sort(a+1,a+n+1,cmp);//按最右端点从小到大排序
		right=a[1].max;//记录最右端点
		for (int i=1;i<=n;i++)
		if (a[i].min>right)//下一个点的最左端点在最右端点右边(之前的端点不可以可以侦测到这个小岛)
		{
			right=a[i].max;//更新最右端点
			ans++;//需要的雷达数加一
		}
		printf("Case %d: %d\n",++c,ans);//输出雷达数
		scanf("%d%d",&n,&d);//读入
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值