Gluttony CodeForces - 892D

原题链接
考察:构造
参考官方题解的思路:
假定原序列是从小到大排序的:

\[a:1,2,3,4,5 \]

将原序列左移或者右移一位,就可以使得子序列的和不同.

\[b:2,3,4,5,1 \]

证明:
(1) 不考虑原序列最大的数,其他位上的每一位数都是\(a[i]<b[i]\),如果\(S\)内没用原序列最大值的下标,那么原序列任意一子段和都 \(<\) 现序列.
(2) 如果原序列最大值的下标在\(S\)内,那么令

\[T = \{1,2,3...,n\} \]

\[S = \{x_1,x_2,x_3...,x_k\} \]

那么\(T - S\)就是证明(1),可以发现和\(<\)现序列,那么总共的-(T-S) >现序列.

证明完毕.
  那么给定的数组\(a\)可以映射为1,2,3,4,5...按大小左移或者右移即可.

Code

#include <iostream> 
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 25;
int n,a[N],b[N];
int main()
{
   scanf("%d",&n);
   for(int i=0;i<n;i++) scanf("%d",&a[i]),b[i] = a[i];
   sort(b,b+n);
   for(int i=0;i<n;i++)
   {
   	int idx = lower_bound(b,b+n,a[i])-b;
   	printf("%d ",b[(idx+1)%n]);
   }
   printf("\n");
   return 0;
}
posted @ 2021-06-14 15:59  acmloser  阅读(34)  评论(0编辑  收藏  举报