看出来是单调栈维护斜率,但是不会写,2333,原来是和询问放在一起的
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 #include <cmath> 7 typedef __int64 ll; 8 using namespace std; 9 10 const double PI = acos(-1.0); 11 const int maxn = 100005; 12 13 struct Node { 14 int x, h; 15 bool operator <(const Node &a)const { 16 return x < a.x; 17 } 18 } node[maxn<<2], stk[maxn<<2]; 19 double ans[maxn]; 20 int n, q; 21 22 int check(Node &a, Node &b, Node c) { 23 if (c.h <= 0) 24 c.h = 0; 25 return (ll)(a.h - c.h) * (c.x - b.x) >= (ll)(b.h - c.h) * (c.x - a.x); 26 } 27 28 double getAngle(Node a, Node b) { 29 return atan((double)(b.x-a.x)/(double)(a.h)); 30 } 31 32 void cal() { 33 int head = 0; 34 for (int i = 0; i < n+q; i++) { 35 if (node[i].h <= 0) { 36 while (head >= 2 && check(stk[head-2], stk[head-1], node[i])) 37 head--; 38 ans[-node[i].h] += getAngle(stk[head-1], node[i]); 39 } 40 else { 41 while (head && stk[head-1].h <= node[i].h) 42 head--; 43 while (head >= 2 && check(stk[head-2], stk[head-1], node[i])) 44 head--; 45 stk[head++] = node[i]; 46 } 47 } 48 } 49 50 int main() { 51 int t, cas = 1; 52 scanf("%d", &t); 53 while (t--) { 54 scanf("%d", &n); 55 for (int i = 0; i < n; i++) 56 scanf("%d%d", &node[i].x, &node[i].h); 57 scanf("%d", &q); 58 for (int i = 0; i < q; i++) { 59 scanf("%d", &node[i+n].x); 60 node[i+n].h = -i; 61 } 62 63 memset(ans, 0, sizeof(ans)); 64 sort(node, node+n+q); 65 66 cal(); 67 68 reverse(node, node+n+q); 69 for (int i = 0; i < n+q; i++) 70 node[i].x = 10000000 - node[i].x; 71 72 cal(); 73 74 printf("Case #%d:\n", cas++); 75 for (int i = 0; i < q; i++) 76 printf("%.10lf\n", ans[i] * 180.0 / PI); 77 } 78 return 0; 79 }
时间: 2024-11-11 00:13:57