题意:给你n和k,问你能否构造出一个长为n的全排列,使得按照归并排序的执行规则,正好调动k次归并排序函数使得原排列变成递增排列。
题解:我们知道对于递减的排列,需要调用归并函数最多次,因此我们可以初始化数组为递减全排列,然后调用归并函数即可,每次让k减2(除了第一次),直到k为0,然后,让剩下的顺序即可。当然k一定要是奇数,因为除了第一次是调用一次归并函数,。其他都是2的倍数,还有就是k过大也不行。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,k,a[100005];
void merge(int l,int r)
{
if(k<=0 || l+1>=r)
{
sort(a+l,a+r);
return;
}
k-=2;
int mid=(l+r)/2;
merge(l,mid);
merge(mid,r);
}
int main(void)
{
scanf("%d%d",&n,&k);
if(k%2==0 || k>2*n)
{
printf("-1\n");
return 0;
}
k--;
for(int i=1;i<=n;i++)
a[i]=n-i+1;
merge(1,n+1);
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}