【Ybtoj 第2章 例题2】雷达装置【递推】

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


解题思路
如图,对于任意一个建筑物 ( x , y ) (x,y) x,y,我们在x轴上计算出能够侦察到该建筑物的雷达建造区间[l,r]。
在这里插入图片描述
有勾股定理得: l = x − 根 号 ( d 2 − y 2 ) l=x-根号(d^2-y^2) l=xd2y2 r = x + 根 号 ( d 2 − y 2 ) r=x+根号(d^2-y^2) r=x+d2y2
d 2 − y 2 < 0 d^2-y^2<0 d2y2<0 d < y d<y d<y时,该建筑物不可能被雷达监测到,可以直接输出 − 1 -1 1.

我们可以将所有建筑物都转换为雷达建造区间,问题转换为:给定 n n n个区间,在数轴上方尽量少的点,使得每个区间都包含一个点。

贪心策略:

  • 将所有区间按右端点从小到大排序。
  • 一次考虑每个区间
  1. 若当前区间内包含最后一个选择的点,直接跳过
  2. 若当前区间内不包含最后一个选择的点,则在该区间的右端点放一个新的点。

PS:我们很容易做错这题,比如我这个蒟蒻 直接排序,然后如果当前点的左端点比当前区间的左端点大 2 ∗ d 2*d 2d,就 a n s + + ans++ ans++。这是不对的,因为雷达的区间是一个圆,这样做是把雷达的区间当做了一个 d ∗ d d*d dd的矩阵。


代码

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
long long t,n,d,ans,x,y;
double w;
bool flag;
struct c{
    
    
	double x,y;
}a[3000];
bool cmp(const c&a,const c&b)
{
    
    
	return a.y<b.y;
}
int main() {
    
    
	scanf("%lld%lld",&n,&d);
	for(int i=1; i<=n; i++) {
    
    
		scanf("%lld%lld",&y,&x);
		if(abs(x)>d) 
			flag=1;
		a[i].x=y-sqrt(d*d-x*x);
		a[i].y=y+sqrt(d*d-x*x);
	}
	if(flag==1)
	{
    
    
		printf("-1");
		return 0;
	}
	sort(a+1,a+n+1,cmp);
	ans=1,w=a[1].y;
	for(int i=2; i<=n; i++) {
    
    
		if(a[i].x<=w&&a[i].y>=w)
			continue;
		else 
		{
    
    
			ans++;
			w=a[i].y;
		}
	}
	printf("%lld",ans);
}

猜你喜欢

转载自blog.csdn.net/kejin2019/article/details/111707586
今日推荐