P9578「Cfz Round 1」Permutation

思路

我们需要尽量让相邻两个数的和的最大值减最小值最小。

先思考如何让最大值最小。

对于 n,两侧最小也必须要放 12。所以最大值至少也是 n+2

同时,我们再思考 1 周围能摆什么,因为不能让最小值太小,我们需要放比较大的,也就是 nn1

这样来看的话,最小值最大是 n

所以除了 n=1 或者 n=2 的特殊情况外,我们要构造的序列的值最小是 2

再来思考一下能不能达成 2,对于大于 n2i,他的两侧可以放 ni+2ni+1。对于小于 n2i,他的两侧可以放 ni+1ni。可以验证这样摆放再处理一下 n 为偶数的特殊情况,就可以使值为 2

那么,我们在思考如何生成序列。

首先可以确定 n 的位置,在它的两侧放上 12,再在 1 旁边的空位摆上 n1,在 2 旁边的空位摆上 n2

可以发现,这种构造方式可以换一种描述方式。

先摆一个 n,然后每次在两侧加数,第 2×k1 次加数会在两侧分别加 2×k12×k,第 2×k 次加数会在两侧分别加 n2×k+1n2×k

如果最后还剩一个也就是 n 为偶数时,可以把剩下的数放在任意两端。

AC code

#include<bits/stdc++.h>
using namespace std;
int n,a,b[1000005],now,cnt=1,mi,ma,ha;
int main()
{
scanf("%d",&n),now=n,mi=1,ma=n-1,ha=ceil(1.0*n/2),b[ha]=n;//懒得算每次摆的是什么数,于是就用两个变量存一下,ha记录中间的位置
while(cnt<=(n-1)/2)
if(cnt&1) b[ha-cnt]=mi,b[ha+cnt]=mi+1,mi+=2,++cnt;
else b[ha-cnt]=ma,b[ha+cnt]=ma-1,ma-=2,++cnt;//按照上面的方法摆放数字
if(n%2==0) b[n]=mi;//n为偶数时的情况
for(int i=1;i<=n;++i) printf("%d ",b[i]);//输出
return 0;
}
posted @   One_JuRuo  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示