HDOJ-1100 Trees made to order
一、题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1100
二、题目分析
对二叉树的所有形态顺序编号,编号规则是:节点数越多的编号越大;节点数相等,左子树节点数越多的越大;节点数相等,左子树节点数也相等,则依此规则比较右子树。
现给定一个正整数,依题目要求输出对应编号的二叉树形态。
三、求解思路
由题目输出格式要求,很直观地联想到使用深度优先搜索dfs,以当前二叉树对应的编号为条件,依次递归输出左子树和右子树。
1 int main(void) {
2 int n;
3 unsigned int arr[20] = {0};
4
5 init(arr, 20);
6
7 while (scanf("%d", &n) != EOF && n != 0) {
8 dfs(n, arr, 20);
9 printf("\n");
10 }
11
12 return 0;
13 }
其中arr存储的是不同节点数对应的二叉树形态数,即arr[i]表示有i个节点的二叉树总共有多少种形态。
1 void dfs(int n, unsigned int *arr, int num) {
2
3 int left, right;
4
5 if (n == 1) {
6 printf("X");
7 return ;
8 }
9
10 getChildren(&left, &right, n, arr, num);
11
12 if (left != 0) {
13 printf("(");
14 dfs(left, arr, num);
15 printf(")");
16 }
17 printf("X");
18 if (right != 0) {
19 printf("(");
20 dfs(right, arr, num);
21 printf(")");
22 }
23 }
通过getChildren得到左右子树对应的编号,然后递归搜索即可。
计算左右子树对应序号的思路:
计算总节点数nall、左子树节点数nleft和右子树节点数nright;
在计算总节点数和左子树节点数的同时,刨除所有总节点数小于nall的二叉树形态,刨除所有左子树节点数小于nleft的二叉树形态;
那么下面如何确定当前左子树是nleft个节点的二叉树中的第几个?当前右子树又是nright个节点的二叉树中的第几个?且看一例

