【问题描述】
假定海岸线是一条无限延伸的直线,陆地在海岸线的一边,大海在另一侧。海中有许多岛屿,每一个小岛我们可以认为是一个点。现在要在海岸线上安装雷达,雷达的覆盖范围是d,也就是说大海中一个小岛能被安装的雷达覆盖,那么它们之间的距离最大为d。
我们使用平面直角坐标系,定义海岸线是x轴,大海在x轴上方,陆地在下方。给你海中每一个岛屿的坐标位置(x,y)和要安装的雷达所覆盖的范围d,你的任务是写一个程序计算出至少安装多少个雷达能将所有的岛屿覆盖。
(POJ输入中将有多组数据,每组数据间有一行空着,最后用一行0 0表示输入结束,你的任务是对于每组数据,求出最少需要的雷达数,若有岛屿无法被监测到,输出-1)
【样例输入】
3 2
1 2
-3 1
2 1
1 2
0 2
0 0
【样例输出】
Case 1: 2
Case 2: 1
【解题思路】
这题为贪心题,看到题目,不难想到,如果在岛屿正下方的雷达监测不到岛屿,那该岛屿必定是监测的不到的,在读完该组数据后输出-1即可。因此,对于每一个岛屿,我们以h为半径画圆,如果与x轴没有交点,则该岛无法被监测到,否则,将其与x轴的两个交点存入数组a,b。在所有交点存入数组后,以每个岛的左边的交点为关键字排序。设置一个变量r,为雷达的位置,将排序后的b[1]赋值给r,从第二个岛屿开始找,如果第二个岛屿的靠左的交点在r的监测范围之外,则将雷达数+1,将第二个岛屿靠右的交点赋值给r,如果第二个岛屿的靠右的交点在r的监测范围之内,直接将b[2]赋值给r;依此类推。
【代码实现】
1 var i,j,n,d,x,y,num,ans:longint; 2 xx,r:double; 3 f:boolean; 4 a,b:array[1..1000] of double; 5 procedure sort(l,r: longint); 6 var 7 i,j: longint; 8 x,y:double; 9 begin 10 i:=l; 11 j:=r; 12 x:=a[(l+r) div 2]; 13 repeat 14 while a[i]<x do 15 inc(i); 16 while x<a[j] do 17 dec(j); 18 if not(i>j) then 19 begin 20 y:=a[i]; 21 a[i]:=a[j]; 22 a[j]:=y; 23 y:=b[i]; 24 b[i]:=b[j]; 25 b[j]:=y; 26 inc(i); 27 dec(j); 28 end; 29 until i>j; 30 if l<j then 31 sort(l,j); 32 if i<r then 33 sort(i,r); 34 end; 35 begin 36 readln(n,d); 37 while n<>0 do 38 begin 39 f:=true; 40 inc(num);//增加数据数 41 for i:=1 to n do 42 begin 43 readln(x,y); 44 if y>d then//判断是否有无论雷达在哪都监测不到的岛屿 45 begin 46 f:=false; 47 continue; 48 end; 49 xx:=sqrt(sqr(d)-sqr(y)); 50 a[i]:=x-xx;b[i]:=x+xx;//用勾股定理求与x轴的交点 51 end; 52 if not(f) then 53 begin 54 writeln('Case ',num,':',' ',-1); 55 readln(n,d); 56 continue; 57 end;//存在雷达监测不到的点,输出-1,读入下一组数据 58 sort(1,n);//排序 59 r:=b[1]; 60 ans:=1; 61 for i:=2 to n do//一个个比较 62 begin 63 if a[i]>r then//若不在范围雷达数+1 64 begin 65 inc(ans); 66 r:=b[i]; 67 end; 68 if b[i]<r then//若在,直接赋给r 69 r:=b[i]; 70 end; 71 writeln('Case ',num,':',' ',ans); 72 readln(n,d);//读入下一组数据 73 end; 74 end.