POJ 1328 Radar Installation

来源:互联网 发布:王宇直 知乎 编辑:程序博客网 时间:2024/06/13 22:56

题意:给n个岛屿的坐标,x轴上部是海洋,x轴下部是陆地,现要在x轴上建雷达,每个雷达覆盖的范围是半径为d的圆,求覆盖所有岛屿的最小雷达数,如果不能覆盖所有岛屿就输出-1

解题思路:贪心法.这里可以转换一下思路,以每个岛屿为圆心画半径为d的圆,用结构体记录这个圆与x轴交点的坐标st、ed,那么只要雷达建在区间[st,ed]内就可以覆盖该岛屿,这道题就可以转化为求覆盖所有岛屿的最少区间数。按照st排序,首先选定第一个区间的右端点建雷达,然后判断下一个区间的st在当前雷达的左还是右,如果在右侧就表明雷达不在当前区间内,雷达数就要加1,如果在左侧就要判断新的区间的ed是在雷达的左还是右,如果ed在右就表示雷达在当前区间内,雷达的位置就不用动,它们可以共用一个雷达,如果在左就说明区间是包含关系,如果雷达在原处就不能包含在当前区间内,为了用更少的雷达,雷达的位置就要改变,将原雷达放在新区间的ed处,这样两个岛屿就可以共用一个雷达了。

代码:

#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cstdio>#include <cmath>using namespace std;int n,d;struct P{        double st,ed;}p[1010];bool cmp(P p1,P p2){    return p1.st<p2.st;}int main(){int cnt=0;    while(cin>>n>>d&&n+d)    {        int flag=0;        for(int i=0;i<n;i++)        {            int a,b;            cin>>a>>b;            p[i].st=a-sqrt(1.0*(d*d-b*b));            p[i].ed=a+sqrt(1.0*(d*d-b*b));            if(b<0)flag=1;            else if(abs(b)>d)flag=1;        }        cout<<"Case "<<++cnt<<": ";        if(flag==1){cout<<-1<<endl;continue;}        sort(p,p+n,cmp);        int ans=1;        double temp=p[0].ed;        for(int i=1;i<n;i++)        {            if(p[i].st>temp){ans++;temp=p[i].ed;}//雷达建在区间的右端点            else {temp=min(p[i].ed,temp);}//取右端点小的        }        cout<<ans<<endl;    }    return 0;}