-
Notifications
You must be signed in to change notification settings - Fork 1
/
at_abc139_f.cpp
72 lines (55 loc) · 1.63 KB
/
at_abc139_f.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#if 0
2019.09.02
首先有两个需要感性理解的结论:
1) 选择的向量的极角是连续的,不存在一个未选的向量夹在选了的向量中间。
2) 选择的向量一定在一条直线的一侧。
那么把向量按极角排序,然后复制一遍成环,于是选择的向量一定是长度不超过 n 的连续区间。
枚举左端点,最远右端点是可以尺取的,而且只需要考虑尺取中更新的向量和。
因为每次左端点 l 右移,相当与添了一条与 V[l] 相反的向量,
由结论 1) 可知最优解的右端点不会再往左移。
#endif
#include <cstdio>
#include <algorithm>
#include <cmath>
#define debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long lolong;
inline int input() { int x; scanf("%d", &x); return x; }
const int maxn = 100005;
struct Dot {
int x, y;
double a;
};
Dot d[maxn << 1];
inline bool cmp(Dot a, Dot b) {
return a.a < b.a;
}
int main() {
int n = input();
for(int i = 1; i <= n; i ++) {
d[i].x = input();
d[i].y = input();
d[i].a = atan2(d[i].y, d[i].x) + M_PI;
}
std::sort(d + 1, d + n + 1, cmp);
for(int i = 1; i <= n; i ++) {
d[i + n] = d[i];
d[i + n].a += M_PI * 2;
}
lolong ans = 0;
int x = 0, y = 0;
/* for(int i = 1; i <= n * 2; i ++) */
/* debug("%d %d %lf\n", d[i].x, d[i].y, d[i].a); */
for(int l = 1, r = 0; l <= n; l ++) {
while(r + 1 < l + n and d[r + 1].a < d[l].a + M_PI) {
r ++;
x += d[r].x;
y += d[r].y;
ans = std::max(ans, 1ll * x * x + 1ll * y * y);
/* debug("%d %d\n", l, r); */
}
x -= d[l].x;
y -= d[l].y;
ans = std::max(ans, 1ll * x * x + 1ll * y * y);
}
printf("%.12lf\n", sqrt(ans));
}