题目:
题解:
贪心。
以每个小岛为圆心,以雷达半径为半径画弧,交x轴于两点,成一条线段,雷达只有安插在这条线段内部,才能监控到小岛;
将二维问题转化为一维线段问题;
将上述线段按照右端点排序(左端点也可以,右端点更简单);
维护maxx表示已经安插的雷达的最右位置。
在第一条线段的右端点安插雷达,这样既能监控到此小岛,又能尽可能的监控到右边;
对于下一条线段,如果它的左端点比maxx大,maxx不能监控到它,需要新建雷达(仍然建在最左边),如果不比maxx大,那么之前的雷达就能够监控到它,不做处理。
雷达半径有小于0的,与符号无关,正常平方处理即可。
注意:
r<=0 属于不合法情况,直接输出-1
一开始没有注意到,也A了,应该是少数的r<0数据中有y大于0的,卡死了;
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int n,ans,cnt;
bool flag;
double x,y,maxx,r;
struct wkw{
double rit,lft;
}e[10000];
bool cmp(wkw a,wkw b){
return a.rit<b.rit;
}
void init(){
for(int i=1;i<=n;i++) e[i].rit=0,e[i].lft=0;
maxx=0;
ans=0;
flag=0;
}
int main(){
while(scanf("%d%lf",&n,&r)){
cnt++;
if(n==0) return 0;
init();
if(r<=0) flag=1;
for(int i=1;i<=n;i++){
scanf("%lf%lf",&x,&y);
double a=sqrt(r*r-y*y);
e[i].rit=x+a;
e[i].lft=x-a;
if(y>r) flag=1;
}
if(flag) {
printf("Case %d: -1\n",cnt);
continue;
}
sort(e+1,e+n+1,cmp);
maxx=e[1].rit;ans=1;
for(int i=2;i<=n;i++){
if(e[i].lft>maxx){
maxx=e[i].rit;
ans++;
}
}
printf("Case %d: %d\n",cnt,ans);
}
}