poj 1095 Trees Made to Order
来源:互联网 发布:新华社新媒体数据库 编辑:程序博客网 时间:2024/05/22 13:47
http://blog.csdn.net/scut_lyq00/article/details/4393598
http://blog.csdn.net/lvlu911/article/details/5425974
题目要求:略
思路:首先,设拥有N个结点的不同形态的有序二叉树有L[N]棵。L[N]即为卡特兰数。那么:
(1).针对这个问题先转换为输入N,求n和k。n表示编号为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-1,s=k;L[0]*L[n-1]+1<=k<=L[1]*L[n-2]时,,左子树结点树为1,右子树结点数为n-2,s=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增长的过程即为树形态不断发生变化的过程。那么首先是右子树在发生变化,从1到L[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);打印);}
}
#include <iostream>#include <cstdio>using namespace std;const int maxn = 20;int a[maxn], b[maxn];int n;void solve(int num);int main(){a[0] = 1; b[0] = 0; a[1] = 1; b[1] = 1;for(int i = 2; i < maxn; i++){a[i] = 0;for(int j = 0; j < i; j++)a[i] += a[j] * a[i - 1 - j];b[i] = b[i - 1] + a[i];}while(true){scanf("%d", &n);if(0 == n)break;solve(n);printf("\n");}return 0;}void solve(int num){int i, j, t;if(0 == num)return;if(1 == num){printf("X");return;}for(j = 1; j < maxn; j++){if(b[j] >= num)break;}num -= b[j - 1];for(i = 0; i < j; i++){t = a[i] * a[j - 1 - i];if(num > t)num -= t;elsebreak;}if(i != 0){printf("(");solve(b[i - 1] + 1 + (num - 1) / a[j - 1 - i]);printf(")");}printf("X");if(i != j - 1){printf("(");solve(b[j - 2 - i] + 1 + (num - 1) % a[j - 1 - i]); printf(")");}}
- poj 1095--Trees Made to Order
- poj 1095 Trees Made to Order
- POJ 1095 Trees Made to Order 递归
- poj 1095 Trees Made to Order
- poj-1095-Trees Made to Order
- poj-1095-Trees Made to Order
- POJ 1095 Trees Made to Order
- POJ 1095 Trees Made to Order 笔记
- POJ 1095 Trees Made to Order(计数问题)
- 【POJ 1095】Trees Made to Order(卡特兰+递归)
- POJ 1095 Trees Made to Order 已被翻译
- Trees Made to Order
- Trees Made to Order
- ZOJ1062 Trees Made to Order
- hdu_1100 Trees Made to Order
- hdu1100 Trees Made to Order
- hdu1100:Trees Made to Order
- POJ 1095 Trees Made to Order 卡特兰数以及递归分治
- CSS属性大全
- Velocity 例子介绍
- Objective-C 类的继承、方法重载
- 一百以内的杨辉三角
- POJ 1113 Wall (凸包)
- poj 1095 Trees Made to Order
- 关于C++中的前置声明(2)
- 构造函数初始化列表
- 链接资源
- 【转】Spring3开发实战 之 第五章:Spring中的事务
- Objective-C 方法、属性
- CAKEPHP2.0变化真大啊。
- Akka框架学习中遇到的部分错误和异常及其解决方法
- PL/SQL学习一