二叉树与卡特兰数结合的一个题目。
这道题目英文关得过
Any binary tree having m nodes with left and right subtrees L and R is numbered n such that all trees having m nodes numbered > n have either Left subtrees numbered higher than L, or A left subtree = L and a right subtree numbered higher than R
题解:
每个节点的树都是从右开始生长
1.t[i]中放i个节点的卡特兰数,sum[i]中放卡特兰数的累计值。
2.判断输入的值至多多少个节点。
3.左右中,三种情况判断下。
#include <stdio.h>
int t[20];
int sum[20];
void init()
{
int i,j;
t[0]=1;
t[1]=1;
for(i=2;i<20;i++)
{
t[i]=0;
for(j=0;j<i;j++)
t[i]+=t[j]*t[i-j-1];
}
sum[1]=1;
for(i=2;i<20;i++)
sum[i]=sum[i-1]+t[i];
}
void printout(int x,int num)
{
int i,re,t1,t2;
if(x==1)
{
printf("X");
return;
}
if(x==2)
{
if(num==1)
printf("X(X)");
else
printf("(X)X");
return;
}
re=0;
for(i=0;i<x-1;i++)
{
if(re+t[i]*t[x-i-1]>=num)break;//i表明右子树节点个数
re+=t[i]*t[x-i-1];
}
if(i==0)
{
printf("X(");//右子树为空
printout(x-1-i,num-re);
printf(")");
return;
}
if(x-i-1==0)
{
printf("(");//左子树为空
printout(i,num-re);
printf(")X");
return;
}
t1=(num-re-1)/t[x-i-1]+1;//左子树与右子树各自变换个数的乘积为这棵树种类的总数,+1的原因是存在一颗子树情况,没有子树情况已经判定过
t2=(num-re)%t[x-i-1];
printf("(");
printout(i,t1);
printf(")X(");
printout(x-1-i,t2);
printf(")");
}
int main()
{
int n,i;
init();
while(scanf("%d",&n))
{
if(n==0) break;
for(i=1;;i++)if(sum[i]>=n) break;
printout(i,n-sum[i-1]);
printf("\n");
}
return 0;
}