赞
踩
https://codeforces.com/contest/1477/problem/C
可以从一个点开始每次找最远点,证明只能脑补一下。。。
还有各种乱搞代码
这里有份随机代码,他还证明了期望两次随机得到正确的排列
- #include<bits/stdc++.h>
-
- using namespace std;
-
- typedef struct{
- long long xz;
- long long yz;
- }point;
-
- point vector_plus(point a,point b){
- point r;
- r.xz=a.xz+b.xz;
- r.yz=a.yz+b.yz;
- return r;
- }
-
- point vector_minus(point a,point b){
- point r;
- r.xz=a.xz-b.xz;
- r.yz=a.yz-b.yz;
- return r;
- }
-
- //naiseki
- long long dotproduct(point a,point b){
- return a.xz*b.xz+a.yz*b.yz;
- }
-
- //gaiseki
- long long crossproduct(point a,point b){
- return a.xz*b.yz-a.yz*b.xz;
- }
-
- int main(){
- std::random_device seed_gen;
- std::mt19937 engine(seed_gen());
-
- ios::sync_with_stdio(false);
- std::cin.tie(nullptr);
-
- int n;
- cin >> n;
- vector<point> pt(n);
- for(int i=0;i<n;i++){cin >> pt[i].xz >> pt[i].yz;}
-
- vector<int> p(n);
- for(int i=0;i<n;i++){p[i]=i;}
- while(1){
- shuffle(p.begin(),p.end(),engine);
- for(int i=2;i<(n-1);i++){
- for(int j=i;j<n;j++){
- swap(p[i],p[j]);
- if(dotproduct(vector_minus(pt[p[i-2]],pt[p[i-1]]),vector_minus(pt[p[i-1]],pt[p[i]]))<0){
- break;
- }
- }
- }
- int fl=1;
- for(int i=2;i<n;i++){
- if(dotproduct(vector_minus(pt[p[i-2]],pt[p[i-1]]),vector_minus(pt[p[i-1]],pt[p[i]]))>=0){
- fl=0;break;
- }
- }
- if(fl==1){break;}
- }
-
- for(int i=0;i<n;i++){
- if(i){cout << ' ';}
- cout << p[i]+1;
- }
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。