[*][size=large]题意[/size]
中文不解释
[*][size=large]思路[/size]
首先看到题目第一个的想法就是全排列,求出提供的全排列一组数据的位置,在找出第K个位置,想起第K最小元,也可以利用快排实现。一想似乎是可行办法。
但这样就要做两件事:第一,解决如何求全排列;第二,解决如何求提供的一组数据的位置。全排列可以使用分治递归的方法。而求一组数据的位置就较为麻烦,也想到了一个递归的方法,但比较麻烦。因此不行。
因此查阅了相关的书籍,发现这是一道模拟题。其中n为1024,很大,使用递归不合理。而k<=36,较小,因此可以使用直接求下一个排列数的方法,直接求出结果。
接下来就是怎么求下一个排列为2 1 4 7 6 5 3(例子来自在线评测那本书),基本的思路是从右往左找出一个数,比后面的至少一个数小,这样的话可以交换实现数变大。例子中即为4可以与后面的比它大的数交换。要使数最小,则选择后面的数最小的一个(当然前提是大于4),即为5,然后进行交换,变为 2 1 5 7 6 4 3。然后很容易想到的就是7 6 4 3要变成最小,书里面的方法是排序,但我发现剩下的内容直接就是逆序了,因此只要进行一次逆序操作就行了,可以节省时间,有O(nlogn)变成O(n)节省了时间。
[*][size=large]总结[/size]
暂无
[*][size=large]代码[/size]
I 使用直接求下一个+逆序
(1)C
中文不解释
[*][size=large]思路[/size]
首先看到题目第一个的想法就是全排列,求出提供的全排列一组数据的位置,在找出第K个位置,想起第K最小元,也可以利用快排实现。一想似乎是可行办法。
但这样就要做两件事:第一,解决如何求全排列;第二,解决如何求提供的一组数据的位置。全排列可以使用分治递归的方法。而求一组数据的位置就较为麻烦,也想到了一个递归的方法,但比较麻烦。因此不行。
因此查阅了相关的书籍,发现这是一道模拟题。其中n为1024,很大,使用递归不合理。而k<=36,较小,因此可以使用直接求下一个排列数的方法,直接求出结果。
接下来就是怎么求下一个排列为2 1 4 7 6 5 3(例子来自在线评测那本书),基本的思路是从右往左找出一个数,比后面的至少一个数小,这样的话可以交换实现数变大。例子中即为4可以与后面的比它大的数交换。要使数最小,则选择后面的数最小的一个(当然前提是大于4),即为5,然后进行交换,变为 2 1 5 7 6 4 3。然后很容易想到的就是7 6 4 3要变成最小,书里面的方法是排序,但我发现剩下的内容直接就是逆序了,因此只要进行一次逆序操作就行了,可以节省时间,有O(nlogn)变成O(n)节省了时间。
[*][size=large]总结[/size]
暂无
[*][size=large]代码[/size]
I 使用直接求下一个+逆序
(1)C
#include "stdio.h"
#include "stdlib.h"
#define MAX 1024
int a[MAX+2];
int main()
{
int i,j,m,n,k;
int tmpi,min;
int flag;
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&n,&k);
for(i=0;i<n;i++) {scanf("%d",&a[i]);}
while(k--)
{
for(i=(n-1)-1;i>=0;i--)
{
if(a[i]<a[i+1])//存在
{
min = a[i+1];
tmpi = i+1;
for(j=i+2;j<n;j++)
{
if(a[j] > a[i] && a[j] < min) {min=a[j];tmpi = j;}
}
//swap
a[tmpi] = a[i];
a[i] = min;
break;
}
}
if(i<0)//最大
{
for(i=0;i<n;i++) a[i] = i+1;
}
else
{
/*//冒泡排序
while(++i<n)
{
flag = 0;
for(j=n-1;j>i;j--)
{
if(a[j-1]>a[j]){tmpi=a[j-1];a[j-1]=a[j];a[j]=tmpi;flag=1;}
}
if(flag==0){break;}
}*/
//逆序
j = ++i;
while(j<=(n-1+i)/2)
{
tmpi = a[j];
a[j] = a[(n-1) - (j-i)];
a[(n-1) - (j-i)] = tmpi;
j++;
}
}
}
printf("%d",a[0]);
for(i=1;i<n;i++) printf(" %d",a[i]);
putchar('\n');
}
//system("pause");
return 0;
}