这题用到了卡特兰数,比较麻烦。关于卡特兰数的基本概念百度一下你就知道。

使用卡特兰数对数组元素进行分组之后,需要具体计算一下要求的是第几组的第几个数,然后向下递归。

首先来看利用卡特兰数分组:

  从1开始前4个卡特兰数是 C[1]=1, C[2]=2, C[3]=5, C[4]=14  (C[0]也是有定义的,C[0]=1)

  于是我们把第1个元素归为第1组,第2,3个元素归为第2组,4,5,6,7,8归为第3组,9到22归为第4组,这样分组就完成了

  这里的每个元素,就对应着题目里的每一棵树。而卡特兰数的下标,即树的节点数

  所以1个节点的树有1棵,2个节点的树2棵,3个节点的树5棵,4个节点的树14棵

  比如现在我们求第17棵树在第几组,17-C[1]-C[2]-C[3]=9,因为9<=C[4],所以第17棵树肯定在4个节点的树的第9个位置

然后是对卡特兰数进行递归拆分:

  由卡特兰数的性质,C[i]=C[0]*C[i-1] + C[1]*C[i-2] + ... + C[i-2]*C[1] + C[i-1]C[0]

  我们找到所在组的位置后,就要寻找向下递归的参数。

  比如我们刚才找到了第17棵树在C[4]的第9个位置,接下来要找这第9个位置的树究竟是什么

  首先,C[4]=C[0]*C[3] + C[1]*C[2]+C[2]*C[1] +C[3]*C[0],这相当于把C[4]所含的14棵树再一次进行了分组

  它使用规模更小的卡特兰数的乘积,对原先的卡特兰数进行分组,把C[4]分成C[0]*C[3]=5,C[1]*C[2]=2,C[2]*C[1]=2,C[3]*C[0]=5,一共4组

  那么第9棵树在哪呢?9-C[0]*C[3]-C[1]*C[2]=2,因为2<=C[2]*C[1],所以这第9棵树肯定在C[2]*C[1]那个分组里的第2棵

  C[2]就是左子树,由2个树节点构成。C[1]是右子树,由1个树节点构成。

  接下来应该对左右子树进行递归。递归结束条件是C[1],根据题意,找到C[1],就可以输出一个X

  但现在我们还缺少一些递归参数,右子树C[1]没问题,反正就输出X。但右子树是由2个节点构成的树,C[2]=2,所以这样的树有2棵,究竟是哪一棵?

  这里需要停下来想一想,对于这种卡特兰数形式的树来说,左子树x个节点,右子树y个节点,其内涵是什么?

    -  首先这是一棵由x+y+1个节点构成的树,对吧?

    -  其次这棵树一共有几种变化?C[x]*C[y]种

      -  比如x=2,y=3,那么这棵树一共有C[2]*C[3]=2*5=10种变化,具体来看:

        - 3个节点的右子树有5种变化,每当右子树5种变化结束之后,左子树才变化一次,我们把这样叫一轮变化。一共有C[2]=2轮,每轮5种,共2*5=10种变化  

         - 假设我们要找这10种变化里的第6种变化,那么是第几轮的第几种变化?应该是第二轮的第一种,对吧?

            - 如何用公式来表示呢?

          - 我们相当于用右子树的C[3]=5把10种变化分成了2轮,那么求第n种变化是第几轮第几种,公式为:第(n-1)/C[3]+1=轮的第(n-1)%C[3]+1种变化

          - 当n=6,(n-1)/C[3]+1=2,(n-1)%C[3]+1=1,即第2轮第1种

          - 即左子树C[2]里面的第2棵树,右子树C[3]里的第1棵树

  好了,这样我们已经找齐所有的递归参数,可以对左右子树分别进行递归。

  贴一下AC代码,JAVA版的:

import java.util.Scanner;

public class POJ1095 {

    static long[] catalan = new long[30];

    static void initCatalan(){
catalan[0]=catalan[1]=1;
for(int i=2;i<catalan.length;i++){
catalan[i] = (4*i-2)*catalan[i-1]/(i+1);
}
} // n个节点的第k种情况
static void draw(int n,long k){
if(n==0)
return;
if(n ==1){
System.out.print("X");
return;
}
// cn:去掉根节点后的节点数
int cn=n-1,leftn=0,rightn=0;
long rightc=0,leftk=0,rightk=0;
for(int i=cn;i>=0;i--){
long j = catalan[i]*catalan[cn-i];
if(j<k){
k-=j;
}else {
leftn = cn-i;
rightn = i;
rightc = catalan[i];
break;
}
}
leftk=(k-1)/rightc +1;
rightk=(k-1)%rightc +1;
if(leftn>0) {
System.out.print("(");
draw(leftn, leftk);
System.out.print(")");
}
System.out.print("X");
if(rightn>0) {
System.out.print("(");
draw(rightn, rightk);
System.out.print(")");
}
} public static void main(String[] args) {
initCatalan();
Scanner sc = new Scanner(System.in);
long c = Integer.valueOf(sc.nextLine());
int i;
while (c!=0) {
for(i=1;i<catalan.length;i++){
if(catalan[i]<c){
c-=catalan[i];
}else
break;
}
draw(i,c);
System.out.println();
c = Integer.valueOf(sc.nextLine());
}
}
}

