排列的字典序问题

排列的字典序问题

 

Time Limit:   2000MS       Memory Limit:   65535KB
Submissions:   1128       Accepted:   162

 

Description

n个元素{1,2,..., n }有n!个不同的排列。将这n!个排列按字典序排列,并编号为0,1,…,n!-1。每个排列的编号为其字典序值。例如,当n=3时,6 个不同排列的字典序值如下: 

0       1     2    3     4    5

123 132 213 231 312 321

任务:给定n 以及n 个元素{1,2,..., n }的一个排列,计算出这个排列的字典序值,以及按字典序排列的下一个排列。

 

Input

第1 行是元素个数n(n < 15)。接下来的1 行是n个元素{1,2,..., n }的一个排列。

 

Output

第一行是字典序值,第2行是按字典序排列的下一个排列。

 

Sample Input

 

8
2 6 4 5 8 1 7 3

 

Sample Output

 

8227
2 6 4 5 8 3 1 7

 

解析:

①本来可以用next_permutation函数的,但考虑到时间的复杂度,那么还是用http://www.cnblogs.com/jiangjun/archive/2012/05/20/2510748.html中借用逆序数的方法,它的原理是一位一位的累加,其实递归也行,那么还是用熟悉的for语句吧;只需要把该数的前几位乘上后面数的全排即可,每位以此类推  ②要求下一个排列,那么简单用一次next_permutation函数就得到了,代码如下:

# include<iostream>
# include<cstdio>
# include<algorithm>
using namespace std;
int solve(int num)
{
    int sign=1,i;
    for(i=1;i<=num;i++)
        sign*=i;
    return sign;
}
int main()
{
    int str[20];
    int n,sum=0,count=0,i,j;
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&str[i]);
    for(i=0;i<n-1;i++)
    {
        count=0;
        for(j=i+1;j<n;j++)
            if(str[j]<str[i])count++;//计算逆序数
        sum+=count*solve(n-i-1);//后面可能出现的情况计算
    }
    printf("%d\n",sum);
    if(next_permutation(str,str+n))
    {
        for(i=0;i<n;i++)
            printf("%d ",str[i]);
        printf("\n");
    }
        return 0;
}

 

posted on 2013-03-05 21:31  即为将军  阅读(824)  评论(0)    收藏  举报

导航