题面
题意:
输入n,k,要求构造一个序列,使1-n这些数字都出现且仅出现一次,而且满足有k个峰,(中间数大于两边的数就是峰,Ax>Ax+1&&Ax>Ax-1)
思路:
初始化数组a[n] a[i]=i,保证1-n出现,如果n是偶数,那么最多有n/2-1个峰,奇数有n/2个峰,k>最大峰,直接输出-1,否则就输出序列。
序列的输出:每次从取最后一个数(也是最大的数,用sort保证),插到前面两个小的数字中间
举例:
n=5 k=2
MaxPeeks=n/2=2<=k,所以应该构造序列
初始化1 2 3 4 5
第一次交换2和5,变成1 5 3 4 2,再sort排序后边变成1 5 2 3 4
这样就完成了把最大的数插到两个小数之间
AC代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+7;
int n,k,t;
int a[maxn];
int peeks;
//n个数(1-n) k个peek
//偶数 /2-1 奇数 /2
int main()
{
for(scanf("%d",&t);t;t--){
scanf("%d%d",&n,&k);
if(n==1&&k>=n){cout<<"-1"<<'\n';continue;}
peeks=n&1?(n/2):(n/2-1);
if(k>peeks){
cout<<"-1"<<'\n';continue;
}else{
for(int i=1;i<=n;i++)a[i]=i;
int index=2;
for(int i=0;i<k;i++){
swap(a[index],a[n]);
sort(a+index+1,a+n+1);
index+=2;
}
}
for(int i=1;i<=n;i++) printf("%d ",a[i]);
printf("\n");
}
return 0;
}
Thanks for your time!