POJ 1328

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

x轴以及其上方有一些海岛,要在x轴(海岸)上安装最少的雷达(每个雷达覆盖范围半径为d),使得每个海岛都能被雷达覆盖到,求安装的最少雷达的数量。


思路是,对于某个海岛i,求出海岸上最小的区间[ai,bi],s.t.任意的在这个区间内位置安装雷达都可以覆盖该岛

then对于每个海岛,都有一个区间[ai,bi](若求不出区间,显然是无论如何雷达都覆盖不到海岛了,就输出-1),这样就变成了区间选点问题。

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 typedef struct{
 7     float x;float y;
 8 }type;
 9 bool cmp(type a,type b)  
10 {  
11     if(a.y == b.y) return a.x > b.x; 
12     return a.y < b.y;
13 }
14 type island[1003];
15 
16 int main()
17 {
18     int n,d,kase=0;
19     bool flag; 
20     while( scanf("%d %d",&n,&d) == 2 && n!=0){
21         flag=1;
22         for(int i=1;i<=n;i++){
23             scanf("%f %f",&island[i].x,&island[i].y);
24             if(island[i].y > d){
25                 flag=0; //如果有某个海岛无论如何雷达都覆盖不到的话,就标记一个false 
26             }
27             float x=island[i].x;
28             float delta=sqrt(d*d-island[i].y*island[i].y);
29             island[i].x = x - delta; island[i].y = x + delta; //将海岛的坐标转换为对应安放雷达的区间
30         }
31         if(flag==0){
32             printf("Case %d: -1
",++kase);
33             continue;
34         }//如果前面有某个点标记了false,输出-1 
35         
36         sort(island+1,island+n+1,cmp); //将区间排序,为后续区间选安放雷达的点做准备 
37         
38         int i=1,cnt=1;
39         do{
40             float end_point = island[i].y;
41             int j;
42             for(j=i;;j++)
43                 if(j == n || island[j].x > end_point) break; //寻找下一个点的位置(位于哪个区间) 
44             if(island[i].y < island[j].x) cnt++; //如果找到的那个区间可以确实不能被上一个点覆盖到,就增加一个雷达点
45             i=j;
46         }while(i < n);
47         //区间选点完成 
48          
49         printf("Case %d: %d
",++kase,cnt);
50     }
51 }





测试数据:

2 5
-3 4
-6 3

4 5
-5 3
-3 5
2 3
3 3

20 8
-20 7
-18 6
-5 8
-21 8
-15 7
-17 5
-1 5
-2 3
-9 6
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 7
9 6
10 5
0 0

2 3
0 2
2 3

2 3
0 2
1 3

3 3
1 2
-3 2
2 4

8 5
2 4
-4 4
-3 3
-3 1
-3 0
-1 0
0 5
6 0

3 0
1 2
-3 1
2 1

3 2
1 2
-3 1
2 1

1 2
0 2

2 3
0 2
2 3

4 -5
4 3
4 3
2 3
6 -9

3 -3
1 2
-3 2
2 1

6 2
1 2
1 2
1 2
-3 1
2 1
0 0

1 2
0 2

2 3
0 2
1 3

3 10
1 10
2 3
4 5

3 5
1 10
2 3
4 5

4 7
1 10
2 3
4 5
0 0

3 9
1 10
2 3
4 5

2 5
0 3
8 3

0 0

对应结果:

Case 1: 1
Case 2: 2
Case 3: 4
Case 4: 1
Case 5: 1
Case 6: -1
Case 7: 3
Case 8: -1
Case 9: 2
Case 10: 1
Case 11: 1
Case 12: -1
Case 13: -1
Case 14: 2
Case 15: 1
Case 16: 1
Case 17: 1
Case 18: -1
Case 19: -1
Case 20: -1
Case 21: 1




原文地址:https://www.cnblogs.com/dilthey/p/6804174.html