[CF1477C] Nezzar and Nice Beatmap - 构造
Description
给定平面直角坐标系上的 (n) 个点 (A_1,A_2,dots,A_n) ,求一个排列 (p_1,p_2,dots,p_n) 使得对于任意一个 $iin(1,n),iin $ 都有 (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;
}
}