UVA 10382 Watering Grass (区间覆盖,贪心)

问题可以转化为草坪的边界被完全覆盖。这样一个圆形就换成一条线段。

贪心,从中选尽量少的线段把区间覆盖,按照把线段按左端点排序,记录一个当前已经覆盖区间的位置cur,

从左端点小于等于cur选一个右端点最大的作为这次选的区间,如果没有符合条件的,说明不可能完全覆盖。

r*r会爆int...

 

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4+5;
int n,l,w;
struct seg
{
    double l,r;
    bool operator < (const seg& rh)const {
        return l < rh.l;
    }
}L[maxn];


int main()
{
    //freopen("in.txt","r",stdin);
    while(~scanf("%d%d%d",&n,&l,&w)){
        double d = w*w/4.;
        int ss = 0;
        for(int i = 0; i < n; i++){
            int p,r; scanf("%d%d",&p,&r);
            if(2*r<=w) {
                continue;
            }
            double dx = sqrt(1.*r*r-d);
            L[ss].l = p-dx; L[ss++].r = p+dx;
        }
        sort(L,L+ss);
        double cur = 0.; bool fg = false;
        int ans = 0;

        for(int i = 0; i < ss;){
            int j = i;
            double nxt = cur;
            while(j<ss && L[j].l <= cur) {
                if(L[j].r > nxt) nxt = L[j].r;
                j++;
            }
            if(j == i) break;
            ans++;
            cur = nxt;
            i = j;
            if(cur>=l){ fg = true; break; }
        }

        if(fg) printf("%d\n",ans);
        else puts("-1");
    }
    return 0;
}

 

posted @ 2015-09-15 12:54  陈瑞宇  阅读(226)  评论(0编辑  收藏  举报