题意:假设滑行是无限直线。土地位于海岸线的一侧,另一侧是海洋。每个小岛都位于海边。并且位于滑行的任何雷达装置只能覆盖d距离,因此如果它们之间的距离最多为d,则可以通过半径装置覆盖海中的岛屿。我们使用笛卡尔坐标系,定义滑行是x轴。海侧在x轴上方,陆侧在下方。考虑到每个岛屿在海中的位置,并考虑到雷达装置覆盖范围的距离,您的任务是编写一个程序,以找到覆盖所有岛屿的最小数量的雷达装置。注意,岛的位置由其xy坐标表示。
分析:对于每个建筑物,可以计算出x轴上能管辖它的一段区间,于是题目转化为了有n段区间,选择尽量少的点使得所有区间包含至少一个选了的点.考虑贪心,把区间按照左端点从小到大排序,开一个变量pos记录当前最后一台设备的位置,对于一个区间,如果包含pos则不用新开设备,但要更新(pos=min(pos,r[i]));否则就要新开一个设备,同时令(pos=r[i]).
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
inline int read(){
int x=0,o=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')o=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*o;
}
struct ppx{
double l,r;
}a[1005];
inline bool cmp(const ppx &x,const ppx &y){return x.l<y.l;}
int main(){
int T=0;
while(1){
int n=read(),d=read();if(!n&&!d)break;
printf("Case %d: ",++T);int bj=0;
for(int i=1;i<=n;++i){
int x=read(),y=read();
a[i].l=x*1.0-sqrt(d*d*1.0-y*y*1.0);
a[i].r=x*1.0+sqrt(d*d*1.0-y*y*1.0);
if(y>d)bj=1;
}
if(bj){puts("-1");continue;}
else{
sort(a+1,a+n+1,cmp);
int ans=1;double pos=a[1].r;
for(int i=2;i<=n;++i){
if(a[i].l>pos)++ans,pos=a[i].r;
else pos=min(pos,a[i].r);
}
printf("%d
",ans);
}
}
return 0;
}