【题目大意】
给出平面上$n$个点,求一条连接$n$个点的不相交的路径,使得转换的方向符合所给长度为$n-2$的字符串。
$n leq 5000$
【题解】
考虑取凸包上一点,然后如果下一个是‘R',也就是向右转,那么就连到最左的点,这样下一次无论连到哪里都是向右;如果是'L',同理。
由于每次都是一个半平面,所以不会相交。
# include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long double ld; const int N = 1e5 + 10, M = 2e5 + 10; int n; struct P { int x, y; P() {} P(int x, int y) : x(x), y(y) {} friend P operator + (P a, P b) { return P(a.x+b.x, a.y+b.y); } friend P operator - (P a, P b) { return P(a.x-b.x, a.y-b.y); } friend ll operator * (P a, P b) { return - 1ll * a.y * b.x + 1ll * a.x * b.y; } friend ll operator / (P a, P b) { return 1ll * a.x * b.x + 1ll * a.y * b.y; } inline void set() { scanf("%d%d", &x, &y); } }p[M]; int ans[M], an; char str[M]; bool v[M]; int main() { // freopen("route.in", "r", stdin); // freopen("route.out", "w", stdout); cin >> n; for (int i=1; i<=n; ++i) p[i].set(); int id = 1; for (int i=2; i<=n; ++i) if(p[i].x > p[id].x) id = i; ans[++an] = id; v[id] = 1; scanf("%s", str+1); for (int i=1; i<=n-2; ++i) { for (int j=1; j<=n; ++j) if(!v[j]) { id = j; break; } for (int j=id+1; j<=n; ++j) if(!v[j]) { if(((p[id] - p[ans[i]]) * (p[j] - p[ans[i]]) > 0) ^ (str[i] == 'L')) id = j; } ans[++an] = id; v[id] = 1; } for (int i=1; i<=n; ++i) if(!v[i]) ans[++an] = i; for (int i=1; i<=n; ++i) printf("%d ", ans[i]); puts(""); return 0; }