这道题一个容易思考的思路是把所有的排列都存储下来,但是由于最大的数组长度是1024,因此1024!种可能肯定超时。可以用模拟的方法找到一个比较节省时间的方法
如果有a1---an个元素,分四步
1从an开始逆序向前,直到找到一个ai,使a[i-1]<a[i]
2从a[i]向后,找到一个大于a[i-1]得元素中最小的元素a[p]
3交换a[i]与a[p]
4从第i个元素开始,对后面的元素开始排序
(特殊情况:如果已经是完全的逆序,如5,4,3,2,1,那么下一个直接为1,2,3,4,5即可)
/*
* 1833.cpp
*
* Created on: 2010-4-6
* Author: zhanghan
*/
#include<iostream>
#include<stdlib.h>
using namespace std;
//n是数组的长度,k是往后挪多少个
int compare(const void *x,const void *y)
{
return *(int *)x-*(int *)y;
}
int *pai(int *str,int k,int n)
{
int minmax=0;
int change=0;
if(k!=0)
{
int i,pos=0;
for(i=n-1;i>0;i--)
if(str[i-1]<str[i])
{
pos=i;
break;
}
if(i==0)
{
for(i=0;i<n;i++)
str[i]=i+1;
return pai(str,k-1,n);
}
else
{
minmax=str[pos];
for(i=pos+1;i<n;i++)
{
if(str[i]>str[pos-1])
{
if(str[i]<minmax)
minmax=str[i];
}
}//求出比str[pos-1]达的元素中最小的一个
for(i=n-1;i>0;i--)
if(str[i]==minmax)
{
change=i;
break;
}
int temp=0;
temp=str[pos-1];//交换位置
str[pos-1]=str[change];
str[change]=temp;
qsort(str+pos,n-pos,sizeof(int),compare);//快排可以不从数组首地址开始
return pai(str,k-1,n);
}
}
else return str;
}
int main()
{
int m;
scanf("%d",&m);
while(m--)
{
int n,k;
scanf("%d%d",&n,&k);
int a[1024]={};
int i,j;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int *p=pai(a,k,n);
for(i=0;i<n;i++)
cout<<*(p+i)<<' ';
cout<<endl;
}
}