描述

我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串。

FBI树是一种二叉树1,它的结点类型也包括F结点,B结点和I结点三种。由一个长度为2^N的“01”串S可以构造出一棵FBI树T,递归的构造方法如下:

  1. T的根结点为R,其类型与串S的类型相同;
  2. 若串S的长度大于1,将串S从中间分开,分为等长的左右子串S1和S2;由左子串S1构造R的左子树T1,由右子串S2构造R的右子树T2。

    现在给定一个长度为2^N的“01”串,请用上述构造方法构造出一棵FBI树,并输出它的后序遍历2序列。

格式

输入格式

输入的第一行是一个整数N(0<=N<=10),第二行是一个长度为2^N的“01”串。

输出格式

输出包括一行,这一行只包含一个字符串,即FBI树的后序遍历序列。

样例1

样例输入1

3

10001011

样例输出1

IBFBBBFIBFIIIFF

限制

每个测试点1s

来源

NOIP2004普及组第三题

<br/ >

<nr/ >

解析:依据题意构造出这棵二叉树,然后后序遍历即可。

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. struct Node{
  5. char val;
  6. Node *l = NULL, *r = NULL;
  7. };
  8. string s;
  9. Node* build(const string& s)
  10. {
  11. bool flag0 = false, flag1 = false;
  12. size_t len = s.length();
  13. for(size_t i = 0; i < len; ++i){
  14. if(s[i] == '0')
  15. flag0 = true;
  16. else
  17. flag1 = true;
  18. if(flag0 && flag1)
  19. break;
  20. }
  21. char ch;
  22. if(flag0 && flag1)
  23. ch = 'F';
  24. else if(flag0)
  25. ch = 'B';
  26. else
  27. ch = 'I';
  28. Node *root = new Node;
  29. root->val = ch;
  30. if(len > 1){
  31. if(len&1){
  32. string left = s.substr(0, len/2);
  33. string right = s.substr(len/2+1);
  34. root->l = build(left);
  35. root->r = build(right);
  36. }
  37. else{
  38. string left = s.substr(0, len/2);
  39. string right = s.substr(len/2);
  40. root->l = build(left);
  41. root->r = build(right);
  42. }
  43. }
  44. return root;
  45. }
  46. void post_order(Node* root)
  47. {
  48. if(root != NULL){
  49. post_order(root->l);
  50. post_order(root->r);
  51. cout<<root->val;
  52. }
  53. }
  54. void destroy(Node* root)
  55. {
  56. if(root->l != NULL)
  57. destroy(root->l);
  58. if(root->r != NULL)
  59. destroy(root->r);
  60. delete root;
  61. }
  62. int main()
  63. {
  64. int n;
  65. cin>>n>>s;
  66. Node *root = build(s);
  67. post_order(root);
  68. destroy(root);
  69. return 0;
  70. }

<br/ >

<br/ >

顺便给出先序和中序遍历:

  1. void pre_order(Node* root)
  2. {
  3. if(root != NULL){
  4. cout<<root->val;
  5. pre_order(root->l);
  6. pre_order(root->r);
  7. }
  8. }
  1. void in_order(Node* root)
  2. {
  3. if(root != NULL){
  4. in_order(root->l);
  5. cout<<root->val;
  6. in_order(root->r);
  7. }
  8. }

<br/ >

