Description
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 is terminated by a line containing pair of zeros
Output
Sample Input
3 2 1 2 -3 1 2 1 1 2 0 2 0 0
Sample Output
Case 1: 2Case 2: 1
雷达可以位于岛屿的左侧也可以位于雷达的右侧。而这就可以分别确定雷达相对与岛屿x的最左坐标和x最右坐标。
最左为:x - sqrt(d*d-y*y); 最右为:x + sqrt(d*d-y*y);
每个岛屿都有这样的最左和最右可被侦测坐标。
根据贪婪的思想,每次都应该将最右可被侦测坐标作为衡量标准。假定当前的岛屿为cur,当前的下一个为next。
如果next的最左可被侦测坐标比cur的最右都大的话,只能再设一个雷达来侦测next了。(转)
解题思路:
将二维坐标转换为一维坐标上的区间。求最小点覆盖所有区间。
如果小岛能被雷达覆盖,则转换在一维坐标上的最大区间为,[x-sqrt(d*d*1.0-y*y),x+sqrt(d*d*1.0-y*y)] 如果其中某个小岛不能被覆盖,则用标记变量标记。直接输出-1。
如果所有小岛都能被雷达覆盖,则进行贪心策略。 对所有区间右端进行从小大到排序(右端相同时,左端从大到小排序),则如果出现区间包含的情况,小区间一定排在前面。 然后开始遍历区间。如果当前区间超过上一个区间的覆盖范围,则雷达数+1。
第一个区间去最右值。 证明:如果第一个区间不取最右值,而取中间的点,那么把点移到最右端,被满足的区间增加了。而原先被满足的区间现在一定被满足。(转)
代码:
#include<stdio.h> #include<math.h> #include<algorithm> using namespace std; struct node { double s,e; }a[1010]; int cmp(node x,node y) { if(x.e!=y.e) return x.e<y.e; else return x.s>y.s; } int main() { int n,d,i,j,k=1; double temp; while(scanf("%d%d",&n,&d)&&(n||d)) { int x,y; int flag=0; for(i=0;i<n;i++) { scanf("%d%d",&x,&y); if(y>d) { flag=1; continue; } temp=sqrt(d*d*1.0-y*y); a[i].s=x-temp; a[i].e=x+temp; } printf("Case %d: ",k++); if(flag) { printf("-1\n"); continue; } sort(a,a+n,cmp); int ans=1; temp=a[0].e; for(int i=1;i<n;i++) { if(a[i].s>temp)//如果next的最左可被侦测坐标比cur的最右都大的话, //只能再设一个雷达来侦测next了。 { ans++; temp=a[i].e; } } printf("%d\n",ans); } return 0; }