POJ1095 Trees Made to Order(JAVA)的更多相关文章

  1. POJ 1095 Trees Made to Order 最详细的解题报告

    题目来源:Trees Made to Order 题目大意:根据下面的规则给一棵二叉树编号: 规则1:如果二叉树为空,则编号为0: 规则2:如果二叉树只有一个节点,则编号为1: 规则3:所有含有m个节 ...

  2. Trees Made to Order——Catalan数和递归

    Trees Made to Order Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7155   Accepted: 40 ...

  3. HDU.P1100 Trees Made to Order 解题报告

    http://www.cnblogs.com/keam37/p/3637717.html  keam所有 转载请注明出处 Problem Description We can number binar ...

  4. POJ 1095 Trees Made to Order(卡特兰数列)

    题目链接 中间计算的各种细节.有的细节没处理好,就wa了...主要思路就是根据卡特兰数列的: h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n&g ...

  5. poj 1095 Trees Made to Order 卡特兰数

    这题用到了卡特兰数,详情见:http://www.cnblogs.com/jackge/archive/2013/05/19/3086519.html 解体思路详见:http://blog.csdn. ...

  6. poj 1095 Trees Made to Order

    http://poj.org/problem?id=1095 先求出n个节点数的二叉树的形态有多少种.卡特兰数f[n]=f[n-1]*(4*n-2)/(n+1);再递归求. #include < ...

  7. HDOJ-1100 Trees made to order

    一.题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1100 二.题目分析 对二叉树的所有形态顺序编号,编号规则是:节点数越多的编号越大:节点数相等,左子 ...

  8. POJ题目排序的Java程序

    POJ 排序的思想就是根据选取范围的题目的totalSubmittedNumber和totalAcceptedNumber计算一个avgAcceptRate. 每一道题都有一个value,value ...

  9. ssh整合问题总结--运行项目时报java.lang.StackOverflowError(堆栈溢出)异常

    今天在整合ssh项目中,碰到一个异常,当我提交购物车数据到订单时,浏览器报了一个这样的异常. 当时,我就吓坏了.尼玛,这不是内存溢出了吗?吓得我赶紧去检查了每一个有遍历语句的代码,结果没有发现一个死循 ...

随机推荐

  1. maven标签说明

    <project xmlns="http://maven.apache.org/POM/4.0.0 " xmlns:xsi="http://www.w3.org/2 ...

  2. golang之切片

    1.切片:切片是数组的一个引用,因此切片是引用类型 2.切片的长度可以改变,因此,切片是个可变的数组. 3.切片遍历方式和数组一样,可以用len()求长度 4.cap可以求出slice最大的容量,0& ...

  3. python 类函数

    81定义: class 类名(object):# __init__(self, 参数列表):    # __init__叫构造函数,其作用:使用类实例对象时,自动调用_init_,起到对象进行初始化, ...

  4. SpringCloud之自动化配置-config

    编程开发的时候有没有觉得很多配置文件需要维护,比如,修改了数据库连接,所有用到该数据库的服务配置都得替换,是不是超级的麻烦呢 下面,给大家介绍一下Spring提供的配置自动化组件-spring clo ...

  5. 10 Consensus and Profile

    Problem A matrix is a rectangular table of values divided into rows and columns. An m×nm×n matrix ha ...

  6. XP+Android手机DIY家庭视频点播系统-历时3周全力打造吊丝的幸福生活

    需求场景(纯熟虚构): 1. 哥电脑里有200G电影copy到手机上看没那么大空间,copy一部看一部删除一部,很是不方便也费时间.     2. 小林同学需求比较旺盛但是媳妇总有不方便的时候,家里有 ...

  7. Redis数据结构(三)

    Redis五种数据类型: (1)字符串 (2)字符串列表 (3)有序字符串集合 (4)哈希 (5)字符串集合 其中(4)(5)应用最多. key命名的注意: (1)不要过长,尽量不要超过1024,会降 ...

  8. 一)get started with the Quartz project

    官网 http://www.quartz-scheduler.org/ 下载链接 http://www.terracotta.org/download/reflector.jsp?b=tcdistri ...

  9. window.location 对象

    http://www.home.com:8080/windows/location/page.html?ver=1.0&id=timlq#love 1, window.location.hre ...

  10. delphi中,write和read的用法?什么时候需要用?

    如你所说,在控件或者类的属性中,read 表示 读取,write 则表示设置.比如在类中:TTestClass = (Class)privateFOrderCode:String;publicprop ...