来源:http://acm.hdu.edu.cn/showproblem.php?pid=1100
卡特兰数的讲解:http://www.cnblogs.com/code-painter/p/4417354.html
设a[],a[i]表示i个节点能表示的二叉树数量
设b[],b[i]表示节点数小于等于i时所能表示的所有二叉树数量,既b[i]=b[i-1]+a[i]
有关二叉树数量计算,有下面的公式:
a[j]=a[0]*a[j-1]+a[1]*a[j-2]+.....+a[j-1]*a[j];
这很明显是卡特兰数的形式。
题目要求输入n
首先你得判断有几个节点,再根据上面的公式算出左右字树的n值,然后对左右字树进行递归。
代码如下:
#include<stdio.h>
#include<iostream>
using namespace std;
int a[20],b[20];
void prin(int n)
{
int i,j,t;
if(n==0)return;
if(n==1){printf("X");return;}
j=1;
while(1)
{
if(b[j]>=n)break;
j++;
}
n=n-b[j-1];
for(i=0;i<j;i++)
{
t=a[i]*a[j-1-i];
if(n>t)
{
n=n-t;
}
else break;
}
if(i!=0)
{
printf("(");
prin(b[i-1]+1+(n-1)/a[j-1-i]);
printf(")");
}
printf("X");
if(i!=j-1)
{
printf("(");
prin(b[j-2-i]+1+(n-1)%a[j-1-i]);
printf(")");
}
}
int main()
{
int n,i,j;
a[0]=a[1]=b[1]=1;
b[0]=0;
for(i=2;i<20;i++)
{
a[i]=0;
for(j=0;j<i;j++)
a[i]+=a[i-1-j]*a[j];
b[i]=b[i-1]+a[i];
}
while(scanf("%d",&n)&&n)
{
prin(n);
printf("\n");
}
return 0;
}