nyist 12 喷水装置(二)

来源:互联网 发布:java时间加减 小时 编辑:程序博客网 时间:2024/05/21 09:25


喷水装置(二)

时间限制:3000 ms  |  内存限制:65535 KB
难度:4
描述
有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。
输入
第一行输入一个正整数N表示共有n次测试数据。
每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。
随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。
输出
每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。
如果不存在一种能够把整个草坪湿润的方案,请输出0。
样例输入
22 8 61 14 52 10 64 56 5
样例输出
12
装换为贪心区间覆盖问题 左端点从小到大排序 每次选区间最长的,
#include<stdio.h>#include<iostream>#include<math.h>#include<algorithm>using namespace std;struct xxx{    double a,b;} k[10010];bool  cmp(xxx q1,xxx q2){    return q1.a<q2.a;}int main(){    int t,n,i,cou;    double w,h,xi,ri;    cin>>t;    while(t--)    {        cin>>n>>w>>h;        cou=0;        for(i=0; i<n; i++)        {            cin>>xi>>ri;            if(ri<=h/2)                continue;            double m=sqrt(ri*ri-h*h/4);           // cout<<" m="<<m<<endl;            k[cou].a=xi-m;            k[cou].b=xi+m;            cou++;        }        sort(k,k+cou,cmp);        int ans=0,ok=1;        double MAX=0,sum=0;       // cout<<k[0].a<<endl;        while(sum<w)        {            MAX=0;            for(i=0; i<cou&&k[i].a<=sum; i++)            {                //cout<<"i="<<i<<endl;               // cout<<k[i].b-sum<<endl;                if(k[i].b-sum>MAX)                {                    MAX=k[i].b-sum;                }            }          //  cout<<"MAX="<<MAX<<endl;            if(MAX==0)            {                ok=0;                break;            }            else            {                sum=sum+MAX;                ans++;            }        }        if(ok==0)            cout<<"0"<<endl;        else            cout<<ans<<endl;    }    return 0;}

0 0
原创粉丝点击