题意: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; }