您的位置:首页 > 其它

「6月雅礼集训 2017 Day8」route

2017-06-24 20:14 309 查看
【题目大意】

给出平面上$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;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: