poj 1095 递归(Catalan)

题意:将二叉树编号,给定一个数字,求其对应的二叉树。

思路:递归。题目中蕴含了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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值