华师一附中OI组

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1008|回复: 2
打印 上一主题 下一主题

教授的测试(二叉树计数)

[复制链接]

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
跳转到指定楼层
楼主
发表于 2020-1-29 10:52:53 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
一年一度的研究生面试又快要来临了。为了测试学生对树结构的认识,同时也检验他们的编程能力,福州大学计算机系把面试的一项内容定为:要求学生们编程按编号顺序打印出节点个数不少于m的所有二叉树。
二叉树编号规则如下:
仅有一个节点的树编号为1。
当满足以下条件之一时,定义二叉树a的编号比b大:
   1. a的节点数比b多。
   2. 若a的节点数与b相等,且a的左子树编号比b的左子树大。
   3. a的节点数和左子树编号都和b相等,且a的右子树编号比b的右子树大。
二叉树的节点用大写X表示,例如:

当然当m较大时,检验答案对错的工作也是很繁重的,所以教授只打算对其中的若干个编号的二叉树进行抽查,他想麻烦你编制一个程序能够产生编号为n的二叉树的标准答案。
Input 输入数据由多组数据组成。每组数据仅一个整数,表示n (1≤n≤10^8)的值。输入数据以n=0表示结束,该数据不要处理。
Output 对于每组数据,输出仅一行,即你求出的标准答案。
二叉树的输出格式为:
(左子树){若左子树为空则省略}X{根}(右子树){若右子树为空则省略}
其中{…}中的内容是说明,不必输出。例如,在上图中编号为5的树可表示为X((X)X);编号为6的树表示为(X)X(X)。
Sample Input
20
0

Sample Output
((X)X(X))X


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
推荐
 楼主| 发表于 2020-1-29 11:05:45 | 只看该作者
来一组测试数据
输入
2727
45678
80270
12163
82596
53868849
66951445
95227629
98046525
1154205
0
输出
X((X((X)X))X(((X(X))X)X))
(X(X))X(X((X(X((X(X(X)))X)))X))
((((X(X))X((X)X))X((X(X))X))X)X
(X)X(X((((X((X)X))X)X(X))X))
X(X(X(X(X(X((X((X)X((X)X)))X))))))
X(X(((((X((X)X))X(X))X(X))X)X((X((X(X))X))X(X))))
X(((((X)X)X((X)X(X(X))))X)X(X(X((X)X((X(X))X)))))
(X(X))X(((X)X((X((X)X))X(X(X))))X(((X)X(X))X(X)))
((X)X)X((((X)X(X))X(X((X((X(X))X))X)))X((X)X(X)))
X(X(((X((X)X(X(((X)X)X))))X)X((X)X(X))))
回复 支持 1 反对 0

使用道具 举报

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
板凳
 楼主| 发表于 2020-1-31 11:23:50 | 只看该作者
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int catalan[18] = {1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790};
  4. int n;
  5. int nodes(int x)
  6. {
  7.         int sum = 0;
  8.         for (int i=1; i<=17; i++)
  9.         {
  10.                 sum += catalan[i];
  11.                 if (sum>x) return i;
  12.         }
  13.         return 18;
  14. }

  15. void dfs(int node,int x)
  16. {
  17.         if (node==0) return ;
  18.         if (node==1)
  19.         {
  20.                 cout<<"X";
  21.                 return ;
  22.         }
  23.         int temp_no = x;
  24.         int left = 0,right = node - 1;
  25.         while (1)
  26.         {
  27.                 int temp;
  28.                 if ((temp = catalan[left]*catalan[right])>=temp_no)
  29.                         break;
  30.                 temp_no -= temp;
  31.                 left ++;
  32.                 right --;
  33.         }
  34.         if (left>0)
  35.         {
  36.                 cout<<"(";
  37.                 dfs(left,(temp_no - 1)/catalan[right] + 1);
  38.                 cout<<")";
  39.         }
  40.         cout<<"X";
  41.         if (right>0)
  42.         {
  43.                 cout<<"(";
  44.                 dfs(right,(temp_no - 1)%catalan[right] + 1);
  45.                 cout<<")";
  46.         }
  47. }

  48. int main()
  49. {
  50.         cin>>n;
  51.         int node = nodes(n);
  52.         int temp = n;
  53.         for (int i=1; i<node; i++)
  54.                 temp -= catalan[i];
  55.         dfs(node,temp);
  56.         return 0;
  57. }
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|服务支持:DZ动力|华师一附中OI组  

GMT+8, 2024-12-26 12:49 , Processed in 0.104653 second(s), 25 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表