poj 1328 贪心 转化

来源:互联网 发布:中国广电网络缴费 编辑:程序博客网 时间:2024/06/06 23:31

题目大意:


如图所示,x轴表示海岸线,x轴上方表示大海,下方表示陆地,有n(1<=n<=1000)个岛屿在海中,现在要在海岸线上建立雷达,每个雷达最大能探测仪雷达为半径的距离为d的区域,问最少需要多少个雷达才能将岛屿全部至于监测之下,如果无法做到输出-1;


基本思路:

一开始是想让岛屿尽量落在雷达能测量的圆的边界上,尽量让雷达位置靠右,后来发现有些情况是无法满足的(至于什么情况请自行思考),根据第一个岛屿放雷达位置很明显要受到后边岛屿位置的影响,不仅仅是它后面那一个岛屿,所以这样做是不可行的,所以我的做法先排序,然后是把每一个岛屿可以在x轴上放雷达监测到的区间表示出来,然后用一个变量表示选到当前岛屿区间的最右端记录,一个一个地根据后面区间与当前right记录的数值关系不断更新right,加或者不加个数,最终得出结果;

重点是:将每个岛屿的位置转换为x轴上的区间来通过集合的关系来判断并计算需要雷达的个数,然后贪心的话就是从最左边开始放累的的地方肯定是某一个区间最右边;

代码如下:

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 1000+10;
struct Node
{
    double x,y;
    double x1,x2;
};
Node node[maxn];
bool cmp(Node a,Node b)
{
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}
int main()
{
    int n,d,cnt=0;
    while(scanf("%d%d",&n,&d)==2&&n&&d)
    {
        int ok=1;
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf",&node[i].x,&node[i].y);
            if(node[i].y>d) ok=0;//排除无法检测的情况;
        }
        if(ok)
        {
            printf("Case %d: ",++cnt);
            sort(node,node+n,cmp);
            for(int i=0;i<n;i++)
            {
                double x=node[i].x;
                double y=node[i].y;
                double temp=sqrt(d*d-y*y);
                node[i].x1=x-temp;
                node[i].x2=x+temp;
            }
            int sum=1;
            double right=node[0].x2;
            for(int i=1;i<n;i++)
            {
                if(node[i].x2<right) right=node[i].x2;  //下一个岛屿的区间在当前right的左边,要用一个雷达能同时监测到这两个岛屿,更新right的值;
                else if(node[i].x1>right)   //无法让一个雷达同时监测这两个岛屿,所以直接放下一个雷达;
                {
                    right=node[i].x2;
                    sum++;
                }
                //当然还有其他情况,不过对当前right和sum没有改变;
            }
            printf("%d\n",sum);
        }
        else
        {
            printf("Case %d: %d\n",++cnt,-1);
        }
    }
    return 0;
}

0 0
原创粉丝点击