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
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
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
题意:N座岛屿,坐标用xi,yi表示,岛屿都位于x轴上。在x轴上建造雷达,每个雷达的的探测范围是以【x,0】为圆心,半径为R的圆(下半圆一看就没用),问最少几个雷达可以探测全部岛屿?
思路:我们把每个岛屿为圆心,做出x轴上雷达的可行建造区域,那么问题就变成用最小的雷达覆盖最多的区域(每个区域一个雷达)。
我们先将区域按左边界递增排序,每取到一个区间,就记录在这个区间右边界pos,如果下个区间的左边界>pos,说明这个雷达无法探测,需要新建雷达,
否则就pos = min(pos,r),就是让原有的雷达去探测它,但是雷达需要移至两个区间的最小右边界处(交集嘛)。
①因为要用比较左边界和上一次区间的右边界,所以一定是按照左边界排序的。(这样处理后面的区域和之前区域没啥关系,只和pos有关)
置于为什么pos取右边界,因为右边界代表了雷达最远可放置位置(极值),其包含了区间内可行取值了。(决策包容性?)
②当然如果你反过来,右边界排序,你就需要比较右边界和上一次的左边界也行。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<math.h> 5 using namespace std; 6 7 int n,r; 8 struct Node 9 { 10 double l,r; 11 } L[1005]; 12 13 double calc(int y,int r) 14 { 15 return sqrt(r*r-y*y); 16 } 17 18 int dcmp(double a,double b) 19 { 20 if(fabs(a-b) < 1e-8) 21 return 0; 22 else 23 return a-b > 0?1:-1; 24 } 25 bool cmp(Node a,Node b) 26 { 27 return dcmp(a.l,b.l)<0; 28 } 29 int main() 30 { 31 int cas = 0; 32 while(~scanf("%d%d",&n,&r) && (n || r)) 33 { 34 int ans=0; 35 for(int i=1; i<=n; i++) 36 { 37 double x,y; 38 scanf("%lf%lf",&x,&y); 39 if(dcmp(y,r) > 0) 40 { 41 ans = -1; 42 continue; 43 } 44 double add = calc(y,r); 45 L[i].l = x-add; 46 L[i].r = x+add; 47 } 48 if(ans == -1){printf("Case %d: -1 ",++cas);continue;} 49 sort(L+1,L+1+n,cmp); 50 double pos = -0x3f3f3f3f3f3f3f; 51 for(int i=1; i<=n; i++) 52 { 53 if(dcmp(L[i].l,pos)>0) 54 { 55 ans++; 56 pos = L[i].r; 57 } 58 else 59 { 60 pos = min(L[i].r,pos); 61 } 62 } 63 printf("Case %d: %d ",++cas,ans); 64 } 65 }