康托展開和逆康托展開

2022-01-12 23:01:00 字數 2581 閱讀 8712

康托展開是乙個全排列到乙個自然數的雙射,常用於構建雜湊表時的空間壓縮。 康托展開的實質是計算當前排列在所有由小到大全排列中的順序,因此是可逆的。

解決的問題型別:有一組元素,按字典序從小排到大,在所有的組合型別中,某個組合排第幾?(從0開始排,或者說比該組合小的組合個數有多少)

公式:康托展開值x = a[n-1]*(n-1)! + a[n-2]*(n-2)! + ...... + a[i]*i! + ......+ a[1]*1! + a[0]*0! ;

a[i]為整數,表示當前未出現的元素排第幾個(從0開始排,或者說比該元素小的元素個數)。

舉例說明,有 5個元素。按字典序排列,最小的排列組合是12345,最大的排列組合是54321,計算34152的康托展開值。n=5。

第一位是3,3在未出現的元素12345這5個元素中排第3,但是從0開始排,a[4]=2;

第二位是4,4在未出現的元素1245中排第3(3已經出現過了)從0開始排,a[3]=2;

第三位是1,1在未出現的元素125中排第1(3和4已經出現過了),從0開始排,a[2]=0;

第四位是5,在未出現的元素25中,比5小的元素有1個,a[1]=1;

第五位是2,在未出現的元素2中,比2小的元素有0個,a[0]=0;

x = a[4]*4! + a[3]*3! + a[2]*2! + a[1]*1! + a[0]*0!

x = 2*4! + 2*3! + 0*2! + 1*1! +0*0! = 61

按照正常人的邏輯,從0開始排,排到61,就是所謂的62。

逆康托展開:求在所有全排列中排在第x位的組合是什麼?

舉例說明,在的排列組合中,排在第62位的是多少?

62-1=61。n=5,從(n-1)的階乘(n-1)!開始除。

61 / 4! = 2......13,說明a[4]=2,在所有未出現的元素12345中比首位小的數有2個,顯然是3

13 / 3! = 2......1,說明a[3]=2,在所有未出現的元素1245中比第二位小的數有2個,顯然是4

1  / 2! = 0......1,說明a[2]=0,在所有未出現的元素125中比第三位小的數有0個,顯然是1

1 /  1!= 1......0,說明a[1]=1,在所有未出現的元素25中比第四位小的數有1個,顯然是5

最後乙個,a[0]=0,最後乙個就是2了

所以排列組合是34152。

記憶體限制:64mb 時間限制:1000ms 

難度:3

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

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

3

abcdefghijkl

hgebkflacdji

gfkedhjblcia

1

302715242

260726926

ac**:

#include#include

#include

#include

#include

#include

using

namespace

std;

int fact[13

];string

a,s;

void f()///

列印階乘表

int num(char

b)

for(int i=0;i)

if( b==s[i] )

return0;

}int

cantor()

return

res;

}int main()///

nyoj139,康托展開

return0;

}

記憶體限制:64mb 時間限制:3000ms

難度:3

現在有"abcdefghijkl」12個字元,將其按字典序排列,如果給出任意一種排列,我們能說出這個排列在所有的排列中是第幾小的。但是現在我們給出它是第幾小,需要你求出它所代表的序列.

第一行有乙個整數n(0輸出乙個序列,佔一行,代表著第m小的序列。

複製

3

1302715242

260726926

abcdefghijkl

hgebkflacdji

gfkedhjblcia

ac**:

#include#include

#include

#include

#include

#include

using

namespace

std;

int fact[13

],x,y;

string

a,s;

void f()///

列印階乘表

void

cantor()

}int main()///

nyoj143,逆康托展開

return0;

}

康托展開 康托逆展開

x a n n 1 a n 1 n 2 a i i 1 a 1 0 其中a i 為當前未出現的元素中是排在第幾個 從0開始 這就是康托展開。康托展開可用 實現。編輯 把乙個整數x展開成如下形式 x a n n 1 a n 1 n 2 a i i 1 a 2 1 a 1 0 其中a i 為當前未出現的...

康托展開 逆康托展開

康托展開 問題 給定的全排列,計算出它是第幾個排列 求序列號 方法 康托展開 對於乙個長度為 n 的排列 num 1 n 其序列號 x 為 x a 1 n i a 2 n 2 a i n i a n 1 1 a n 0 其中a i 表示在num i 1 n 中比num i 小的數的數量 includ...

康托展開 逆康托展開

用途 康托展開是一種雙射,用於排列和整數之間的對映,可用於排列的雜湊 康托展開 公式 i n1pi i 1 sum limits p i i 1 i n 1 pi i 1 其中p ip i pi 為第i ii個數構成的逆序的個數,n為排列數的個數 例 排列 2134 i n1pi i 1 sum l...