1、康拓展开:
一个序列长度为n,是1~n的数字的全排列中的一种,求出这个序列对应的全排列中序列的编号就是康拓展开,
即将一个全拍列的序列转化为一个数字编号。
代码:
int cantor(int a[],int n) //序列a的下标从0~n-1
{
int ans = 0;
for(int i=0;i<n;i++)
{
int x = 0,c = 1,m = 1;
for(int j=i+1;j<n;j++)
{
if(a[j]<a[i]) x++;
m *= c; c++;
}
ans += x*m;
}
return ans;
}
2、逆康拓展开
将一个数字编号转化为一个长度为n的全排列的序列,eg:x = 1时代表的序列为1 2 3 4 5,一次类推。
代码:
int fac[120],b[120];
bool vis[120];
void decantor(int x,int n)
{
fac[0] = 1;
for(int i=1;i<=n;i++) fac[i] = fac[i-1]*i,vis[i] = false;
x--;//如果从1开始
for(int j,i=0;i<n;i++)
{
int t = x/fac[n-1-i];
for(j=1;j<=n;j++)
if(vis[j] == false){
if(t == 0) break;
t--;
}
b[i] = j;
vis[j] = true;
x %= fac[n-1-i];
}
//得到b数组就是要求的序列。
}
来源:CSDN
作者:WA掘机
链接:https://blog.csdn.net/qq_41829060/article/details/104080408