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 }