POJ 1328 Radar Installation(贪心)

来源:互联网 发布:斗图软件下载 编辑:程序博客网 时间:2024/06/06 08:43

poj 1328

  • 题目大意
    在x轴上方分布n(1<=n<=1000)个点,给出了这n个点的坐标。在x轴上的一个雷达能覆盖半径为d的区域,问最少需要多少雷达才能覆盖所有点。

  • 分析
    最开始是想对雷达位置进行贪心(恰好能覆盖最左边的点的位置放雷达),但仔细想了之后发现这样不可行。
    转换思路后,考虑对每个点都对应x轴上的一个区间,只有这个区间的雷达才能覆盖这个点。那么现在问题就变成了给定n个区间,选出k个点使得每个区间上至少有一个点的k的最小值。这样问题就变成了一个比较典型的贪心问题了:按照区间的右端点作为关键字升序排序,从左到右开始扫描,用一个变量cur来表示当前扫描到的位置,对于当前区间的左端点如果小于等于cur那么看下一个区间;若大于,ans++,并更新cur的值为这个区间的右端点,看下一个区间.

  • 注意
    应该注意d<y以及d为负的特殊情况

  • 代码

#include<cstdio>#include<iostream>#include<cmath>#include<cstring>#include<cstdlib>#include<queue>using namespace std;const double INF=999999999;int n;double d;struct LINE{      double s;      double t;}line[1005];int num=0;int Cmp(const void *p1,const void *p2){    return ((LINE *)p2)->t < ((LINE *)p1)->t ? 1 : -1;}int main(){    int Case=0;    double x,y;    int flag=0;    while(scanf("%d%lf",&n,&d))    {         flag=0;         if(d<0)flag=1;         num=0;         if(n==0 && d==0)break;         for(int i=1;i<=n;i++)         {              scanf("%lf%lf",&x,&y);              if(y>d)flag=1;              line[++num].s=x-sqrt(d*d-y*y);              line[num].t=x+sqrt(d*d-y*y);         }         if(flag==1)         {               printf("Case %d: -1\n",++Case);               continue;         }         qsort(line+1,num,sizeof(line[0]),Cmp);         double cur=line[1].t;         int ans=1;         for(int i=2;i<=num;i++)         {              if(line[i].s<=cur)continue;              else              {                    ans++;                    cur=line[i].t;              }         }         printf("Case %d: %d\n",++Case,ans);    }    return 0;}
0 0
原创粉丝点击