题目大意
给出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);
}