UVA 10382 Watering Grass

来源:互联网 发布:供销e家 源码 编辑:程序博客网 时间:2024/06/05 19:53

题意:有一块长l宽w的草坪,有n个喷水的装置,每个装置的位置和喷洒半径已经给出,求喷满整个草坪最少要几个喷水装置

解题思路:贪心,区间覆盖.因为喷洒的时候是个圆,所以两个圆即使有交点它们上下也可能有覆盖不到的草坪,所以就不能直接用半径去算区间,要用有效区间算


有效区间可以用勾股定理求出,接下来就是经典的区间覆盖问题了,按照区间的左端点排序不断向下找即可。(排序后我直接特判了一下第一个点的左端点和最后一个点的右端点,然后就wa了...,可能是我当时的操作有问题?!!)

代码:

#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cstdio>#include <cmath>using namespace std;struct P{    double st,ed;} p[10010];bool cmp(P p1,P p2){    if(p1.st==p2.st)return p1.ed<p2.ed;    return p1.st<p2.st;}int n;double l,w;int cnt,ans,flag;void solve(){    double temp=0;    int i=0;    while(i<cnt)    {        double v=temp;        if(p[i].st>temp)break;        else if(p[i].st<=temp)        {            while(i<cnt&&p[i].st<=temp)            {                v=max(v,p[i].ed);                i++;            }            ans++;            temp=v;        }        if(temp>=l)        {            flag=1;            break;        }    }}int main(){    while(cin>>n>>l>>w)    {        double a,b;        cnt=0;        for(int i=0; i<n; i++)        {            cin>>a>>b;            if(b>w/2.0)            {                double x=sqrt(b*b-w*w/4.0);                p[cnt].st=a-x;                p[cnt].ed=a+x;                cnt++;            }        }        sort(p,p+cnt,cmp);        ans=0;        flag=0;        solve();        if(flag)cout<<ans<<endl;        else cout<<-1<<endl;    }    return 0;}


原创粉丝点击