http://www.cnblogs.com/keam37/p/3637717.html  keam所有 转载请注明出处

Problem Description

We can number binary trees using the following scheme:

我们用下面的规则来给一颗二叉树编号:
The empty tree is numbered 0.

空树编号为0。
The single-node tree is numbered 1.

只有一个节点的树编号为1。
All binary trees having m nodes have numbers less than all those having m+1 nodes.

所有m个节点的树的编号不会大于有m+1个节点的树的编号。
Any binary tree having m nodes with left and right subtrees L and R is numbered n such that all trees having m nodes numbered > n have either
Left subtrees numbered higher than L, or A left subtree = L and a right subtree numbered higher than R.

任意一个编号为n,有m个节点,左右子树节点分别为L和R的二叉树。当一棵树的编号>n,不是该树的左子树的编号大于L,就是左子树编号相同,右子树编号大于R;
The first 10 binary trees and tree number 20 in this sequence are shown below:

前10颗二叉树和第20颗树如下所示:

Your job for this problem is to output a binary tree when given its order number.

你的任务是依据给定编号,输出一颗树.

Input

Input consists of multiple problem instances. Each instance consists of a single integer n, where 1 <= n <= 500,000,000. A value of n = 0 terminates input. (Note that this means you will never have to output the empty tree.)

Output