以及它们的非递归实现:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. struct Node{
  5. char val;
  6. Node *l = NULL, *r = NULL, *p = NULL; //增加了一个字段p,用于记录他的父结点
  7. };
  8. string s;
  9. Node* build(const string& s, Node* p) //建树也做相应的更改
  10. {
  11. bool flag0 = false, flag1 = false;
  12. size_t len = s.length();
  13. for(size_t i = 0; i < len; ++i){
  14. if(s[i] == '0')
  15. flag0 = true;
  16. else
  17. flag1 = true;
  18. if(flag0 && flag1)
  19. break;
  20. }
  21. char ch;
  22. if(flag0 && flag1)
  23. ch = 'F';
  24. else if(flag0)
  25. ch = 'B';
  26. else
  27. ch = 'I';
  28. Node *root = new Node;
  29. root->val = ch;
  30. root->p = p;
  31. if(len > 1){
  32. if(len&1){
  33. string left = s.substr(0, len/2);
  34. string right = s.substr(len/2+1);
  35. root->l = build(left, root);
  36. root->r = build(right, root);
  37. }
  38. else{
  39. string left = s.substr(0, len/2);
  40. string right = s.substr(len/2);
  41. root->l = build(left, root);
  42. root->r = build(right, root);
  43. }
  44. }
  45. return root;
  46. }
  47. void pre_order2(Node* root)
  48. {
  49. Node *pre = NULL;
  50. Node *node = root;
  51. while(node != NULL){
  52. if(pre == node->p){
  53. cout<<node->val;
  54. if(node->l != NULL){
  55. pre = node;
  56. node = node->l;
  57. }
  58. else{
  59. if(node->r != NULL){
  60. pre = node;
  61. node = node->r;
  62. }
  63. else{
  64. pre = node;
  65. node = node->p;
  66. }
  67. }
  68. }
  69. else if(pre == node->l){
  70. if(node->r != NULL){
  71. pre = node;
  72. node = node->r;
  73. }
  74. else{
  75. pre = node;
  76. node = node->p;
  77. }
  78. }
  79. else if(pre == node->r){
  80. pre = node;
  81. node = node->p;
  82. }
  83. }
  84. }
  85. void in_order2(Node* root)
  86. {
  87. Node *pre = NULL;
  88. Node *node = root;
  89. while(node != NULL){
  90. if(pre == node->p){
  91. if(node->l != NULL){
  92. pre = node;
  93. node = node->l;
  94. }
  95. else{
  96. cout<<node->val;
  97. if(node->r != NULL){
  98. pre = node;
  99. node = node->r;
  100. }
  101. else{
  102. pre = node;
  103. node = node->p;
  104. }
  105. }
  106. }
  107. else if(pre == node->l){
  108. cout<<node->val;
  109. if(node->r != NULL){
  110. pre = node;
  111. node = node->r;
  112. }
  113. else{
  114. pre = node;
  115. node = node->p;
  116. }
  117. }
  118. else if(pre == node->r){
  119. pre = node;
  120. node = node->p;
  121. }
  122. }
  123. }
  124. void post_order2(Node* root)
  125. {
  126. Node *pre = NULL;
  127. Node *node = root;
  128. while(node != NULL){
  129. if(pre == node->p){
  130. if(node->l != NULL){
  131. pre = node;
  132. node = node->l;
  133. }
  134. else{
  135. if(node->r != NULL){
  136. pre = node;
  137. node = node->r;
  138. }
  139. else{
  140. cout<<node->val;
  141. pre = node;
  142. node = node->p;
  143. }
  144. }
  145. }
  146. else if(pre == node->l){
  147. if(node->r != NULL){
  148. pre = node;
  149. node = node->r;
  150. }
  151. else{
  152. cout<<node->val;
  153. pre = node;
  154. node = node->p;
  155. }
  156. }
  157. else if(pre == node->r){
  158. cout<<node->val;
  159. pre = node;
  160. node = node->p;
  161. }
  162. }
  163. }
  164. void destroy(Node* root)
  165. {
  166. if(root->l != NULL)
  167. destroy(root->l);
  168. if(root->r != NULL)
  169. destroy(root->r);
  170. delete root;
  171. }
  172. int main()
  173. {
  174. int n;
  175. cin>>n>>s;
  176. Node *root = build(s, NULL);
  177. pre_order(root);
  178. cout<<endl;
  179. pre_order2(root);
  180. cout<<endl<<endl;
  181. in_order(root);
  182. cout<<endl;
  183. in_order2(root);
  184. cout<<endl<<endl;
  185. post_order(root);
  186. cout<<endl;
  187. post_order2(root);
  188. cout<<endl<<endl;
  189. destroy(root);
  190. return 0;
  191. }

