康托展开
int cantor(int *a,int n)
{
int ans=0;
for(int i=0;i<n;i++)
{
int x=0;int c=1;m=1;//c记录后面的阶乘
for(int j=i+1;j<n;j++)
{
if(a[j]<a[i])
{
x++:
}
m*=c;c++;
}
ans+=x*m;
}
return ans;
}
逆康托展开
static const int FAC[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; // 阶乘
void decantor(int x, int n)
{
vector<int> v; // 存放当前可选数
vector<int> a; // 所求排列组合
for(int i=1;i<=n;i++)
{
v.push_back(i);
}
for(int i=m;i>=1;i--)
{
int r = x % FAC[i-1];
int t = x / FAC[i-1];
x = r;
sort(v.begin(),v.end());// 从小到大排序
a.push_back(v[t]); // 剩余数里第t+1个数为当前位
v.erase(v.begin()+t); // 移除选做当前位的数
}
}
1173

被折叠的 条评论
为什么被折叠?



