YbtOJ——贪心算法【例题2】雷达装置

B. 【例题2】雷达装置

题目链接
内存限制:64 MiB
时间限制:1000 ms
标准输入输出
题目类型:传统
评测方式:文本比较

题目描述

有 个建筑物,第 个建筑物在笛卡尔坐标系上的坐标为 ,你需要在 轴上安装一些雷达,每个雷达的侦察半径均为 ,要求每个建筑物都至少被一个雷达侦测到,求最少要安装几个雷达。

输入格式

第一行两个正整数 。

接下来 行,第 行两个整数 。

输出格式

输出一行表示答案,若没有解决方案,则答案为 。

样例

样例输入

3 2
1 2
-3 1
2 1

样例输出

2

数据范围与提示

对于 % 100 \%100 %100 的数据,有 1 ≤ N ≤ 1 0 3 1\leq N\leq10^3 1N103

思路

先画个图感性理解一下:
在这里插入图片描述
能检测到点(x,y)的雷达只能在圆圈内,而在x轴内的雷达就只在 [l,r] 区间内了。
由勾股定理得: d 2 = ( x − l ) 2 + y 2 = ( r − x ) 2 + y 2 d^2=(x-l)^2+y^2=(r-x)^2+y^2 d2=(xl)2+y2=(rx)2+y2
所以 d 2 − y 2 = x − l = r − x \sqrt{d^2-y^2}=x-l=r-x d2y2 =xl=rx
所以 l = x − d 2 − y 2 , r = x + d 2 − y 2 l=x-\sqrt{d^2-y^2},r=x+\sqrt{d^2-y^2} l=xd2y2 r=x+d2y2
所以我们就能求出每个点对应的区间,
然后问题就变成在n个区间里放最少的点,使得每个区间里都有点。
贪心策略为:
将区间按右端点从小到大排序,
然后枚举每个区间,若这个区间里有雷达(即最近放的雷达在左端点的右边),则不管它。
否则,放一个雷达在这个区间的右端点。
证明省略······

代码

#include<iostream>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
ll n,ans;
double x,y,d,t;
struct node
{
	double l,r;
} a[1001];
ll cmp(node x,node y)
{
	return x.r<y.r;//按右端点从小到大排序
}
int main()
{
	cin>>n>>d;
	for(int i=1; i<=n; i++)
	{
		cin>>x>>y;
		x+=10000001;//将可能的负数变成正数
		if(d<y)
		{
			cout<<-1;
			return 0;
		}
		a[i].l=x-sqrt(d*d-y*y);
		a[i].r=x+sqrt(d*d-y*y);
		//计算区间
	}
	sort(a,a+n+1,cmp);
	t=a[1].r;
	ans=1;
	for(int i=2; i<=n; i++)
	{
		if(a[i].l>t)
		{
			t=a[i].r;
			ans++;//得加一个雷达
		}
	}
	cout<<ans;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值