NYOJ 喷水装置2 (贪心)

来源:互联网 发布:女人不孕不育网络咨询 编辑:程序博客网 时间:2024/05/17 14:29

喷水装置(二)

时间限制: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<iostream>#include<cmath>#include<vector>#include<algorithm>using namespace std;double len(double r,double h){return sqrt(r*r-h*h);} int cmp(pair<double,double>a,pair<double,double> b){return a.first<b.first;}int main(){int N;int n,w,h;int x,r;cin>>N;while(N--){cin>>n>>w>>h;vector<pair<double,double> > v;for(int i=0;i<n;i++){cin>>x>>r;if(r>h/2.0){//求解左右顶点 double l=len(r,h/2.0);pair<double,double> p;p.first=x-l;p.second=x+l;v.push_back(p);}}//按左点升序排序 sort(v.begin(),v.end(),cmp);//进行比较double right=0.0;int count=0;while(right<w){double m=0.0;for(int i=0;i<v.size()&&v[i].first<=right;i++){if(v[i].second-right>m) m=v[i].second-right;}if(m!=0){count++;right+=m;}else break;}if(right<w) cout<<0<<endl;else cout<<count<<endl;}return 0;}        




0 0
原创粉丝点击