[gym103055H]Grammy and HearthStone
题目即要求构造一个长为$2n$的序列$a_{i}$,满足$\forall 1\le i\le n$,$i$恰好出现两次,假设分别是$a_{x}=a_{y}=i(x<y)$,即要求$y-x=i$
(输出序列即对于所有$i$,依次输出其第一次出现的位置$x$即可)
考虑$S_{1}=\sum_{i=1}^{n}x$(定义与之前相同)和$S_{2}=\sum_{i=1}^{n}y$,满足$\begin{cases}S_{2}-S_{1}=\frac{n(n+1)}{2}\\S_{1}+S_{2}=n(2n+1)\end{cases}$,将两式相减即可解得$S_{1}=\frac{n(3n+1)}{4}\in Z$
因此,有解的必要条件即$n\equiv 0,1(mod\ 4)$
接下来,对$n$分类讨论,并构造对应$a_{i}$:
当$n=4k$,令$a_{i}$为以下序列即可——
$$
\{4k,4k-2,...,2\}\{4k-1\}\{2,4,...,4k\}\\\{2k-1\}\{4k-3,4k-5,...,2k+1\}\{2k-3,2k-5,...,3\}\\\{4k-1,2k-1\}\{3,5,...,2k-3\}\{1,1\}\{2k+1,...,4k-3\}
$$
(特别的,当$n=4$时前者构造不合法,可以令$a_{i}=\{1,1,3,4,2,3,2,4\}$)
当$n=4k+1$,令$a_{i}$为以下序列即可——
$$
\{4k+1\}\{4k-2,4k-4...,2\}\{4k\}\{2,4,...,4k-2\}\\\{2k+1,4k+1\}\{4k-1,4k-3,...,2k+3\}\{2k-1,2k-3,...,3\}\\\{4k,2k+1\}\{3,5,...,2k-1\}\{1,1\}\{2k+3,2k+5,...,4k-1\}
$$
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1000005 4 int n,a[N<<1],ans[N]; 5 void add(int x){ 6 a[++a[0]]=x; 7 } 8 int main(){ 9 scanf("%d",&n); 10 if ((n%4==2)||(n%4==3)){ 11 printf("-1"); 12 return 0; 13 } 14 if (n==4){ 15 printf("1 5 3 4"); 16 return 0; 17 } 18 if (n%4==0){ 19 int k=n/4; 20 for(int i=4*k;i>=2;i-=2)add(i); 21 add(4*k-1); 22 for(int i=2;i<=4*k;i+=2)add(i); 23 add(2*k-1); 24 for(int i=4*k-3;i>=2*k+1;i-=2)add(i); 25 for(int i=2*k-3;i>=3;i-=2)add(i); 26 add(4*k-1),add(2*k-1); 27 for(int i=3;i<=2*k-3;i+=2)add(i); 28 add(1),add(1); 29 for(int i=2*k+1;i<=4*k-3;i+=2)add(i); 30 } 31 else{ 32 int k=n/4; 33 add(4*k+1); 34 for(int i=4*k-2;i>=2;i-=2)add(i); 35 add(4*k); 36 for(int i=2;i<=4*k-2;i+=2)add(i); 37 add(2*k+1),add(4*k+1); 38 for(int i=4*k-1;i>=2*k+3;i-=2)add(i); 39 for(int i=2*k-1;i>=3;i-=2)add(i); 40 add(4*k),add(2*k+1); 41 for(int i=3;i<=2*k-1;i+=2)add(i); 42 add(1),add(1); 43 for(int i=2*k+3;i<=4*k-1;i+=2)add(i); 44 } 45 for(int i=1;i<=a[0];i++) 46 if (!ans[a[i]])ans[a[i]]=i; 47 for(int i=1;i<=n;i++)printf("%d ",ans[i]); 48 }