NYOJ 喷水装置(二)

题目转换成,每个水龙头在横坐标方向上覆盖的长度区间,转换后的问题就有点像会场安排问题了,然后接下来选的方案依据贪心,我们队这些个区间进行排序,依照区间的左端点按从小到大排序,然后从左往右选取,条件是当前区间的左端点在覆盖范围内,右端点最远。如果一次循环覆盖范围没有加大,就证明不能覆盖。

 1 #include<iostream>
 2 #include<cmath>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 
 6 
 7 using namespace std;
 8 
 9 typedef struct
10 {
11     double start;
12     double end;
13 }SE;
14 
15 SE a[10002];
16 
17 int compare (const void *p1, const void *p2)
18 {
19     return (((SE *)p1)->start<((SE *)p2)->start)? 1:-1;
20 }
21 
22 int main()
23 {
24     int T;
25     cin>>T;
26     while(T--)
27     {
28         int N;
29         double w, h;
30         cin>>N>>w>>h;
31         for(int i=0; i<N; i++)
32         {
33             double x, r;
34             cin>>x>>r;
35             double tem = r*r-((double)h/2)*((double)h/2);
36             if(tem>=0)
37                 tem = sqrt(tem);
38             else
39                 tem = 0;
40             a[i].start = x - tem;
41             a[i].end = x+ tem;
42         }
43         qsort(a,N,(sizeof(a[0])),compare);
44         /*for(int i=0; i<K; i++)
45         {
46             cout<<a[i].start<<"    "<<a[i].end<<endl;
47         }*/
48         double st=0, en=0;
49         int visit[1002];
50         memset(visit,0,sizeof(visit));
51         int num = 0;
52         while(en<w)
53         {
54             double endest = en;
55             for(int i=0; i<N; i++)
56             {
57                 if(visit[i]==0&&a[i].start<=en&&a[i].end>endest)
58                 {
59                     endest = a[i].end;
60                 }
61             }
62             if(endest>en)
63             {
64                 en = endest;
65                 num++;
66             }
67             else
68             {
69                 cout<<0<<endl;
70                 break;
71             }
72         }
73         if(en>=w)
74         {
75             cout<<num<<endl;
76         }
77     }
78     return 0;
79 }
原文地址:https://www.cnblogs.com/chaiwentao/p/3947764.html