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.

Author: NoobCpp

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

Please read the guidelines before commenting.


There are no comments at the moment.