NYOJ 12 喷水装置(二)

 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     int ncases,n,i,width,high,x,r,count,flag;
19     double len,sum,max;
20     scanf("%d",&ncases);
21     while(ncases--)
22     {
23         flag=1;sum=0;count=0;
24         scanf("%d %d %d",&n,&width,&high);
25         for(i=0;i<=n-1;i++) 
26         {
27             scanf("%d %d",&x,&r);
28             len=(double)r*r-(double)high/2*high/2;
29             if(len>=0) {len=sqrt(len);}//**以前把这布直接并入到sqrt(len),结果忘了len可以小于0,一直WA**//
30             if(len<0) {len=0;}//**覆盖不到,这个长度就可以忽略掉**//
31             w[i].left=x-len;
32             w[i].right=x+len;
33         }
34         sort(w,w+n,comp);
35         while(sum<width)//**关键思想**//
36         {
37             max=0;//**代表比前一个装置能够辐射的范围往右延长的最大值**//
38             for(i=0;i<=n-1&&w[i].left<=sum;i++)//**w[i].left<=sum保证两个碰水装置可以相交,也就是说两点直接的能够完全覆盖**//
39             {
40                 if((w[i].right-sum)>max)//**找出既能保证完全覆盖又能保证这点能够达到的右交点最大,即需要的喷水装置最少**//
41                 {
42                     max=w[i].right-sum;//**找出最大值**//
43                 }
44             }
45             if(max==0)//**说明w[i].left>sum,表示其中一个点的右交点跟另外一个点的左交点没有连接上,即不能完全覆盖**//
46             {
47                 flag=0;
48                 break;
49             }
50             else
51             {
52                 sum=sum+max;//**更新能够覆盖的宽度**//
53                 count++;
54             }
55         }
56         if(flag==1)
57         {
58             printf("%d
",count);
59         }
60         else
61         {
62             printf("0
");
63         }
64     }
65     return 0;
66 }
67                                         
View Code

转自http://blog.csdn.net/a_eagle/article/details/7269591

解题难点与思路:

1.不知道跟贪心有什么关系,于是联系到了radar(nyoj287)那道题目,发现两题有相似点,于是很快就会想到区间覆盖的题目,但是这个覆盖有点儿不同

2.知道了是区间覆盖后,但是不知道怎么满足把所有的地方都覆盖(就是选最好的区间段使得区间与区间之间没有间隙,一直到线段的最末端)。

3.贪心策略是将左端点从小到大排序,选择右端点,使得右端点尽量覆盖的最远

原文地址:https://www.cnblogs.com/WDKER/p/5362899.html