Vijos 1114 FBI树的更多相关文章

  1. 【递归】Vijos P1114 FBI树(NOIP2004普及组第三题)

    题目链接: https://vijos.org/p/1114 题目大意: 把01串一分为二,左半边描述当前节点左子树,右半边描述右子树,子树全为1则为I节点,全为0则为B节点,混合则为F节点,直到当前 ...

  2. Vijos P1114 FBI树【DFS模拟,二叉树入门】

    描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串. FBI树是一种二叉树1,它的结点类型也包括F结点,B结点和I结点三种 ...

  3. 创建FBI树

    需求:数串由2^n个'0' '1'数串组成,对于一个数串,有01混合出现,则视为F,全0数串为B,全1数串为I. 将给定数串进行切割,如10010011可以用二叉树表示为 F(10010011) / ...

  4. 蓝桥杯之FBI树问题

    问题描述 我们可以把由"0"和"1"组成的字符串分为三类:全"0"串称为B串,全"1"串称为I串,既含"0&q ...

  5. noip普及组2004 FBI树

    FBI树 描述 我们可以把由"0"和"1"组成的字符串分为三类:全"0"串称为B串,全"1"串称为I串,既含" ...

  6. [题解]ybt1365:FBI树(fbi)

    ybt1365:FBI树(fbi) [题目描述] 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串. FBI树是一种二叉树,它 ...

  7. FBI树-数据结构(二叉树)

    问题 B: [2004_p4]FBI树-数据结构 时间限制: 1 Sec  内存限制: 125 MB提交: 57  解决: 46 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称 ...

  8. C语言 · FBI树

    算法训练 FBI树   时间限制:1.0s   内存限制:256.0MB        锦囊1 二叉树. 问题描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I ...

  9. FBI树(第一次做建树题)

    试题来源 NOIP2004 普及组 问题描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串. FBI树是一种二叉树,它的结 ...

随机推荐

  1. POJ 2823 Sliding Window (线段树/单调队列)

    题目不说了,可以用线段树或者单调队列,下面附上代码. 线段树: #include <iostream> #include <stdio.h> #include <algo ...

  2. 无废话版本-Asp.net MVC4.0 Rasor的基本用法

    最近工作有点忙,好久没写东西了!废话不多说了,进入主题! 1.在页面中输出单一变量时候,只要在C#语句之前加上@符号即可,For example: <p>Now Time:@DateTim ...

  3. SDUT1466双向队列

    http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=1466&cid=1182 题目描述 想想双向链表……双向队列的定义差不多,也就是说一个队列 ...

  4. 李洪强iOS开发之keychain的使用

    通常情况下,我们用NSUserDefaults存储数据信息,但是对于一些私密信息,比如密码.证书等等,就需要使用更为安全的keychain了.keychain里保存的信息不会因App被删除而丢失,在用 ...

  5. [topcoder] EllysNumberGuessing

    http://community.topcoder.com/stat?c=problem_statement&pm=12975 简单题 #include <cstdlib> #in ...

  6. 【Linux高频命令专题(12)】touch.md

    概述 一般在使用make的时候可能会用到,用来修改文件时间,或者新建一个不存在的文件. 命令格式 touch [选项]... 文件... 命令参数 -a 或--time=atime或--time=ac ...

  7. Orcle数据库查询练习复习:三

    一.题目 1.与“张三”同乡的男生姓名 select * from student where snativeplace=(select snativeplace from student where ...

  8. JavaWeb项目开发案例精粹-第3章在线考试系统-002配置文件及辅助类

    1. <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5&qu ...

  9. 机器学习 —— 概率图模型(Homework: StructuredCPD)

    Week2的作业主要是关于概率图模型的构造,主要任务可以分为两个部分:1.构造CPD;2.构造Graph.对于有向图而言,在获得单个节点的CPD之后就可依据图对Combine CPD进行构造.在获得C ...

  10. DataGridView控件的使用---添加行

    最简单的方法 可以静态绑定数据源,这样就自动为DataGridView控件添加相应的行. 假如需要动态为DataGridView控件添加新行,方法有很多种,下面简单介绍如何为DataGridView控 ...