-
喷水装置(二)
时间限制: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。 - 样例输入
-
2 2 8 6 1 1 4 5 2 10 6 4 5 6 5
- 样例输出
-
1 2
我的程序:
1 #include<iostream> 2 #include<algorithm> 3 #include <math.h> 4 using namespace std; 5 #define max(a,b) (a>b?a:b) 6 struct Ww{ 7 float xi,ri; 8 }; 9 bool com(const Ww &a,const Ww &b){ 10 if(a.xi<b.xi) return true; 11 if(a.xi==b.xi&&a.ri>b.ri) return true; 12 13 return false; 14 15 } 16 float dis(float rr,float hh){ 17 if(rr*rr-hh*hh/4>=0) 18 return sqrt(rr*rr-hh*hh/4); 19 else 20 return 0; 21 22 } 23 24 25 int main(){ 26 int m; 27 freopen("12.txt","r",stdin); 28 cin>>m; 29 while(m--){ 30 int n; 31 cin>>n; 32 Ww a[n]; 33 float w,h; 34 cin>>w; 35 cin>>h; 36 for(int i=0;i<n;i++) 37 cin>>a[i].xi>>a[i].ri; 38 39 sort(a,a+n,com); 40 41 42 43 float sum=0; 44 int count=0; 45 int first=0,rear=n-1; 46 47 for(int i=0;i<=n-1;i++){ 48 49 if(rear==first&&(a[first].ri>=sqrt(w/2+h*h/4))) { count++; break; 50 } 51 if(rear==first&&a[first].ri<sqrt(w/2+h*h/4)) {break;} 52 53 if(dis(a[first].ri,h)>=a[first].xi){ 54 if(dis(a[rear].ri,h)>=w-a[rear].xi) { 55 if(a[i].xi!=a[i+1].xi){ 56 if(dis(a[i].ri,h)+dis(a[i+1].ri,h)>=a[i+1].xi-a[i].xi){ 57 if(first==i) count+=2; 58 else 59 count++; 60 61 62 }} 63 64 }else{ 65 rear--; 66 } 67 68 69 }else 70 { 71 first++; 72 } 73 74 } 75 76 77 cout<<count<<endl; 78 } 79 80 81 }
我后来重写的:
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<algorithm> 5 using namespace std; 6 struct ps 7 { 8 double left; 9 double right; 10 }w[10001]; 11 bool comp(ps a,ps b) 12 { 13 if(a.left<b.left) return true; 14 return false; 15 } 16 int main() 17 { 18 freopen("12.txt","r",stdin); 19 int ncases,n,i,width,high,x,r,count,flag; 20 double length,sum,max; 21 scanf("%d",&ncases); 22 while(ncases--) 23 { 24 flag=1;sum=0;count=0; 25 scanf("%d %d %d",&n,&width,&high); 26 for(i=0;i<=n-1;i++) 27 { 28 scanf("%d %d",&x,&r); 29 length=(double)r*r-(double)high/2*high/2; 30 if(length>=0) {length=sqrt(length);} 31 if(length<0) {length=0;} 32 w[i].left=x-length; 33 w[i].right=x+length; 34 } 35 sort(w,w+n,comp); 36 while(sum<width) 37 { 38 max=0; 39 for(i=0;i<=n-1&&w[i].left<=sum;i++) 40 { 41 if((w[i].right-sum)>max) 42 { 43 max=w[i].right-sum; 44 } 45 } 46 if(max==0) 47 { 48 flag=0; 49 break; 50 } 51 else 52 { 53 sum=sum+max; 54 count++; 55 } 56 } 57 if(flag==1) 58 { 59 printf("%d\n",count); 60 } 61 else 62 { 63 printf("0\n"); 64 } 65 } 66 return 0; 67 }
最优程序:1 2 #include<iostream> 3 #include<vector> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 double r,x,y,width,height; 8 class Circle 9 { 10 public: 11 Circle(double x,double r):x(x),r(r){} 12 double Left() const{ 13 if(r*r-height*height/4<0) return x;return x-sqrt(r*r-(height*height/4));} 14 double Right() const{if(r*r-height*height/4<0) return x;return x+sqrt(r*r-(height*height/4));} 15 friend ostream & operator<<(ostream& out,const Circle& circle); 16 private: 17 double x,r; 18 }; 19 ostream & operator<<(ostream& out,const Circle& circle) 20 { 21 out<<circle.x<<" "<<circle.r; 22 return out; 23 } 24 struct CircleLess 25 { 26 bool operator()(const Circle& c1,const Circle& c2) 27 { 28 return c1.Right()<c2.Right(); 29 } 30 }; 31 32 int main() 33 { 34 35 int m; 36 cin>>m; 37 while(m--) 38 { 39 int n; 40 41 vector<Circle> Rs; 42 cin>>n>>width>>height; 43 Rs.reserve(n); 44 45 46 while(n--) 47 { 48 cin>>x>>r; 49 Rs.push_back(Circle(x,r)); 50 } 51 sort(Rs.begin(),Rs.end(),CircleLess()); 52 vector<int> choosed; 53 choosed.push_back(-1); 54 double len=0; 55 try{ 56 while(len<width) 57 { 58 int last=-1; 59 for(vector<Circle>::size_type i=choosed.back()+1;i!=Rs.size();i++) 60 { 61 if (Rs[i].Left()<=len) 62 { 63 //cout<<Rs[i].Left()<<endl; 64 last=i; 65 } 66 } 67 if (last==-1) throw -1; 68 else 69 { 70 choosed.push_back(last); 71 len=Rs[last].Right(); 72 } 73 } 74 cout<<choosed.size()-1<<endl; 75 76 }catch(...) 77 { 78 cout<<0<<endl; 79 } 80 } 81 82 }
NYOJ 喷水装置(二)
欢迎转载,转载请注明出处。本文出自:http://www.cnblogs.com/zdcaolei