康拓展開 快速找到某個數在全排序中的位置

2021-09-25 12:36:56 字數 989 閱讀 2022

寫了道題,經典的eight題目,就推數字的問題。

然後裡面用到了康拓展開來優化。

後面講題先來講康拓展開

剛開始演算法練習的時候,最害怕跟全排序有關的問題,因為當時不是很懂遞迴,也不是很會搜尋,就很害怕。。

扯遠了。我們來講康拓排序。

康拓排序更像是當初我們學的數論裡面的乙個只是點,其實他就是小的全排列和數的相乘法,並不難懂。

先來看個例題,比如給你5個數字1,2,3,4,5;

問你第23個全排列數是多少?

我們來一位一位的考慮

最左邊這位,即最高位。他如果從1開始變化,如果它想要增加1,那我們的全排列數要排列多少次呢?很顯然4! = 16次。 所以我們先 23 / 4! = 1······7,即我們第乙個數字增加了1,而且後面的數字還進行了7次全排列。那麼第乙個數字是2

第二個數字是什麼呢?和第乙個數字求取一樣 7 / 3! = 1······1, 第二個數字是3

依次類推,第三個數字是1,然後是4, 5.

所以第23個數字就是23145

同理反推,如果給你乙個數字23145,怎麼算他是第幾個

要看每一位數字是這群數字總第幾小。

第一位2,後面只有乙個1比他小,說明第一位進了一下,這裡要加乙個4!* 1

第二位3,後面也只有乙個1比他小,說明進了一下,這裡要加乙個3! * 1

依次類推

ans = 4! + 3! + 0! = 23

int

cantor

(int

*arr)

ans = ans + fac[

9-i-1]

* t;

}return ans +1;

}//這裡 fac表示乙個陣列,裡面存著從0開始到9的階乘數

//查表讓程式更快

然後最後給出題目,其實有了這個優化,其他部分就是一些陣列的轉化和普通的bfs。

a-eight

康拓展開和逆康拓展開

康托展開就是一種特殊的雜湊函式 把乙個整數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進...

康拓展開與逆康拓展開

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

康拓展開和逆康拓展開

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