【CF1343B】Balanced Array 题解

  由题意可知,我们需要构造一个满足如下性质的序列:

  - $a$的前$\frac{n}{2}$个元素是偶数
  - $a$的后$\frac{n}{2}$个元素是奇数
  - $a$的所有元素都是互不相同的正整数
  - 前半部分的和等于后半部分的和(即$\sum\limits_{i=1}^{\frac{n}{2}} a_i = \sum\limits_{i=\frac{n}{2} + 1}^{n} a_i$)

  先来讲讲如何判定无解的情况。因为题目保证$n$为偶数,所以不必担心会出现奇数序列和偶数序列长度不同,所以我们着重讨论奇数序列和偶数序列长度的奇偶性。在小学的时候,老师就教过我们:

  - 奇数加奇数等于偶数
  - 偶数加偶数等于偶数
  - 偶数加奇数等于奇数

  奇数序列和偶数序列的长度$\frac{n}{2}$,当$\frac{n}{2}$为奇数时,奇数序列的和为奇数个奇数相加,由上面列出的性质易得奇数序列的和为奇数,以此类推,偶数序列的和为偶数。奇数是不可能等于偶数的,所以当$\frac{n}{2}$为奇数的时候,是无解的,直接输出“NO”即可。而当$\frac{n}{2}$为偶数的时候,我们可得奇数序列与偶数序列的和都为偶数,所以我们就可以构造序列了!

  构造序列的主要思想是暴力,我们可以先直接拿出一个长度为$\frac{n}{2}$的偶数序列,做法有很多可以乱搞,举个例子:

  我先拿出一个长的为$\frac{n}{2}$的偶数序列:2,4,6,8 …… n,然后我们的奇数序列就要按照这个来构造,以此来满足题目要求,奇数序列前$\frac{n}{2}-1$项给它安排一下,每个元素比偶数序列对应的元素少1,也就是:1,3,5,7 …… n-3。为了让这个合并起来的序列满足前半部分的和等于后半部分的和,所以最后一项不仅仅只有n-1,还要加上整个奇数序列的和比偶数序列的和少的值,经过简单的计算得,奇数序列的最后一个元素等于$n+\frac{n}{2}-1$。感觉样例有很明显的提示这个做法

  当然,你要可以去随便构造其它的序列,但是这个思想是通用的!

贴代码:

#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<string>
#include<cstring>
#define Mod m 
#define ll long long
using namespace std;
inline int read(){ //快读,习惯使然
    int num=0,f=1;
    char rd=getchar();
    while(!isdigit(rd)){
        if(rd=='-') f=-1;
        rd=getchar();
    }
    while(isdigit(rd)){
        num=num*10+rd-48;
        rd=getchar();
    } 
    return f*num;
}
int main()
{
    int t=read(),n;
    while(t--){
        n=read(); //n为要构造的序列长度
        if((n>>1)&1){ //无解情况的判定
            printf("NO\n");
            continue;
        }
        else{
            printf("YES\n");
            for(int i=1;i<=n/2;i++) printf("%d ",i<<1);//偶数序列
            for(int i=1;i<n/2;i++) printf("%d ",(i<<1)-1);//奇数序列
            printf("%d\n",n+n/2-1);//最后一项特殊处理
        }
    }
    return 0;
}

 

posted @ 2020-04-26 21:06  明月地霜  阅读(358)  评论(0)    收藏  举报
Live2D