喷水装置二


描述
有一块草坪,横向长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

首先寻找小于等于0的喷水装置中end最大的,然后以end为下一轮起始点,再找小于等于end数中覆盖最广的,依次找到结果。若最后无法大于横向长度,则无解,输出0。

代码如下:

[cpp]  view plain  copy
 print ?
  1. #include <stdio.h>  
  2. #include <algorithm>  
  3. #include <math.h>  
  4. using namespace std;  
  5. int ans;  
  6. double base;  
  7. double maxd;  
  8. struct node  
  9. {  
  10.     double st,end,x,r;  
  11. }data[10022];  
  12. double cal(double x,double z)  
  13. {  
  14.     double m;  
  15.     m=sqrt(x*x-z*z);  
  16.     return m;  
  17. }  
  18. int main()  
  19. {  
  20.     int u;  
  21.     int n;  
  22.     double w,h;  
  23.     double t;  
  24.     scanf ("%d",&u);  
  25.     while (u--)  
  26.     {  
  27.         scanf ("%d %lf %lf",&n,&w,&h);  
  28.         h/=2;  
  29.         for (int i=0;i<n;i++)  
  30.         {  
  31.             scanf ("%lf %lf",&data[i].x,&data[i].r);  
  32.             t=cal(data[i].r,h);  
  33.             data[i].st=data[i].x-t;  
  34.             data[i].end=data[i].x+t;  
  35.         }  
  36.         base=0;  
  37.         ans=0;  
  38.         for (int i=0;i<n;i++)  
  39.         {  
  40.             if (base>=w)  
  41.                 break;  
  42.             else  
  43.             {  
  44.                 maxd=0;  
  45.                 for (int j=0;j<n;j++)  
  46.                 {  
  47.                     if (data[j].st<=base)  
  48.                     {  
  49.                         if (data[j].end>maxd)  
  50.                             maxd=data[j].end;  
  51.                     }  
  52.                 }  
  53.                 base=maxd;  
  54.                 ans++;  
  55.             }  
  56.         }  
  57.         if (base<w)      //考虑是否能完全覆盖   
  58.             printf ("0\n");  
  59.         else  
  60.             printf ("%d\n",ans);  
  61.     }  
  62.     return 0;  
  63. }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值