现在的位置: 首页 > 综合 > 正文

贪心-poj-1328-Radar Installation

2013年12月12日 ⁄ 综合 ⁄ 共 1321字 ⁄ 字号 评论关闭

题目链接:

http://poj.org/problem?id=1328

题目意思:

X轴上方有些点,给一个距离d,求在X轴上找最少的点,使得以这些点为圆心以d为半径,能够包围住所有的点。

解题思路:

贪心。

问题等价转换。对于每个X轴上方的点A(x,y),在X轴能扫到它的范围为【x-sqrt(d*d-y*y),x+sqrt(d*d-y*y)】,所以问题就转化为,给定若干区间,求最少的点数,使得每个区间至少有一个点在这些点中。很容易想到,对区间的结尾端点排序,对于每个区间,将点设到结尾端点,这样它能覆盖的区间是最多的。直到后一区间的开始端点超过它时,才不能覆盖。

关键:将题目等价转化,转换成区间形式。这样就好办了。

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 1100
struct Inte
{
    double s,e;
}inte[Maxn];
int n;
double d;

bool cmp(struct Inte a,struct Inte b)
{
    return a.e<b.e; //对后一个端点排序

}
int main()
{
    int ca=0;

    while(scanf("%d%lf",&n,&d)&&n+d)
    {
        bool flag=true;

        for(int i=1;i<=n;i++)
        {
            double x,y,temp;
            scanf("%lf%lf",&x,&y);

            if(y>d)
                flag=false; //肯定不行
            else
            {
                temp=sqrt(d*d-y*y); //求出能覆盖该点的区间
                inte[i].s=x-temp;
                inte[i].e=x+temp;
            }

        }
        printf("Case %d: ",++ca);
        if(!flag)
        {
            printf("-1\n");
            continue;
        }

        sort(inte+1,inte+n+1,cmp);
        int ans=1;
        int cur=1;

        for(int i=2;i<=n;i++)
        {
            if(inte[i].s>inte[cur].e) //该点不能覆盖了
            {
                ans++;
                cur=i;
            }
        }
        printf("%d\n",ans);

    }
   return 0;
}


抱歉!评论已关闭.