这里假定左子树有三种形态,分别是1,2,3,右子树有两种形态,分别是a,b。额,其实有哪个节点总数对应三种二叉树形态,这里只是举例子
由这个小例子可以看出,要想确定左右子树对应的序号,需要依据右子树的形态数 ,对应的就是代码中的div,rem以及下面计算的blablabla
1 void getChildren(int *left, int *right, int n, unsigned int *arr, int num) {
2
3 int i;
4 int nall, nleft, nright;
5 int div, rem;
6
7 for (i = 1; i < num; i++) {
8 if ((unsigned)n > arr[i]) {
9 n -= arr[i];
10 } else {
11 nall = i;
12 break;
13 }
14 }
15
16 for (i = 0; i < nall; i++) {
17 if ((unsigned)n > arr[i] * arr[nall - i - 1]) {
18 n -= arr[i] * arr[nall - i - 1];
19 } else {
20 nleft = i;
21 break;
22 }
23 }
24 nright = nall - nleft - 1;
25
26 div = n / arr[nright];
27 rem = n % arr[nright];
28
29 *left = *right = 0;
30
31 if (nleft != 0) {
32 for (i = 1; i < nleft; i++) {
33 *left += arr[i];
34 }
35 *left += rem == 0 ? div : div + 1;
36
37 if (nright != 0) {
38 for (i = 1; i < nright; i++) {
39 *right += arr[i];
40 }
41 *right += rem == 0 ? arr[nright] : rem;
42 }
43 }
嗯,差不多就这些了。为什么是arr[20]?怎么计算i个节点对应的二叉树形态数?wiki一下Catalan numbers吧。
附完整代码:
1 /* http://acm.hdu.edu.cn/showproblem.php?pid=1100 */
2
3 #include <stdio.h>
4
5 void init(unsigned int *arr, int N);
6 void dfs(int n, unsigned int *arr, int num);
7 void getChildren(int *left, int *right, int n, unsigned int *arr, int num);
8
9 int main(void)
10 {
11 int n;
12 unsigned int arr[20] = {0};
13
14 init(arr, 20);
15
16 while (scanf("%d", &n) != EOF && n != 0) {
17 dfs(n, arr, 20);
18 printf("\n");
19 }
20
21 return 0;
22 }
23
24 void init(unsigned int *arr, int N)
25 {
26 int i, j;
27
28 arr[0] = arr[1] = 1;
29 for (i = 2; i < N; i++) {
30 for (j = 0; j < i; j++) {
31 arr[i] += arr[j] * arr[i - j - 1];
32 }
33 }
34 }
35
36 void dfs(int n, unsigned int *arr, int num)
37 {
38 int left, right;
39
40 if (n == 1) {
41 printf("X");
42 return ;
43 }
44
45 getChildren(&left, &right, n, arr, num);
46
47 if (left != 0) {
48 printf("(");
49 dfs(left, arr, num);
50 printf(")");
51 }
52 printf("X");
53 if (right != 0) {
54 printf("(");
55 dfs(right, arr, num);
56 printf(")");
57 }
58 }
59
60 void getChildren(int *left, int *right, int n, unsigned int *arr, int num)
61 {
62 int i;
63 int nall, nleft, nright;
64 int div, rem;
65
66 for (i = 1; i < num; i++) {
67 if ((unsigned)n > arr[i]) {
68 n -= arr[i];
69 } else {
70 nall = i;
71 break;
72 }
73 }
74
75 for (i = 0; i < nall; i++) {
76 if ((unsigned)n > arr[i] * arr[nall - i - 1]) {
77 n -= arr[i] * arr[nall - i - 1];
78 } else {
79 nleft = i;
80 break;
81 }
82 }
83 nright = nall - nleft - 1;
84
85 div = n / arr[nright];
86 rem = n % arr[nright];
87
88 *left = *right = 0;
89
90 if (nleft != 0) {
91 for (i = 1; i < nleft; i++) {
92 *left += arr[i];
93 }
94 *left += rem == 0 ? div : div + 1;
95
96 if (nright != 0) {
97 for (i = 1; i < nright; i++) {
98 *right += arr[i];
99 }
100 *right += rem == 0 ? arr[nright] : rem;
101 }
102 }
HDOJ-1100 Trees made to order的更多相关文章
- Trees Made to Order——Catalan数和递归
Trees Made to Order Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7155 Accepted: 40 ...
- POJ 1095 Trees Made to Order 最详细的解题报告
题目来源:Trees Made to Order 题目大意:根据下面的规则给一棵二叉树编号: 规则1:如果二叉树为空,则编号为0: 规则2:如果二叉树只有一个节点,则编号为1: 规则3:所有含有m个节 ...
- HDU.P1100 Trees Made to Order 解题报告
http://www.cnblogs.com/keam37/p/3637717.html keam所有 转载请注明出处 Problem Description We can number binar ...
- 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 ...
- poj 1095 Trees Made to Order 卡特兰数
这题用到了卡特兰数,详情见:http://www.cnblogs.com/jackge/archive/2013/05/19/3086519.html 解体思路详见:http://blog.csdn. ...
- poj 1095 Trees Made to Order
http://poj.org/problem?id=1095 先求出n个节点数的二叉树的形态有多少种.卡特兰数f[n]=f[n-1]*(4*n-2)/(n+1);再递归求. #include < ...
- POJ1095 Trees Made to Order(JAVA)
这题用到了卡特兰数,比较麻烦.关于卡特兰数的基本概念百度一下你就知道. 使用卡特兰数对数组元素进行分组之后,需要具体计算一下要求的是第几组的第几个数,然后向下递归. 首先来看利用卡特兰数分组: 从1开 ...
- [Swift]LeetCode894. 所有可能的满二叉树 | All Possible Full Binary Trees
A full binary tree is a binary tree where each node has exactly 0 or 2 children. Return a list of al ...
- [LeetCode] 894. All Possible Full Binary Trees 所有可能的满二叉树
A full binary tree is a binary tree where each node has exactly 0 or 2 children. Return a list of al ...
随机推荐
- C 库函数 - strstr()
定义 char *strstr(const char *haystack, const char *needle) 参数 haystack -- 要被检索的 C 字符串. needle -- 在 ha ...
- 【CSP模拟赛】坏天平(数学&思维)
蹭兄弟学校的题目做还不用自己出题的感觉是真的爽 题目描述 nodgd有一架快要坏掉的天平,这架天平右边的支架有问题,如果右边的总重量比左边多太多,天平就彻底坏掉了.现在nodgd手上有n种砝码,质量分 ...
- redis渐进式 rehash
转载(http://redisbook.com/preview/dict/incremental_rehashing.html) 上一节说过, 扩展或收缩哈希表需要将 ht[0] 里面的所有键值对 r ...
- Firefox disable search in the address bar
disable search in the address bar Hi oitconz, setting keyword.enabled to false prevents Firefox from ...
- Tosca : 把 inner text 放到变量里,定义变量,使用变量
XB的是分开取 注意颜色要变成蓝色的,才可用 上面是定义 下面是使用 键盘输入变量
- IDEA中使用Maven:通过模板项目来创建新工程(转)
首先自己有一个很完善的项目,并想通过这个项目做一个Demo事例项目: 例子1 如下图,在idea的terminal中敲入命令: mvn archetype:create-from-project 1 ...
- MacBook Pro设置外接显示器竖屏显示 切换主显示器
切换主显示器设置 有一些使用 Mac 电脑的用户,比如笔记本用户,可能会由于屏幕太小想外接一个更大的显示器,也或是有多显示输出的需求.当 Mac 电脑上有了多个显示器以后,此时便会有主副显示区之分了. ...
- 处理 Bootstrap CSS 冲突
问题: Bootstrap 是Web上最流行的CSS框架.它使创建漂亮,响应迅速的设计非常容易. 但是,有时候并不希望在整个网站上使用 Bootstrap,您只需要使用Bootstrap CSS的一部 ...
- jenkins发布程序触发shell调用python脚本刷新akamai cdn api
刷新cdn的流程:jenkins获取git中的代码,触发脚本推送到生产环境中(即cdn的源站) --> 触发脚本获取git工作目录的更新列表,将更新列表拼凑成带域名信息的url,写入到目录中 - ...
- web项目访问被拦截
如图,一启动就出现下图登录界面 原因很简单就是被拦截了.pom.xml中引入了下面的包,注释掉就可以了.当然如果用了shiro等权限框架也可能出现类似问题.谁copy进来的,盘他. <!-- h ...