For each problem instance, you should output one line containing the tree corresponding to the order number for that instance. To print out the tree, use the following scheme:
A tree with no children should be output as X.
A tree with left and right subtrees L and R should be output as (L')X(R'), where L' and R' are the representations of L and R.
If L is empty, just output X(R').
If R is empty, just output (L')X.

Sample Input

1

20

31117532 0

Sample Output

X

((X)X(X))X

(X(X(((X(X))X(X))X(X))))X(((X((X)X((X)X)))X)X)

 

分析:

要打印这颗树,首先要确定树的节点数。

先用递推计算n个节点的树有多少颗,就能得到节点小于k的树一共有Sum[k],这样对于输入的编号n

总的第n棵树,就是有k个节点的第(n-sum[k-1])棵树.

再确定左右子树分别是总的第几棵树,再递归即可

参考代码

#include <iostream>
using namespace std;
//定义0个节点时有1种二叉树,用于递推
int radix[20] = {1};
int sRadix[20];
//递归求k个节点的第n颗树
int make (int n, int k)
{
//只有一个节点时直接输出'X'
if (k == 1) {
cout << 'X';
return 0;
}
//nL,nR代表左右子树的节点个数,sL,sR代表左右子树分别是当前节点数的第几颗树
int nL = 0, sL = 0, nR = k - 1, sR = n;
//如果sR>nR个节点最多二叉树的种数,左子树序号+1,p帮助累计左子树节点
for (int p = 0; radix[nR] < sR; sL++) {
sR -= radix[nR];
if (p) p--;
//如果p==0,左子树节点数+1,右节点数-1,更新p为nL个节点的左子树的种数-1
else {
nL++, nR--;
p = radix[nL] - 1;
}
}
//递归子树时为子树加上括号
if (nL > 0) {
cout << '('; make (sL - sRadix[nL - 1], nL);
cout << ')';
}
cout << 'X';
if (nR > 0) {
cout << '('; make (sR, nR);
cout << ')';
}
return 0;
}
int main()
{
int n, k;
//递推,求出radix[i]。代表i个节点的二叉树有几种
for (int i = 1; i <= 18; i++) {
for (int j = 0; j <= (i - 1) / 2; j++)
radix[i] += radix[j] * radix[i - j - 1] * 2;
if (~ (i - 1) & 1) radix[i] -= radix[ (i - 1) / 2] * radix[ (i - 1) / 2];
//sRadix数组方便求出第N颗数有几个节点
sRadix[i] = sRadix[i - 1] + radix[i];
}
while (cin >> n && n) {
for (k = 1; sRadix[k] < n; k++);
make (n - sRadix[k - 1], k);
cout<<endl;
}
return 0;
}

HDU.P1100 Trees Made to Order 解题报告的更多相关文章

  1. 【LeetCode】1030. Matrix Cells in Distance Order 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 排序 日期 题目地址:https://leetcod ...

  2. 【LeetCode】950. Reveal Cards In Increasing Order 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 模拟 日期 题目地址:https://leetcod ...

  3. hdu 1002.A + B Problem II 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1002 题目意思:就是大整数加法. 两年几前做的,纯粹是整理下来的. #include <stdi ...

  4. hdu 1004 Let the Balloon Rise 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1004 用STL 中的 Map 写的 #include <iostream> #includ ...

  5. hdu 2066 一个人的旅行 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2066 题目意思:给出T条路,和草儿家相邻的城市编号,以及草儿想去的地方的编号.问从草儿家到达草儿想去的 ...

  6. hdu 2680 Choose the best route 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2680 题目意思:实质就是给定一个多源点到单一终点的最短路. 卑鄙题---有向图.初始化map时 千万不 ...

  7. HDU 1010 temp of the bone 解题报告 (DFS)

    转载大佬的blog,很详细,学到了很多东西 奇偶剪枝:根据题目,dog必须在第t秒到达门口.也就是需要走t-1步.设dog开始的位置为(sx,sy),目标位置为(ex,ey).如果abs(ex-x)+ ...

  8. 【LeetCode】1114. Print in Order 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 mutex锁 promise/future 日期 题 ...

  9. poj 2013 Symmetric Order 解题报告

    题目链接:http://poj.org/problem?id=2013 设长度非递减的字串序列为s[1]...s[n].设计递归子程序print(n),其中n为字串序号,每分析1个字串,n=n-1. ...

随机推荐

  1. koa2实现简易的webpack-dev-server

    koa2实现简易的webpack-dev-server热更新 原文https://github.com/zhuangZhou/Blog/issues/3 闲来无事,用koa2撸了一个简易的webpac ...

  2. Prim算法以及Kruskal算法

    Prim算法主要用于计算最小生成树.算法在选取最小路径的时候需要优化,算法思路:从某个顶点开始,假设v0,此时v0属于最小生成树结点中的一个元素,该集合假设V,剩下的点待选择的点为U,然后找寻V中的点 ...

  3. 关于mapState和mapMutations和mapGetters 和mapActions辅助函数的用法及作用(一)-----mapState

    一.通过mapState函数的对象参数来赋值: <p>{{ count }}</p> <p>{{ count1 }}</p> <p>{{ c ...

  4. Html 内联元素、外联元素 和 可变元素

    块元素(block element)一般是其他元素的容器元素 块元素一般都从新行开始,它可以容纳内联元素和其他块元素,常见块元素是段落标签'P".“form"这个块元素比较特殊,它 ...

  5. print reverse <> 是打印全部的文件内容 ?

    reverse 是倒置 <> 则是 把 @ARGV  参数列表里面的文件都读取出来 ? print <> 就是和  cat 的功能一样了. 脚本语言交流.数据处理 QQ群:66 ...

  6. sql备份

    SELECT id,Name FROM TeachSite GROUP BY id select * from #temp as [type], SchoolRollID,SUM(Chargeable ...

  7. js 上传图片、压缩、旋转

    亲测 <!doctype html> <html> <head> <meta charset="utf-8"> <title& ...

  8. 「 HDU 1978 」 How many ways

    # 解题思路 记忆化搜索 一个点可以跳到的点,取决于它现在的能量.而且有一个显而易见的性质就是一条可行路径的终点和起点的横坐标之差加上纵坐标之差肯定小于等于起点的能量. 因为跳到一个点之后,能量和之前 ...

  9. 20181228 模拟赛 T3 字符串游戏 strGame 博弈论 字符串

    3  字符串游戏(strGame.c/cpp/pas) 3.1  题目描述 pure 和 dirty 决定玩 T 局游戏.对于每一局游戏,有n个字符串,并且每一局游戏由K轮组成.具体规则如下:在每一轮 ...

  10. 自动下载相对应的jar包

    一.去到需要的 maven下载地址 http://mvnrepository.com/artifact/org.apache.struts/struts2-core/2.5.13 二.然后去到 pom ...