POJ 1095 解题报告

题目要求:略

思路:首先,设拥有N个结点的不同形态的有序二叉树有L[N]棵。L[N]即为卡特兰数。那么:

(1).针对这个问题先转换为输入N,求nkn表示编号为N的树所拥有的结点数。k表示这棵编号为N的树是拥有结点数为n的树的有序集合的第几棵。我们可以先将Catalan数表打出来:

int L[19]=

{1,1,2,5,14,42,132,429,1430,4862,16796,58786,208012,742900,2674440,9694845,35357670,129644790,477638700};

对于输入的N,可以求出n=min(j|L[0]+L[1]+...+L[j]>=N)。而k=n-L[0]-L[1]- ...-L[n-1]

鉴于二叉树的固有特性,我可以构造递归函数fun(n,k)。即打印出拥有n个结点树的第k种状态。

(2).继续转化问题,这棵树的左子树和右子树各有结点数多少?设这棵树左子树的结点数为i,右子树的结点数为n-i-1,那么这棵树是又左子树的结点数为i,右子树的结点数为n-i-1的形态的第几种(设为第s)?可以知道当1<=k<=L[0]*L[n-1],左子树结点树为0,右子树结点数为n-1s=kL[0]*L[n-1]+1<=k<=L[1]*L[n-2]时,,左子树结点树为1,右子树结点数为n-2s=k- L[0]*L[n-1] ...L[i-1]*L[n-i]+1<= L[i]*L[n-i+1]时,左子树结点树为i,右子树结点数为n-i-1,s= k- L[0]*L[n-1]- ... L[i-1]*L[n-i]

(3).继续想象s增长的过程即为树形态不断发生变化的过程。那么首先是右子树在发生变化,从1L[n-i-1]。继续增长,右子树的形态复位为1,而左子树的形态增加1.因此右子树相当于秒针,左子树相当于分针。对于s,该树的左子树编号为(s-1)/L[n-i-1]+1,右子树编号为(s-1)% L[n-i-1]+1

(4).fun(n,k)的递归终止条件很容易知道,为n==1。此时树的形态只有一种,所以直接打印X

(5).综上所述,fun(n,k)的形式为:

fun(n,k){

   if(1==n)打印X,返回。

   求出 s,i

   If(i>0){打印(fun(i, (s-1)/L[n-i-1]+1);打印)}

   打印X

   If(n-i-1>0) {打印(fun(n-i-1, (s-1)%L[n-i-1]+1);打印)}

}

至此,问题得到了解决。代码如下:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值