1 条题解

  • 0
    @ 2025-8-24 22:49:47

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Defy_HeavenS
    世界上有两种程序员,一种是下标以0开始的,一种是下标以1开始的,我是第一种,请问我是下标为几的程序员

    搬运于2025-08-24 22:49:47,当前版本为作者最后更新于2023-08-26 19:57:43,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题意(我尽量不用太多数学式子

    定义一个函数 f({xn})f(\{x_n\}),是求一个序列相邻两项(首尾相邻)的和最大值减最小值。

    你需要构造一个元素为 11nn 的排列。使得它是所有元素为 11nn 的排列对 ff 函数求值最小的。

    思路

    观察数据范围,提示我们可以奇偶数分别考虑,暴力构造 n=3n=3n=10n=10

    奇数

    • n=3:1,3,2n=3:1 ,3 ,2
    • n=5:1,5,2,3,4n=5:1 ,5 ,2 ,3 ,4
    • n=7:1,7,2,5,4,3,6n=7:1 ,7 ,2 ,5 ,4 ,3 ,6
    • n=9:1,9,2,7,4,5,6,3,8n=9:1 ,9 ,2 ,7 ,4 ,5 ,6 ,3 ,8

    下标为奇数 正着枚举1,2,4,6,8,...1 ,2 ,4 ,6 ,8 ,...,为偶数 反着枚举3,5,7,9,...3 ,5 ,7 ,9 ,...

    可以构造数组 aaa11a_1 \leftarrow 1,其他奇数下标 aii1a_i \leftarrow i-1。下标为偶数 aini+2a_i \leftarrow n-i+2


    偶数

    • n=4:1,3,2,4n=4:1 ,3 ,2 ,4
    • n=6:1,5,3,4,2,6n=6:1 ,5 ,3 ,4 ,2 ,6
    • n=8:1,8,3,5,4,6,2,8n=8:1 ,8 ,3 ,5 ,4 ,6 ,2 ,8
    • n=10:1,9,3,7,5,6,4,8,2,10n=10:1 ,9 ,3 ,7 ,5 ,6 ,4 ,8 ,2 ,10

    对半分左边一半下标为奇数的与它们相对称的都为下标本身。

    对半分左边一半下标为偶数的与它们相对称的相加为 n+1n+1,且左边一半第一个元素为 n1n-1正着枚举 每次递减 22,右半边倒数第二个元素为 22反着枚举 每次递增 22

    *正着枚举是指从 11nn 枚举,反着枚举是指从 nn11 枚举

    可以构造数组 aa 下标为偶数 aix , ani+1n+1xa_i \leftarrow x\ ,\ a_{n-i+1}\leftarrow n+1-x,且每次 ,xx+2,x\leftarrow x+2。其余 aiia_i\leftarrow i

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,a[1000005];
    int main(){
    	cin>>n;
    	if(n%2==0){
    		for(int i=2,j=n-1;i<=n/2;i+=2,j-=2){
    			a[i]=j;
    			a[n-i+1]=n+1-j;
    		}
    		for(int i=1;i<=n;i++){
    			if(!a[i]){
    				cout<<i<<" ";
    			}else{
    				cout<<a[i]<<" ";
    			}
    		}
    	}else{
    		a[1]=1;
    		for(int i=3,j=2;i<=n;i+=2,j+=2){
    			a[i]=j;
    		}
    		for(int i=2,j=n;i<=n;i+=2,j-=2){
    			a[i]=j;
    		}
    		for(int i=1;i<=n;i++){
    			cout<<a[i]<<" ";
    		}
    	}
        return 0;
    }
    
    • 1

    信息

    ID
    8797
    时间
    1000ms
    内存
    512MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者