ABC 139
Table of Contents
https://atcoder.jp/contests/abc139
A. Tenki
https://atcoder.jp/contests/abc139/tasks/abc139_a
B. Power Socket
https://atcoder.jp/contests/abc139/tasks/abc139_b
C. Lower
https://atcoder.jp/contests/abc139/tasks/abc139_c
D. ModSum
https://atcoder.jp/contests/abc139/tasks/abc139_d
E. League
https://atcoder.jp/contests/abc139/tasks/abc139_e
F. Engines
https://atcoder.jp/contests/abc139/tasks/abc139_f
2026/1/29 解説 AC。
偏角ソートの練習として解いた。偏角ソートを実行するときに $(0, 0)$ があると sort がバグるというのを知らなかったのでなかなか苦戦した。
6
-2 -3
10 -6
0 0
0 0
9 2
-7 0
というテストケースのとき、最初に $(0, 0)$ を除外しないと sort がバグる。
原点抜いた版
9 2
-7 0
-2 -3
10 -6
原点あり版
9 2
-2 -3
10 -6
0 0
0 0
-7 0
struct Point {
long long x, y;
// 上半平面判定
int is_up() const {
if (y > 0) return 0;
if (y == 0 && x > 0) return 0;
return 1;
}
// 外積
long long cross(const Point& other) const {
return x * other.y - y * other.x;
}
// 内積
long long dot(const Point& other) const {
return x * other.x + y * other.y;
}
double norm() {
return sqrt((double)this->norm2());
}
// ノルム^2
long long norm2() const {
return x * x + y * y;
}
Point operator+(const Point& other) const {
return Point({x + other.x, y + other.y});
}
Point& operator+=(const Point& other) {
this->x += other.x;
this->y += other.y;
return *this;
}
// 偏角ソート用 comparator
// x 軸正方向から反時計回りに見たときの角度が小さい順
// (0, 0) があるとバグる
bool operator<(const Point& other) const {
int h1 = is_up();
int h2 = other.is_up();
if (h1 != h2) return h1 < h2;
return cross(other) > 0;
}
// ===== 角度計算 =====
// this と other のなす角(0〜π, ラジアン)
double angle(const Point& other) const {
double d = (double)dot(other);
double n = sqrt((double)norm2() * other.norm2());
double c = d / n;
return acos(clamp(c, -1.0, 1.0));
}
// 角度(度)
double angle_deg(const Point& other) const {
return angle(other) * 180.0 / M_PI;
}
};
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N;
cin >> N;
vector<Point> pts;
rep(i, N) {
ll x, y;
cin >> x >> y;
if (x == 0 && y == 0) continue;
pts.emplace_back(x, y);
}
sort(all(pts));
// for (auto [x, y] : pts) printf("%lld %lld\n", x, y);
N = pts.size();
rep(i, N) pts.push_back(pts[i]);
ll norm_sq = 0;
rep(i, N) {
Point now = {0, 0};
rep(j, N) {
now += pts[i + j];
chmax(norm_sq, now.norm2());
}
}
printf("%.15lf\n", sqrt((double)norm_sq));
}