康托展开与逆展开(原理+模板)
生活随笔
收集整理的這篇文章主要介紹了
康托展开与逆展开(原理+模板)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
定義:
康托展開是一個全排列到一個自然數的雙射,常用于構建哈希表時的空間壓縮。 康托展開的實質是計算當前排列在所有由小到大全排列中的名次,因此是可逆的。
原理:
- 代表在位置i后面且小于的值得個數
- (n-k)!代表階乘
康托展開代碼:
const int fact[10]={1,1,2,6,24,120,720,5040,40320,362880};int cantor(int a[],int n) {int ans=0;for(int i=1;i<=n;i++){int cnt=0;for(int j=i+1;j<=n;j++)if(a[j]<a[i])cnt++;ans+=cnt*fact[n-i];}return ans; }康托逆展開:
我們以[4,2,5,1,3]為例,計算出來的康托值為82,我們該怎么用37回到序列[4,2,5,1,3]呢?
康托逆展開代碼:
const int fact[10]={1,1,2,6,24,120,720,5040,40320,362880};vector<int> decontor(int x,int n) {vector<int>ans;vector<int>num;for(int i=1;i<=n;i++)num.push_back(i);for(int i=n;i>=1;i--){int pos=x/fact[i-1];x%=fact[i-1];ans.push_back(num[pos]);num.erase(num.begin()+pos);}return ans; }?
?
總結
以上是生活随笔為你收集整理的康托展开与逆展开(原理+模板)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU - 1043 Eight(bfs
- 下一篇: AcWing - 171 送礼物(双向d