UVa 10382 喷水装置(贪心)

https://vjudge.net/problem/UVA-10382

题意:

有一个长为l,宽为w的草坪,在其中心线不同位置有n个点状的喷水装置,喷水坐标为p,喷水半径为r。求喷到所有草坪的最少喷水装置数量。

思路:

喷水装置的有效面积是图中的矩形部分,由此就把喷水区域变成了区间区域,之后利用贪心就可以了。

 1 #include<iostream> 
 2 #include<string>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 
 8 const int maxn = 10000 + 5;
 9 
10 int n;
11 double l, w;
12 
13 struct node
14 {
15     double l, r;
16 }a[maxn];
17 
18 double cacl(double y)
19 {
20     return sqrt(y*y - (w / 2.0)*(w / 2.0));
21 }
22 
23 bool cmp(node a, node b)
24 {
25     return a.l < b.l;
26 }
27 
28 int main()
29 {
30     ios::sync_with_stdio(false);
31     //freopen("D:\txt.txt", "r", stdin);
32     double x, y;
33     while (cin >> n >> l >> w)
34     {
35         int cnt = 0;
36         for (int i = 0; i < n; i++)
37         {
38             cin >> x >> y;
39             if (y <= w / 2.0)  continue;
40             double m = cacl(y);
41             a[cnt].l = x - m;
42             a[cnt].r = x + m;
43             cnt++;
44         }
45         sort(a, a + cnt, cmp);
46         int num = 0;
47         int flag = 0;
48         double left = 0, right = 0;
49         if (a[0].l <= 0)
50         {
51             int i = 0;
52             while (i < cnt)
53             {
54                 int j = i;
55                 //找一个右端坐标最大的
56                 while (j < cnt && a[j].l<=left)
57                 {
58                     if (a[j].r > right)
59                     {
60                         right = a[j].r;
61                     }
62                     j++;
63                 }
64                 if (i == j)  break;
65                 i = j;
66                 num++;
67                 left = right;
68                 if (left >= l)
69                 {
70                     flag = 1;
71                     break;
72                 }
73             }
74         }
75         if(flag) cout << num << endl;
76         else cout << "-1" << endl;
77     }
78 }
原文地址:https://www.cnblogs.com/zyb993963526/p/6516286.html