nyoj 139 我排第幾 143 第幾是誰

2021-06-19 11:59:11 字數 1603 閱讀 8133

時間限制:1000 ms  |           記憶體限制:65535 kb

難度:3

描述 現在有"abcdefghijkl」12個字元,將其所有的排列中按字典序排列,給出任意一種排列,說出這個排列在所有的排列中是第幾小的?

輸入第一行有乙個整數n(0

輸出輸出乙個整數m,佔一行,m表示排列是第幾位;

樣例輸入2

abcdefghijkl

hgebkflacdji

樣例輸出1

302715242

解析:

這道題是給出一串字母,求按字典序中的排序。

演算法:康托展開

康托展開就是一種特殊的雜湊函式,它的使用範圍是對於n個數的排列進行狀態的壓縮和儲存,是乙個

全排列到乙個

自然數的

雙射,常用於構建

雜湊表時的空間壓縮。 康托展開的實質是計算當前排列在所有由小到大全排列中的順序,因此是可逆的。

以下稱第x個全排列是都是指由小到大的順序。

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

其中,a[i]為整數,並且0<=a[i]

a[i]的意義參見舉例中的解釋部分

例如,3 5 7 4 1 2 9 6 8 展開為 98884。因為x=2*8!+3*7!+4*6!+2*5!+0*4!+0*3!+2*2!+0*1!+0*0!=98884.

解釋:排列的第一位是3,比3小的數有兩個,以這樣的數開始的排列有8!個,因此第一項為2*8!

排列的第二位是5,比5小的數有1、2、3、4,由於3已經出現,因此共有3個比5小的數,這樣的排列有7!個,因此第二項為3*7!

以此類推,直至0*0!

顯然,n位(0~n-1)全排列後,其康托展開唯一且最大約為n!,因此可以由更小的空間來儲存這些排列。由公式可將x逆推出對應的全排列。

既然康托展開是乙個雙射,那麼一定可以通過康托展開值求出原排列,即可以求出n的全排列中第x大排列。

如n=5,x=96時:

首先用96-1得到95,說明x之前有95個排列.(將此數本身減去!)

用95去除4! 得到3餘23,說明有3個數比第1位小,所以第一位是4.

用23去除3! 得到3餘5,說明有3個數比第2位小,所以是4,但是4已出現過,因此是5.

用5去除2!得到2餘1,類似地,這一位是3.

用1去除1!得到1餘0,這一位是2.

最後一位只能是1.

所以這個數是45321.

139題

**:

#include

#include

int main()

printf("%lld\n",++num);

}}

143題

**:#include

#include

int main()

for(i=0;i<12;i++)

printf("%c",c[i]+97);

printf("\n");

}return 0;}

nyoj 139 我排第幾個(康托展開)

時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 現在有 abcdefghijkl 12個字元,將其所有的排列中按字典序排列,給出任意一種排列,說出這個排列在所有的排列中是第幾小的?輸入 第一行有乙個整數n 0 輸出輸出乙個整數m,佔一行,m表示排列是第幾位 樣例輸入 3 ab...

nyoj139 我排第幾個(康拓展開)

時間限制 1000 ms 記憶體限制 65535 kb 難度 3描述 現在有 abcdefghijkl 12個字元,將其所有的排列中按字典序排列,給出任意一種排列,說出這個排列在所有的排列中是第幾小的?輸入 第一行有乙個整數n 0 輸出輸出乙個整數m,佔一行,m表示排列是第幾位 樣例輸入 3 abc...

NYOJ 139 我排第幾個(康托展開)

時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述現在有 abcdefghijkl 12個字元,將其所有的排列中按字典序排列,給出任意一種排列,說出這個排列在所有的排列中是第幾小的?輸入第一行有乙個整數n 0 輸出輸出乙個整數m,佔一行,m表示排列是第幾位 樣例輸入 3 abcd...