P8976 「DTOI-4」排列 题解
P8976 「DTOI-4」排列
update 2023/2/2 添加了一个例子便于理解
题目描述
给你一个偶数
思路分析
要将长度为
在本题中,在考虑区间
为了便于理解,这里举一个例子。
1
8 23 13
一开始我们选中的是这些数:
1 2 3 4
此时
1 2 3 8
1 2 7 8
1 6 7 8
此时的
2 6 7 8 1 3 4 5
恰好满足条件。
这里需要注意,
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int t;
signed main(){
int t;
read(t);
while(t--){
int n,a,b;
read(n),read(a),read(b);
int sum=(1+n/2)*n/4;
if(sum>=a){//a选择1~n/2
if((1+n)*n/2-sum<b)printf("-1\n");
else{
for(int i=1;i<=n;i++)
printf("%d ",i);
printf("\n");
}
continue;
}
int movnum=(a-sum)/(n/2);//增加n/2的次数
if(movnum>n/2||(movnum==n/2&&(a-sum)%(n/2))){//总操作次数不能大于n/2
printf("-1\n");
continue;
}
bool vis[N]={};//标记哪些数属于前半部分
int suma=0;
for(int i=1;i<(n/2)-movnum;i++)
suma+=i,vis[i]=1;
suma+=(n/2)-movnum+(a-sum)%(n/2);
vis[(n/2)-movnum+(a-sum)%(n/2)]=1;
for(int i=(n/2)-movnum+1;i<=n/2;i++)
suma+=i+n/2,vis[i+n/2]=1;
if((1+n)*n/2-suma<b)printf("-1\n");
else{
for(int i=1;i<=n;i++)
if(vis[i])printf("%d ",i);
for(int i=1;i<=n;i++)
if(!vis[i])printf("%d ",i);
printf("\n");
}
}
return 0;
}