• NYOJ 喷水装置(二)


    
    

    喷水装置(二)

    时间限制: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 }                             
  • 相关阅读:
    关于10月20日#8的六道题的心得与感悟
    关于10月19日#7的六道题的心得与感悟
    关于10月17日#6的五道数据结构题的心得与感悟
    关于10月16日模拟赛的心得与感悟
    关于10月15日#5的四道图论题的心得与感悟
    关于10月14日#4的四道图论题的心得与感悟
    关于跨进程通信AIDL的一些总结
    对App应用架构搭建的一些思考
    Java 实例化接口或抽象类
    使用ViewPager实现卡片叠加效果
  • 原文地址:https://www.cnblogs.com/zdcaolei/p/2483606.html
Copyright © 2020-2023  润新知