题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/E

题意:

       有n个喷头安装在长l米宽w米长的水平草条中间的水平线上,给出每个喷头的半径。为了让水平草条都浇到水,最少需要多少喷头?如果没办法完全浇到水平草条。输出-1。

       案例:

       input

       3 10 1

       3 5

       9 3

       6 1

       3 10 1

       5 3

      1 1

      9 1

      output

      2

      -1

思路分析:

        当喷头的射程半径小于等于水平草条的宽度的一半,不能完全覆盖草坪,可以直接忽视这样的点,而另外的可以通过加减sqrt(r*r-w*w)得出喷头范围的左右端点,就成了一个区间覆盖问题,与MINIMAL COVERAGE的思路是一样的。不懂的人可以参考那题。

源代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 using namespace std;
 6 double a[2][10010],b[10010];
 7 int n,count,j;
 8 double l,w;                
 9 void search(double le)    //区间覆盖
10 {
11     for(int i=0;i<j;i++)
12         if(a[0][i]<=le&&a[1][i]>le&&a[1][i]>b[count])    
13             b[count]=a[1][i];
14     if(b[count]!=0&&b[count]<l)
15     {
16         count++;
17         search(b[count-1]);
18     }
19 }
20 int main()
21 { 
22     while(scanf("%d%lf%lf",&n,&l,&w)!=EOF)
23     {
24         double o,r,nr;            //必须用double
25         j=0;
26         count=0;
27         memset(b,0,sizeof(b));
28         for(int i=0;i<n;i++)
29         {
30             scanf("%lf%lf",&o,&r);
31             if(r<=w/2.0) continue;                     //不需考虑的情况
32             nr=sqrt(r*r-w*w/4.0);                     //预处理
33             a[0][j]=o-nr;                              
34             a[1][j]=o+nr;
35             j++;
36         }
37         search(0);
38         if(b[count]<l)
39             printf("-1\n");
40         else
41             printf("%d\n",count+1);
42     }
43     return 0;
44 }

 

posted on 2015-08-08 15:09  尘埃。  阅读(172)  评论(0编辑  收藏  举报