标签:des style io os ar for div sp art
3 3 1 2 2 1 5 1 1 4 3 1 3 2 2 5 1 1 4 3 1 4 2 3 5 1 1 4
Case #1: 101.3099324740 Case #2: 90.0000000000 Case #3: 78.6900675260 题意:给你n栋楼,每栋楼有高度和坐标,现在询问你人站在某个位置,能看到的天空的角度 思路:将询问的人和楼组合在一起,排序后,维护一个凸的高度下降的单调栈(可以动手画一下),然后每次查询到人的位置的时候,维护单调栈,使得图形是凸的,那么栈首和这个人就能构成答案了,还有是楼的时候也要维护这个栈,那么前后各遍历一次,就能通过正切值求解了#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath> typedef __int64 ll; using namespace std; const double PI = acos(-1.0); const int maxn = 100005; struct Node { int x, h; bool operator <(const Node &a)const { return x < a.x; } } node[maxn<<2], stk[maxn<<2]; double ans[maxn]; int n, q; int check(Node &a, Node &b, Node c) { if (c.h <= 0) c.h = 0; return (ll)(a.h - c.h) * (c.x - b.x) >= (ll)(b.h - c.h) * (c.x - a.x); } double getAngle(Node a, Node b) { return atan((double)(b.x-a.x)/(double)(a.h)); } void cal() { int head = 0; for (int i = 0; i < n+q; i++) { if (node[i].h <= 0) { while (head >= 2 && check(stk[head-2], stk[head-1], node[i])) head--; ans[-node[i].h] += getAngle(stk[head-1], node[i]); } else { while (head && stk[head-1].h <= node[i].h) head--; while (head >= 2 && check(stk[head-2], stk[head-1], node[i])) head--; stk[head++] = node[i]; } } } int main() { int t, cas = 1; scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d%d", &node[i].x, &node[i].h); scanf("%d", &q); for (int i = 0; i < q; i++) { scanf("%d", &node[i+n].x); node[i+n].h = -i; } memset(ans, 0, sizeof(ans)); sort(node, node+n+q); cal(); reverse(node, node+n+q); for (int i = 0; i < n+q; i++) node[i].x = 10000000 - node[i].x; cal(); printf("Case #%d:\n", cas++); for (int i = 0; i < q; i++) printf("%.10lf\n", ans[i] * 180.0 / PI); } return 0; }
标签:des style io os ar for div sp art
原文地址:http://blog.csdn.net/u011345136/article/details/39454537