poj 1328 贪心

//赶紧写一道题解假装我在训练......

//题意: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\n", ++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\n", ++Count, res);
48     }
49 }

 

posted @ 2015-04-25 23:37  AC_Phoenix  阅读(217)  评论(0编辑  收藏  举报