求排列中第k大的數--逆康託展開

我想到了這種方法,但是不知道這就是逆康託展開,然後搜了下,如下:

轉自:http://blog.csdn.net/niushuai666/article/details/6611131

簡單介紹下:

這個方法還是用例子來說比較好
例1 {1,2,3,4,5}的全排列,並且已經從小到大排序完畢
(1)找出第96個數
首先用96-1得到95
用95去除4! 得到3餘23
用23去除3! 得到3餘5
用5去除2!得到2餘1
用1去除1!得到1餘0

有3個數比它小的數是4
所以第一位是4
有3個數比它小的數是4但4已經在之前出現過了所以是5(因爲4在之前出現過了所以實際比5小的數是3個)
有2個數比它小的數是3
有1個數比它小的數是2

最後一個數只能是1
所以這個數是45321

(2)找出第16個數
首先用16-1得到15
用15去除4!得到0餘15
用15去除3!得到2餘3
用3去除2!得到1餘1
用1去除1!得到1餘0

有0個數比它小的數是1
有2個數比它小的數是3 但由於1已經在之前出現過了所以是4(因爲1在之前出現過了所以實際比4小的數是2)
有1個數比它小的數是2 但由於1已經在之前出現過了所以是3(因爲1在之前出現過了所以實際比3小的數是1)
有1個數比它小得數是2 但由於1,3,4已經在之前出現過了所以是5(因爲1,3,4在之前出現過了所以實際比5小的數是1)

最後一個數只能是2
所以這個數是14352

例題:

描述
現在有"abcdefghijkl”12個字符,將其按字典序排列,如果給出任意一種排列,我們能說出這個排列在所有的排列中是第幾小的。但是現在我們給出它是第幾小,需要

你求出它所代表的序列.

輸入
第一行有一個整數n(0<n<=10000);
隨後有n行,每行是一個整數m,它代表着序列的第幾小;

輸出
輸出一個序列,佔一行,代表着第m小的序列。

樣例輸入
3
1
302715242
260726926

樣例輸出
abcdefghijkl
hgebkflacdji
gfkedhjblcia

代碼如下:

#include <iostream>
#include <vector>

std::vector<int>fa(12);
void init(){
    fa[0]=1;
    fa[1]=1;
    fa[2]=2;
    fa[3]=6;
    fa[4]=24;
    fa[5]=120;
    fa[6]=720;
    for(int i=7;i<=11;++i)
        fa[i]=fa[i-1]*i;
}

int main (int argc,char**argv){
    init();
    int n=0;
    std::cin>>n;

    while(n-->0){
        int id=0;
        std::cin>>id;
        std::string str("abcdefghijkl");
        std::string res;
        --id;
        for(int i=11;i>=0;--i){
            int pos=id/fa[i];
            res+=str[pos];//str[pos+1-1];
            str.erase(str.begin()+pos);
            id=id%fa[i];
        }
        std::cout<<res<<std::endl;
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章