codeforces 1477 C. Nezzar and Nice Beatmap

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;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/113407792
今日推荐