康拓展开模板
#include<iostream>
using namespace std;
int fac[] = {1,1,2,6,24,120,720,5040,40320}; //i的阶乘为fac[i]
/* 康托展开.
{1...n}的全排列由小到大有序,s[]为第几个数 */
int KT(int n, int s[])
{
int i, j, t, sum;
sum = 0;
for (i=0; i<n; i++)
{
t = 0;
for (j=i+1; j<n; j++)
if (s[j] < s[i])
t++;
sum += t*fac[n-i-1];
}
return sum;
}
int main()
{
int s[]={4,2,1,3};
cout<<KT(4,s)<<endl;
return 0;
}
康拓逆展开模板(构造第n个排列)
#include<iostream>
using namespace std;
int fac[] = {1,1,2,6,24,120,720,5040,40320}; //i的阶乘为fac[i]
/* 康托展开的逆运算.
{1...n}的全排列,中的第k个数为s[] */
void invKT(int n, int k,int s[])
{
int i, j, t, sum,vis[20]={0};
for (i=0; i<n; i++)
{
t = k/fac[n-i-1];
for(int j=1;j<=n;j++)
{
if(!vis[j])
{
if(t==0)
{
s[i]=j;
vis[j]=1;
break;
}
t--;
}
}
k%=fac[n-1-i];
}
}
int main()
{
int s[]={4,2,1,3,1};
invKT(5,15,s);
for(int i=0;i<5;i++) cout<<s[i]<<" ";
cout<<endl;
return 0;
}