康拓展開和逆展開

2021-07-01 19:18:21 字數 1413 閱讀 3576

康托展開其實就是乙個解決問題的數學公式,因為這個公式是德國的數學家康托爾發明的,所以以他的名字命名為康托展開。

給定乙個整數x,根據康托展開的公式,我們可以把這個x展開為:x=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0!   

x = 2*6!+3*5!+4*4!+3*3!+1*2!+0*0! 那 x 代表什麼意義呢?  

接下來我們再看x代表的意義,說到x就必須說到康托展開究竟有什麼用,究竟在**能用到,應該怎麼用的問題。

康托展開所要解決的問題就是關於序列的問題:給定乙個序列,如:123,它有六種排列方式 123 ,132 ,213 ,231, 312 ,321 我們把這六個數按從小到大的順序進行排列 ,然後給其中的乙個數,求此數前面還有幾個數(也就是有幾個數比此數小),我們就可以用康托展開來求,而且給乙個數,可以求排名此數字的序列式什麼(康托逆展開)。

#includeint p=;

int kangtuo(int *s,int n)

sum=sum+count*p[n-i-1];

} return sum;

}int main(void)

; result = kangtuo(s,n);

printf("%d\n",result);

return 0;

}
最後輸出結果為 2 ,所以在 213 前面有兩個數,所以213排在第三位。

所謂康托的逆展開就是知道排名求序列

用乙個例子解釋其中的原理:

例: 的

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

(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

#include using namespace std;

void cantorreverse(int index,int *p,int n); //康托展開逆用,判斷給定的位置中的排列

long int fac=; //表示階乘運算的結果

//long int fac=;

int main(int argc,char *argv)

組成的所有排列中,求出第96個排列的順序

for(int i=0;i

(如有問題,敬請指出,共同學習,不勝感激)!

康拓展開和逆康拓展開

康托展開就是一種特殊的雜湊函式 把乙個整數x展開成如下形式 x a n n a n 1 n 1 a 2 2 a 1 1 其中,a為整數,並且0 a表示1,2,3,n的排列如 按從小到大排列一共6種,就是123 132 213 231 312 321 代表的數字 1 2 3 4 5 6 也就是把10進...

康拓展開和逆康拓展開

康拓展開模板題 複雜度o n 2 的會tle 看資料就知道了 雖然某題解說可以,不知道是不是後期加強了資料 然而我還是寫了o n 2 的 include typedef long long ll ll f 1000010 const ll mod 998244353 int a 1000010 b ...

康拓展開與逆康拓展開

首先解釋一下,所謂的康拓展開,就是能夠通過乙個式子,得到乙個排列在所有排列中的按字典序排好後的位次。而逆康托展開,則是給出排列的位次,能夠計算出排列是什麼。下面先給出康拓展開的公式 其中ai 為整數,並且 0 ai ai表示原數的第 i位在當前未出現的元素中是排在第幾個 康拓展開是乙個雙射,因此常用...