【贪心】Ybt_雷达装置

题目大意

给出n个目标的坐标,你有若干个雷达,这些雷达只能放在x轴上,雷达的半径为d。
求覆盖所有目标所需最小雷达数,


贪心。
首先可以用勾股定理求出对于一个目标,雷达在x轴上的取值范围。
我选择从左到右考虑放雷达。
遂以右端点从小到大排序。
对于未覆盖的一个目标,最优的是往它的右端点上放个雷达,然后看这个雷达能覆盖多少个后面的雷达,再考虑下一个。


代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int n, d, t, ans, zz, x, y;
double pst, az;
struct asdf{
    
    
	double left, right;
} a[1010];
bool cmp(asdf aa, asdf bb){
    
      //排序
	if(aa.right < bb.right) return 1;
	if(aa.right == bb.right && aa.left < bb.right) return 1;
	return 0;
}
int main(){
    
    
	scanf("%d%d", &n, &d);
	for(int i = 1; i <= n; ++i){
    
    
		scanf("%d%d", &x, &y);
		y = max(y,0-y);
		if(y>d) {
    
      //确保有解
			printf("-1");
			return 0;
		}
		az = sqrt(d*d - y*y*1.0); //勾股定理
		a[++t].left = x-az; 
		a[t].right = x+az;
	} 
	sort(a+1, a+1+t, cmp);  //排序
	pst = a[1].right;  //先放个雷达
	++ans; zz = 1;
	while(zz < t){
    
     //还没覆盖完
		++zz;
		while(a[zz].left <= pst && zz <= t) ++zz;  //看能覆盖后面多少
		if(zz > t) break;
		++ans;  //新增雷达
		pst = a[zz].right;  //雷达位置
	}
	printf("%d", ans);
} 

猜你喜欢

转载自blog.csdn.net/qq_42937087/article/details/112115757