题意:将二叉树编号,给定一个数字,求其对应的二叉树。
思路:递归。题目中蕴含了Catalan数,即结点数为n的二叉树的不同形态为第n个Catalan数。所以先筛出前几个Catalan数,然后求得n对应应该有多少个结点,并求出其在相应节点数中的序号。随后递归处理:求出其左右子树应该具有的节点个数及其在相应的结点个数下得序号。
#include <stdio.h>
#include <string.h>
long long c[20],sum[20];
int n;
void catalan(){
int i,j;
memset(c, 0, sizeof(c));
memset(sum, 0, sizeof(sum));
c[0] = c[1] = sum[1] = 1;
for(i = 2;i<20;i++){
for(j = 0;j<i;j++)
c[i] += c[j]*c[i-1-j];
sum[i] = c[i]+sum[i-1];
}
}
void solve(int x,int num){
int i,j,t = 0,a,b;
if(x == 1){
printf("X");
return;
}
for(i = 0;i<x;i++){
t += c[i]*c[x-1-i];
if(num <= t)
break;
}
t = c[i]*(c[x-1-i])-(t-num);
a = (t-1)/c[x-1-i]+1;
b = (t-1)%c[x-1-i]+1;
if(i){
printf("(");
solve(i,a);
printf(")");
}
printf("X");
if(i<x-1){
printf("(");
solve(x-1-i, b);
printf(")");
}
}
int main(){
catalan();
while (scanf("%d",&n) && n){
int i;
for(i = 1;i<20;i++){
if(n<=sum[i])
break;
}
solve(i,n-sum[i-1]);
printf("\n");
}
return 0;
}