題意:給你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;
}