康拓展开
返回序列的排列数
#include<bits/stdc++.h>
#define ll long long
#define MAXN 16
using namespace std;
ll fac[MAXN];//康拓展开阶乘数
int a[MAXN];//序列
ll cantor(int n)//传长度
{
fac[0]=1;
for(int i=1;i<=n+1;i++)
fac[i]=fac[i-1]*i;
ll x=0;
for (int i=0;i<n;i++)
{
int low=0;
for(int j=i+1;j<n;j++)
{
if (a[j]<a[i])
low++;
}
x+=fac[n-i-1]*low;
}
return x+1;//返回的序号是从1开始的
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
cout<<cantor(3)<<endl;
return 0;
}
逆康拓展开
返回第k序列
#include<bits/stdc++.h>
#define ll long long
#define MAXN 16
using namespace std;
int fac[MAXN] = {1,1,2,6,24,120,720,5040,40320};
int s[MAXN];
void recantor(int n,int k)
{
int i, j, t, vst[8]={0};
--k;
for (i=0; i<n; i++)
{
t = k/fac[n-i-1];
for (j=1; j<=n; j++)
if (!vst[j])
{
if (t == 0) break;
--t;
}
s[i] = j;
vst[j] = 1;
k %= fac[n-i-1];
}
for(int i=0;i<n;i++)
printf("%d ",s[i]);
printf("\n");
}
int main()
{
int n,m,k;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%d",&s[i]);
while(m--)
{
scanf("%d",&k);
recantor(n,k);
}
return 0;
}