题意:x轴上方有若干小岛,用坐标(x,y)给出。现要在x轴上建立若干雷达,雷达的半径(r)全部相同,且由输入给定。问为了覆盖全部小岛,最少需要建立多少雷达?
思路:对每个小岛坐标,求出需要覆盖它的雷达的x坐标范围,可以得到一系列区间。问题变成每个区间里至少选一点,问最少的选点数量。
将所有区间按照右侧大小排序,用一个变量now表示当前可到区间的最右端,如果下一个区间的左端点大于now,则点数加1;否则,点数不加。
#include <stdio.h>
#include <string.h>
#include <math.h>
#define min(a,b) a<b?a:b
#define N 1005
struct point{
int x,y;
}p[N];
struct interval{
double x,y;
}s[N];
int T=1,n,r;
int cmp(const struct interval *a,const struct interval *b){
if((*a).y > (*b).y)
return 1;
if((*a).y < (*b).y)
return -1;
return 0;
}
int main(){
freopen("a.txt","r",stdin);
while(scanf("%d %d",&n,&r) && (n||r)){
int i,j,res=1,flag=1,temp;
double chord,now;
if(r<0)
flag = 0;
for(i = 0;i<n;i++){
scanf("%d %d",&p[i].x,&p[i].y);
if(flag){
temp = r*r-p[i].y*p[i].y;
if(temp < 0){
flag = 0;
continue;
}
chord = sqrt(temp);
s[i].x = p[i].x-chord;
s[i].y = p[i].x+chord;
}
}
if(!flag){
printf("Case %d: -1\n",T++);
continue;
}
qsort(s,n,sizeof(struct interval),cmp);
now = s[0].y;
for(i = 1;i<n;i++){
if(s[i].x > now){
res++;
now = s[i].y;
}
}
printf("Case %d: %d\n",T++,res);
}
return 0;
}