所谓康托尔展开就是形如
a[n]*n!+a[n-1]*(n-1)!+...+a[2]*2!+a[1]*1!
的和,其中a[i]为整数,且0<=a[i]<=i,i=1,2,...,n.
本算法不保存系数为0的阶乘,这样可能更直观。
#include<cstdio>
struct kte//保存阶乘及其系数
{
int x;
int jc;
};
int KTE(kte A[],int n)//康托尔展开
{
int i=1,j=0,r[11]={1},k,m;//r构造阶乘,i为其下标,j为康托尔展开下标
while(n)
{
r[i]=r[i-1]*i;
if(n<r[i])
{
i--;//复位到最接近的阶乘
while(n)
{
m=n%r[i];//获取剩余值
A[j].x=(n-m)/r[i];//系数
A[j].jc=i;//阶乘数
n=m;
k=i-1;
while(n&&k>0)//获取最接近阶乘的下标
{
if(n>=r[k])
break;
k--;
}
i=k;
j++;
}
}
i++;
}
return j;
}
int main()
{
int n;
kte A[11];
while(scanf("%d",&n)!=EOF)
{
if(!n)
{
printf("1*1!\n");
continue;
}
int len=KTE(A,n);
printf("%d*%d!",A[0].x,A[0].jc);
for(int i=1;i<len;i++)
printf("+%d*%d!",A[i].x,A[i].jc);
printf("\n");
}
return 0;
}