//赶紧写一道题解假装我在训练......
//题意:x轴以上分配着一些点,给定圆的半径,求最少需要圆的个数去将这些点全部覆盖掉。
//分析:裸贪心,对于一个点在x轴上存在一个区间,要保证这个区间上必须存放雷达(一个圆的圆心)才能保证这个点被覆盖掉。
//做法:优先考虑右端最靠左的区间,我们在这个区间上放置雷达点时,越往右影响到的区间数就有可能增加,不可能减少。于是我们就将雷达放到最右端,然后将这些受到影响的区间删除,之后继续考虑右端最靠左的区间。
1 #include "cstdio" 2 #include "cstring" 3 #include "algorithm" 4 #include "utility" 5 #include "cmath" 6 #include "iostream" 7 using namespace std; 8 long long n, d; 9 pair<double, double> seg[2010]; 10 bool exist[2010]; 11 12 int main() 13 { 14 int Count = 0; 15 while(scanf("%lld%lld", &n, &d) != EOF && (n || d)) { 16 memset(exist, 1, sizeof(exist)); 17 long long x, y; 18 int i; 19 bool fail = 0; 20 for(i = 1; i <= n; ++i) { 21 scanf("%lld%lld", &x, &y); 22 if((long long)fabs((double)y) > d) { 23 fail = 1; 24 } 25 double dis = sqrt(fabs(double(d * d - y * y))); 26 seg[i].second = x - dis; 27 seg[i].first = x + dis; 28 } 29 if(fail) { 30 printf("Case %d: -1 ", ++Count); 31 continue; 32 } 33 sort(seg + 1, seg + 1 + n); 34 int res = 1; 35 double pos = seg[1].first; 36 exist[1] = 0; 37 for(i = 2; i <= n; ++i) { 38 if(exist[i] && seg[i].second <= pos) { 39 exist[i] = 0; 40 } 41 else if(exist[i]){ 42 exist[i] = 0; 43 pos = seg[i].first; 44 ++res; 45 } 46 } 47 printf("Case %d: %d ", ++Count, res); 48 } 49 }