POJ1328Radar Installation(区间点覆盖问题)

Radar Installation
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 68597   Accepted: 15373

Description

Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d.

We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates.

Figure A Sample Input of Radar Installations


Input

The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases.

The input is terminated by a line containing pair of zeros

Output

For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. "-1" installation means no solution for that case.

Sample Input

3 2
1 2
-3 1
2 1

1 2
0 2

0 0

Sample Output

Case 1: 2
Case 2: 1

http://blog.csdn.net/zxiaopp/article/details/48845201

数轴上有n个闭区间[ai,bi]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)。

贪心策略:

按照b1<=b2<=b3…(b相同时按a从大到小)的方式排序排序,从前向后遍历,当遇到没有加入集合的区间时,选取这个区间的右端点b。

证明:

为了方便起见,如果区间i内已经有一个点被取到,我们称区间i被满足。

1、首先考虑区间包含的情况,当小区间被满足时大区间一定被满足。所以我们应当优先选取小区间中的点,从而使大区间不用考虑。

      按照上面的方式排序后,如果出现区间包含的情况,小区间一定在大区间前面。所以此情况下我们会优先选择小区间。

      则此情况下,贪心策略是正确的。

不一定要按照正规解法,第一次我b相同,并不是按照a从大到小排序,而是a从小到大排序,其实怎么排序都可以,只要看最后的截止时间就ok了,如果下一个的开始时间在截止时间之前,那么可以用一个点覆盖,如果在后面,只需要两个点,然后更新到后面那个的截止时间,只要开始时间在截止前面一定不需要新的一个点来覆盖了。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cmath>
 6 using namespace std;
 7 const int MAX = 1000 + 10;
 8 const double eps = 10e-5;
 9 struct Rader
10 {
11     double a,b;
12 };
13 Rader rader[MAX];
14 int cmp(Rader x, Rader y)
15 {
16     if(fabs(x.b - y.b) <= eps)
17         return x.a < y.a;
18     return (x.b  - y.b) < -eps;
19 }
20 int main()
21 {
22     int n,d,flag,tase = 0;
23     double x, y, t;
24     while(scanf("%d%d", &n, &d) != EOF)
25     {
26         if(n == 0 && d == 0)
27             break;
28         flag = 0;
29         for(int i = 1; i <= n; i++)
30         {
31             scanf("%lf%lf", &x, &y);
32             if(d < y)
33             {
34                 flag = 1;
35                 continue;
36             }
37             t = sqrt(d * d - y * y);
38             rader[i].a = x - t;
39             rader[i].b = x + t;
40         }
41         printf("Case %d: ",++tase);
42         if(flag)
43         {
44             printf("-1\n");
45         }
46         else
47         {
48             sort(rader + 1, rader + 1 + n, cmp);
49             int cnt = 1;
50             double start = rader[1].b;
51             for(int i = 2; i <= n; i++)
52             {
53                 if(start - rader[i].a < -eps)
54                 {
55                     start = rader[i].b;
56                     cnt++;
57                 }
58             }
59             printf("%d\n", cnt);
60         }
61 
62     }
63 
64     return 0;
65 }
b从小到大排序

之后又想了想可不可以针对a来排序,结果也是可以的,就对a从小到大咯,如果下一个的截止时间在这个截止时间之前不用新的点覆盖,但要更新到后一个的截止时间,对,因为要以小区间为基准;如果下一个的开始时间在截止时间之后那么一定得需要一个新的点来覆盖了,同时更新到后一个的截止时间

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cmath>
 6 using namespace std;
 7 const int MAX = 1000 + 10;
 8 const double eps = 10e-5;
 9 struct Rader
10 {
11     double a,b;
12 };
13 Rader rader[MAX];
14 int cmp(Rader x, Rader y)
15 {
16    // if(fabs(x.b - y.b) <= eps)
17      //   return x.a < y.a;
18     return (x.a  - y.a) < -eps;
19 }
20 int main()
21 {
22     int n,d,flag,tase = 0;
23     double x, y, t;
24     while(scanf("%d%d", &n, &d) != EOF)
25     {
26         if(n == 0 && d == 0)
27             break;
28         flag = 0;
29         for(int i = 1; i <= n; i++)
30         {
31             scanf("%lf%lf", &x, &y);
32             if(d < y)
33             {
34                 flag = 1;
35                 continue;
36             }
37             t = sqrt(d * d - y * y);
38             rader[i].a = x - t;
39             rader[i].b = x + t;
40         }
41         printf("Case %d: ",++tase);
42         if(flag)
43         {
44             printf("-1\n");
45         }
46         else
47         {
48             sort(rader + 1, rader + 1 + n, cmp);
49             int cnt = 1;
50             double start = rader[1].b;
51             for(int i = 2; i <= n; i++)
52             {
53                 if(start - rader[i].b > eps)
54                 {
55                     start = rader[i].b;
56                 }
57                 else if(start - rader[i].a < -eps)
58                 {
59                     start = rader[i].b;
60                     cnt++;
61                 }
62             }
63             printf("%d\n", cnt);
64         }
65 
66     }
67 
68     return 0;
69 }
a从小到大

 

posted @ 2016-01-28 21:37  zhaop  阅读(279)  评论(0编辑  收藏  举报