康托展開 全排列

2021-07-11 16:33:13 字數 1261 閱讀 6067

對於n個數的全排列,共有n!中排列方式,如何求某乙個序列在整個排列中的次序(從小到大)?

以9的全排枚舉例:842697513是1-9全排列的第幾個?(高中數學排列組合問題,只需要做到不重不漏)

首先看第一位為8,那麼第一位為1-7的全排列都比它小,共有7*8!個。

在第一位為8的情況下,其次看第二位為4,那麼第二位為1-3的全排列都比它小,共有1*3*7!個。

在第一位為8,第二位為4的情況下,那麼第三位為1的全排列都比它小,共有1*1*6!個。

在第一位為8,第二位為4,第三位為2的情況下,那麼第四位為1-5的全排列都比它小,這裡由於第二位4和第三位2已經確定,第四位的可能取值只能為(1,3,5),共有1*1*1*3*5!

在第一位為8,第二位為4,第三位為2,第四位為6的情況下,那麼第五位為1-8的全排列都比它小,這裡由於第二位為4,第三位為2,第四位為6已經確定,第五位的可能取值只能為(1,3,5,7),共有1*1*1*1*4*4!

對於第i位的可能取值,前i位的數字已經確定,且在全排列中每乙個數字只能出現一次,只需要比較i位後面的數字比i位數字小的有幾個,即可知道第i位的可能取值。

總結上面的方法,計算1-n的全排列

a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[2]*1!+a[1]*0!

其中a[i]表示,在當前未出現的數字中,a[i]為第幾大的數字(從0開始),並且0<=a[i]。

康托展開原公式:

把乙個整數x展開成如下形式:

x=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[2]*1!+a[1]*0!

其中a[i]為當前未出現的元素中是排在第幾個(從0開始),並且0<=a[i]可以把康托展開理解為一種hash方式。

實現**:

#include #include using namespace std;

long int factory=;//階乘表

long contor(char str, int n)

result += counted*factory[n-i-1];

}return result+1; //從0開始

}int main()

康托展開 全排列

今天找到了一篇非常好的介紹康托展開的文章!其核心是這一張圖 letter 儲存所需字母表 void initletter 初始化字母表 int fact int n 階乘 return result void output vector v 輸出生成的結果 cout endl void divisi...

全排列康托展開

n個元素有n 個不同的排列。將這n 個排列按字典序排列,並編號為0,1,n 1。每個排列的編號為其字典序值。例如,當n 3時,6 個不同排列的字典序值如下 0 1 2 3 4 5 123 132 213 231 312 321 任務 給定n 以及n 個元素的乙個排列,計算出這個排列的字典序值,以及按...

全排列 康托展開

includeusing namespace std int num 100 cnt void fun int pos,int n int judge int l,int r int main int judge int l,int r void fun int pos,int n for int ...