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