Editorial for Codeforces Educational 1C - Nearest Vectors
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
Trước hết sort theo độ lớn tăng dần của số đo góc tạo bởi ~\vec{v}_{i}~ ~(1 \le i \le n)~ và tia ~Ox~. Khi đó số đo góc không định hướng nhỏ nhất sẽ là góc tạo bởi ~2~ vector kề nhau (Lưu ý rằng ~\vec{v}_{n}~ kề ~\vec{v}_{1}~, ta có thể gán ~\vec{v}_{n + 1} = \vec{v}_{1}~).
Duyệt ~n~ cặp vector kề nhau, kết quả cuối cùng sẽ là ~id[\vec{v}_{i}]~ và ~id[\vec{v}_{i + 1}]~ ~(1 \le i \le n)~ với góc không định hướng giữa ~\vec{v}_{i}~ và ~\vec{v}_{i + 1}~ nhỏ nhất và ~id[\vec{v}_{i}]~ là chỉ số của ~\vec{v}_{i}~ ban đầu (trước khi sort).
Độ phức tạp: ~O(n \log n)~.
Code mẫu
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 5; const long double eps = 1e-9; int n; pair<long double, int> v[N]; bool cmp(pair<long double, int> x, pair<long double, int> y) { return x.first < y.first - eps; } int main() { ios::sync_with_stdio(0); cout.tie(0); cin.tie(0); cin >> n; for (int i = 1; i <= n; ++i) { int x, y; cin >> x >> y; v[i] = {atan2(y, x), i}; } sort(v + 1, v + n + 1, cmp); v[n + 1] = v[1]; int a = 0, b = 0; long double minAngle = 1e9; for (int i = 1; i <= n; ++i) { long double angle = v[i + 1].first - v[i].first; if (angle < 0) angle += 2 * acos(-1); if (angle < minAngle - eps) { minAngle = angle; a = v[i].second; b = v[i + 1].second; } } cout << a << ' ' << b; return 0; }
Comments