当前位置:   article > 正文

Codeforces Round #698 (Div. 1) C Nezzar and Nice Beatmap_codeforces round 698 (div. 1)

codeforces round 698 (div. 1)

题目链接:https://codeforces.com/contest/1477/problem/C

C. Nezzar and Nice Beatmap

time limit per test

2 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Nezzar loves the game osu!.

osu! is played on beatmaps, which can be seen as an array consisting of distinct points on a plane. A beatmap is called nice if for any three consecutive points A,B,CA,B,C listed in order, the angle between these three points, centered at BB, is strictly less than 9090 degrees.

 

Points A,B,CA,B,C on the left have angle less than 9090 degrees, so they can be three consecutive points of a nice beatmap; Points A′,B′,C′A′,B′,C′ on the right have angle greater or equal to 9090 degrees, so they cannot be three consecutive points of a nice beatmap.

 

Now Nezzar has a beatmap of nn distinct points A1,A2,…,AnA1,A2,…,An. Nezzar would like to reorder these nn points so that the resulting beatmap is nice.

Formally, you are required to find a permutation p1,p2,…,pnp1,p2,…,pn of integers from 11 to nn, such that beatmap Ap1,Ap2,…,ApnAp1,Ap2,…,Apn is nice. If it is impossible, you should determine it.

Input

The first line contains a single integer nn (3≤n≤50003≤n≤5000).

Then nn lines follow, ii-th of them contains two integers xixi, yiyi (−109≤xi,yi≤109−109≤xi,yi≤109) — coordinates of point AiAi.

It is guaranteed that all points are distinct.

Output

If there is no solution, print −1−1.

Otherwise, print nn integers, representing a valid permutation pp.

If there are multiple possible answers, you can print any.

Example

input

Copy

  1. 5
  2. 0 0
  3. 5 0
  4. 4 2
  5. 2 1
  6. 3 0

output

Copy

1 2 5 3 4

Note

Here is the illustration for the first test:

 

 

Please note that the angle between A1A1, A2A2 and A5A5, centered at A2A2, is treated as 00 degrees. However, angle between A1A1, A5A5 and A2A2, centered at A5A5, is treated as 180180 degrees.

题意:输入n个二维点(3<=n<=5000),要求将n个点进行排序,排序后序列中任意相邻的3个点构成的角度为锐角。比如排序后的序列为A1,A2,.....Ai......An,对于任意的(1<i<n)Ai1AiAi+1<90

题解:两种方法

第一种:首先任意选择一个点加入序列,然后选择离它最远的点加入序列,这样第三点任意选择一个点构成的角度一定为锐角,我们再选离第二个点最远的点加入队列作为第三个点,以此类推,每次选择离上一个选择的点最远的点加入序列即可。

第二种:由于三角形中,最多只有一个大于等于90的角。所以我们任意选择一个点加入序列的结尾,若不满足条件,则和序列的前一个点交换,这样末尾三个点一定满足条件,然后继续判断是否满足条件,不满足条件继续往前交换,直到满足条件为止。

复杂度O(n2)

代码如下:

第一种方法:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int nn =5100;
  4. const int inff = 0x3fffffff;
  5. const double eps = 1e-8;
  6. typedef long long LL;
  7. const double pi = acos(-1.0);
  8. int n;
  9. LL x[nn],y[nn];
  10. int ans[nn];
  11. bool use[nn];
  12. int main()
  13. {
  14. cin>>n;
  15. for(int i=1;i<=n;i++)
  16. {
  17. cin>>x[i]>>y[i];
  18. }
  19. memset(use,false,sizeof(use));
  20. use[1]=true;
  21. ans[1]=1;
  22. for(int i=1;i<n;i++)
  23. {
  24. LL maxdis = -1;
  25. int choose = -1;
  26. for(int j=1;j<=n;j++)
  27. {
  28. if(use[j])
  29. continue;
  30. LL dis = (x[j]-x[ans[i]])*(x[j]-x[ans[i]])+(y[j]-y[ans[i]])*(y[j]-y[ans[i]]);
  31. if(dis > maxdis)
  32. {
  33. maxdis = dis;
  34. choose = j;
  35. }
  36. }
  37. ans[i+1]=choose;
  38. use[choose]=true;
  39. }
  40. for(int i=1;i<=n;i++)
  41. {
  42. cout<<ans[i]<<" ";
  43. }
  44. cout<<endl;
  45. return 0;
  46. }

第二种方法:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int nn =5100;
  4. const int inff = 0x3fffffff;
  5. const double eps = 1e-8;
  6. typedef long long LL;
  7. const double pi = acos(-1.0);
  8. const LL mod = (479 << 21) + 1;
  9. int n;
  10. int x[nn],y[nn];
  11. int ans[nn];
  12. bool check(int i,int j,int k)
  13. {
  14. LL v1x=x[j]-x[i];
  15. LL v1y=y[j]-y[i];
  16. LL v2x=x[k]-x[j];
  17. LL v2y=y[k]-y[j];
  18. return v1x*v2x+v1y*v2y<0;
  19. }
  20. int main()
  21. {
  22. cin>>n;
  23. for(int i=1;i<=n;i++)
  24. {
  25. cin>>x[i]>>y[i];
  26. }
  27. ans[1]=1,ans[2]=2;
  28. for(int i=3;i<=n;i++)
  29. {
  30. ans[i]=i;
  31. for(int j=i;j>=3;j--)
  32. {
  33. if(!check(ans[j-2],ans[j-1],ans[j]))
  34. {
  35. swap(ans[j],ans[j-1]);
  36. } else {
  37. break;
  38. }
  39. }
  40. }
  41. for(int i=1;i<=n;i++)
  42. {
  43. cout<<ans[i]<<" ";
  44. }
  45. cout<<endl;
  46. return 0;
  47. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/75424
推荐阅读
相关标签
  

闽ICP备14008679号