这道题一个容易思考的思路是把所有的排列都存储下来,但是由于最大的数组长度是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;
}
}

posted on 2010-04-06 14:08  梦涵  阅读(435)  评论(0编辑  收藏  举报