POJ 1328 Radar Installation(贪心)

来源:互联网 发布:js两个时间戳比较大小 编辑:程序博客网 时间:2024/05/03 16:22

Description
将一条海岸线看成X轴,X轴上面是大海,海上有若干岛屿,给出雷达的覆盖半径和岛屿的位置,要求在海岸线上建雷达,在雷达能够覆盖全部岛屿情况下,求雷达的最少使用量
Input
多组用例,每组用例第一行为两个整数n,d(1<=n<=1000)分别表示岛屿数量和雷达范围,后面n行每行两个整数x,y表示该岛屿横,纵坐标,以n=0,d=0结束输入
Output
对于每组用例,如果雷达可以覆盖全部岛屿则输出雷达最少使用量,否则输出-1
Sample Input
3 2
1 2
-3 1
2 1

1 2
0 2

0 0
Sample Output
Case 1: 2
Case 2: 1
Solution
贪心
从左到右建立雷达,要尽量多地覆盖岛屿。以岛屿的圆心d为半径的圆与x轴有或者没有交点。如果存在没有交点的则不能实现。都存在交点的话,对于第i个岛屿计算出左右交点的x坐标保存在pos[i].l和pos[i].r里。对pos[i].l排序,然后一次从左到右找雷达。初始ll=pos[0].l为当前最左边的坐标,rr=pos[1].r为当前最右边的坐标,则对于下一个考虑岛屿i,如果pos[i].l>rr,则当前需要建立的雷达不能覆盖它,需要以此开始建立下一个雷达;否则,如果rr>pos[i].r,则需要更新rr=pos[i].r,如果ll>pos[i].l,则需要更新ll=pos[i].l,考虑下一个岛屿。别忘了最后需要建立雷达,即ans++:
Code

#include<cstdio>#include<cmath>#include<iostream>#include<algorithm>using namespace std;#define maxn 1001int n,d;struct node{    int x,y;//岛屿横,纵坐标     double l,r;//岛屿左,右交点 }pos[maxn];bool operator<(node a,node b){    return a.l<b.l;}int main(){    int res=1;    while(scanf("%d%d",&n,&d),n)    {        int flag=1;        for(int i=0;i<n;i++)        {            scanf("%d%d",&pos[i].x,&pos[i].y);            if(pos[i].y>d)                flag=0;        }        if(!flag||d<=0)//存在没有交点的岛屿,不能实现         {            printf("Case %d: -1\n",res++);            continue;        }        for(int i=0;i<n;i++)//计算第i个岛屿的左右交点         {            pos[i].l=pos[i].x-sqrt((double)(d*d-pos[i].y*pos[i].y));            pos[i].r=pos[i].x+sqrt((double)(d*d-pos[i].y*pos[i].y));        }        sort(pos,pos+n);//对左交点升序排序         int ans=0;        double ll,rr;        for(int i=0;i<n;ans++)//如果pos[i].l>rr,则当前需要建立的雷达不能覆盖它,需要以此开始建立下一个雷达         {            ll=pos[i].l;//当前最左边的坐标             rr=pos[i++].r;//当前最右边的坐标             while(i<n&&pos[i].l<=rr)//             {                ll=ll>pos[i].l?ll:pos[i].l;//更新rr                 rr=rr<pos[i].r?rr:pos[i].r;//更新ll                 i++;//考虑下一个岛屿             }        }        printf("Case %d: %d\n",res++,ans);    }    return 0;}
0 0