[CF1477C] Nezzar and Nice Beatmap - 构造

Description

给定平面直角坐标系上的 \(n\) 个点 \(A_1,A_2,\dots,A_n\) ,求一个排列 \(p_1,p_2,\dots,p_n\) 使得对于任意一个 $i\in(1,n),i\in \Z $ 都有 \(\angle A_{p_i-1} A_{p_i} A_{p_i+1} < \dfrac{\pi}{2}\) 。若无解,输出 \(-1\)

Solution

从任意一个点开始,每次选择最远的点作为下一个点

正确性利用反证法,假设形成了钝角,那么可以得出,上次选择的一定不是最远点

所以无解的情况是不存在的

#include <bits/stdc++.h>
using namespace std;

#define int long long

struct vec2
{
    int x, y;
    void read()
    {
        cin >> x >> y;
    }
    vec2 operator-(const vec2 &rhs) const
    {
        return {x - rhs.x, y - rhs.y};
    }
    int operator*(const vec2 &rhs) const
    {
        return x * rhs.x + y * rhs.y;
    }
};

signed main()
{
    ios::sync_with_stdio(false);

    int n;
    cin >> n;

    vector<vec2> p(n);
    for (int i = 0; i < n; i++)
        p[i].read();

    vector<int> v(n);
    v[0] = 1;
    int now = 0;
    cout << now + 1 << " ";
    for (int i = 1; i < n; i++)
    {
        int mx = 0, mv = 0;
        for (int j = 0; j < n; j++)
            if (v[j] == 0 && (p[now] - p[j]) * (p[now] - p[j]) > mv)
            {
                mv = (p[now] - p[j]) * (p[now] - p[j]);
                mx = j;
            }
        v[mx] = 1;
        cout << mx + 1 << " ";
        now = mx;
    }
}

相关文章: