UVA-1615 Highway (贪心,区间选点)

题目大意:有一条沿x轴正方向,长为L的高速公路,n个村庄,要求修建最少的公路出口数目,使得每个村庄到出口的距离不大于D。

题目分析:区间选点问题。在x轴上,到每个村庄距离为D的点有两个(超出范围除外),这两个点便构成了一个区间,这样的区间总共有n个。问题便转化为了,在n个区间中选取最少的点占据所有区间。贪心即可,贪心策略:将所有区间按右端点排序,若需要选择,每次都选区间右端点。

 

代码如下:

# include<iostream>
# include<cstdio>
# include<vector>
# include<cmath>
# include<cstring>
# include<algorithm>
using namespace std;

struct Q
{
    double l,r;
    Q(double _l,double _r):l(_l),r(_r){}
    bool operator < (const Q &a) const {
        return r<a.r;
    }
};
int L,D,n;
vector<Q>v;

void dist(int x,int y,double &l,double &r)
{
    l=(double)x-sqrt((double)D*(double)D-(double)y*(double)y);
    r=(double)x+sqrt((double)D*(double)D-(double)y*(double)y);
}

int solve()
{
    int ans=0;
    double p=-1.0;
    for(int i=0;i<n;++i){
        if(p<v[i].l||p>v[i].r){
            ++ans;
            p=v[i].r;
        }
    }
    return ans;
}

int main()
{
    int x,y;
    double li,ri;
    while(scanf("%d",&L)!=EOF)
    {
        scanf("%d%d",&D,&n);
        v.clear();
        for(int i=0;i<n;++i){
            scanf("%d%d",&x,&y);
            dist(x,y,li,ri);
            v.push_back(Q(max(0.0,li),min((double)L,ri)));
        }
        sort(v.begin(),v.end());
        printf("%d\n",solve());
    }
    return 0;
}

  

posted @ 2015-10-18 10:40  20143605  阅读(638)  评论(0编辑  收藏  举报