康托展開,求某個排列在字典序排的位置

2021-07-05 12:01:53 字數 1501 閱讀 8735

遇到乙個程式設計題,考核的內容就是康托展開問題,這裡就重新描述下

x=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]為整數,並且x=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0!。這就是康托展開。康托展開可用**實現。推導過程大家有興趣可以自己去找資料,這裡我就直接拿例子來說明:

表示1,2,3,...,n的排列如 按從小到大排列一共6個。123 132 213 231 312 321 。

代表的數字 1 2 3 4 5 6 也就是把10進製數與乙個排列對應起來。

他們間的對應關係可由康托展開來找到。

如我想知道321是中第幾個小的數可以這樣考慮 :

第一位是3,當第一位的數小於3時,那

排列數小於321 如 123、 213 ,小於3的數有1、2 。所以有2*2!個。再看小於第二位2的:小於2的數只有乙個就是1 ,所以有1*1!=1 所以小於321的排列數有2*2!+1*1!=5個。所以321是第6個小的數。 2*2!+1*1!+0*0!就是康托展開。

再舉個例子:1324是排列數中第幾個大的數:第一位是1小於1的數沒有,是0個 0*3! 第二位是3小於3的數有1和2,但1已經在第一位了,所以只有乙個數2 1*2! 。第三位是2小於2的數是1,但1在第一位,所以有0個數 0*1! ,所以比1324小的排列有0*3!+1*2!+0*1!=2個,1324是第三個小數。

康托逆展開

的 全排列,並且已經從小到大排序完畢

(1)找出第96個數

首先用96-1得到95

用95去除4! 得到3餘23

有3個數比它小的數是4

所以第一位是4

用23去除3! 得到3餘5

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

用5去除2!得到2餘1

有2個數比它小的數是3,第三位是3

用1去除1!得到1餘0

有1個數比它小的數是2,第二位是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

排列的編碼 康托展開

題目大意 15,67思路 考試時居然把這道題推出來了。然後還ak了。正題 這道題要我們求出這個排列是字典序第幾大的,也就是讓我們求有多少個排列比該排列小,再加1即是答案。那麼應該如何考慮呢?舉個例子 這個排列是 考慮萬位數,有多少個數只填萬位數就肯定比它小呢?很明顯,如果必須比它小,那麼就只有萬位數...

康托展開 全排列的本質

參考鏈結 x a n n 1 a n 1 n 2 a i i 1 a 1 0 1.求乙個排列是原排列的按字典序的第幾個排列。include include using namespace std int fac 階乘 intcantor int a,int n x fac n i 1 smaller...

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

我想到了這種方法,但是不知道這就是逆康托展開,然後搜了下,如下 簡單介紹下 這個方法還是用例子來說比較好 例1 的全排列,並且已經從小到大排序完畢 1 找出第96個數 首先用96 1得到95 用95去除4 得到3餘23 用23去除3 得到3餘5 用5去除2 得到2餘1 用1去除1 得到1餘0 有3個...