小nod 新学了快速排序,并且学会了用random函数获取随机中枢避免最坏复杂度的出现。
代码如下:
void Qsort(int a[], int low, int high)
{
if(low >= high) return;
int first = low;
int last = high;
int key_index = (rand() % (high - low + 1)) + low;
swap(a[first], a[key_index]);
int key = a[first]; /*用数组的第一个记录作为枢轴*/
while(first < last) {
while(first < last && a[last] >= key) --last;
a[first] = a[last]; /*将比第一个小的移到低端*/
while(first < last && a[first] <= key) ++first;
a[last] = a[first]; /*将比第一个大的移到高端*/
}
a[first] = key; /*枢轴记录到位*/
Qsort(a, low, first - 1);
Qsort(a, first + 1, high);
}
号称这份代码跑的比谁都快,并且到处找人炫耀。
夹克老爷 为了教育他,事先更改了测试机的环境,构造了大小为k的数组r,使得快排开始后,第i次调用rand函数时返回的是r[i%k](注意,这里的i从第0次开始),给出r数组中的k个数
你能构造一个1-N的排列让测试机上运行的快排代码递归深度最大吗?(Qsort函数的递归调用深度最大,不考虑尾递归优化)
PS:
上面这句话里的“第i次调用”是从第0次调用开始的...
也就是简单的按照从前往后循环使用r数组...
输出递归深度最大的排列中字典序最小的那个排列。
例如:
3 1
0
每次选择第0个数字作为枢轴,最大递归3层,(1,2,3)、(3,2,1)、(3,1,2)等排列都符合要求,其中字典序最小的是(1,2,3)
答案为(1,2,3)
3 1
1
每次选择第1个数字作为枢轴,最大递归3层,(2,1,3)、(3,1,2)、(1,3,2)等排列都符合要求,其中字典序最小的是(1,3,2)
答案为(1,3,2)
4 2
1 2
循环使用1、2数字作为枢轴,最大递归4层,(3,4,1,2)、(3,1,4,2)、(1,4,3,2)等排列都符合要求,其中字典序最小的是(1,4,3,2)
答案为(1,4,3,2)
输入格式
第一行两个整数N, K.(1 <= N <= 50000, 1 <= K <= 50000)。 第2 - K + 1行:每行1个数对应数组r中的元素。(0 <= r[i] <= 10^9)
输出格式
N行整数,1-N的一个排列,使得上述快排代码递归深度最大,输出其中字典序最小的那个排列。
输入样例
3 1
0
输出样例
1
2
3
#include <bits/stdc++.h>
using namespace std;
int r[50005],res[50005],ori_idx[50005],n,k;
int main(){
cin>>n>>k;
for(int i=0;i<k;i++){
cin>>r[i];
}
int min_num=1,max_num=n,min_idx=0;
for(int i=0;i<n;i++){
ori_idx[i]=i;
res[i]=-1;
}
for(int i=0;i<n;i++){
int rand_idx=min_num-1+r[i%k]%(max_num-min_num+1);
if(ori_idx[rand_idx]==min_idx){
res[min_idx]=min_num;
swap(ori_idx[rand_idx],ori_idx[min_num-1]);
++min_num;
for(;min_idx<n&&res[min_idx]>=0;)
++min_idx;
}else{
res[ori_idx[rand_idx]]=max_num;
swap(ori_idx[rand_idx],ori_idx[min_num-1]);
swap(ori_idx[max_num-1],ori_idx[min_num-1]);
--max_num;
}
}
for(int i=0;i<n;i++){
cout<<res[i]<<endl;
}
return 0;
}