描述

我们可以把由“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/ >

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

#include <iostream>
#include <string>
using namespace std; struct Node{
char val;
Node *l = NULL, *r = NULL;
}; string s; Node* build(const string& s)
{
bool flag0 = false, flag1 = false;
size_t len = s.length();
for(size_t i = 0; i < len; ++i){
if(s[i] == '0')
flag0 = true;
else
flag1 = true;
if(flag0 && flag1)
break;
}
char ch;
if(flag0 && flag1)
ch = 'F';
else if(flag0)
ch = 'B';
else
ch = 'I';
Node *root = new Node;
root->val = ch;
if(len > 1){
if(len&1){
string left = s.substr(0, len/2);
string right = s.substr(len/2+1);
root->l = build(left);
root->r = build(right);
}
else{
string left = s.substr(0, len/2);
string right = s.substr(len/2);
root->l = build(left);
root->r = build(right);
}
}
return root;
} void post_order(Node* root)
{
if(root != NULL){
post_order(root->l);
post_order(root->r);
cout<<root->val;
}
} void destroy(Node* root)
{
if(root->l != NULL)
destroy(root->l);
if(root->r != NULL)
destroy(root->r);
delete root;
} int main()
{
int n;
cin>>n>>s;
Node *root = build(s);
post_order(root);
destroy(root);
return 0;
}

<br/ >

<br/ >

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

void pre_order(Node* root)
{
if(root != NULL){
cout<<root->val;
pre_order(root->l);
pre_order(root->r);
}
}
void in_order(Node* root)
{
if(root != NULL){
in_order(root->l);
cout<<root->val;
in_order(root->r);
}
}

<br/ >

以及它们的非递归实现:

#include <iostream>
#include <string>
using namespace std; struct Node{
char val;
Node *l = NULL, *r = NULL, *p = NULL; //增加了一个字段p,用于记录他的父结点
}; string s; Node* build(const string& s, Node* p) //建树也做相应的更改
{
bool flag0 = false, flag1 = false;
size_t len = s.length();
for(size_t i = 0; i < len; ++i){
if(s[i] == '0')
flag0 = true;
else
flag1 = true;
if(flag0 && flag1)
break;
}
char ch;
if(flag0 && flag1)
ch = 'F';
else if(flag0)
ch = 'B';
else
ch = 'I';
Node *root = new Node;
root->val = ch;
root->p = p;
if(len > 1){
if(len&1){
string left = s.substr(0, len/2);
string right = s.substr(len/2+1);
root->l = build(left, root);
root->r = build(right, root);
}
else{
string left = s.substr(0, len/2);
string right = s.substr(len/2);
root->l = build(left, root);
root->r = build(right, root);
}
}
return root;
} void pre_order2(Node* root)
{
Node *pre = NULL;
Node *node = root;
while(node != NULL){
if(pre == node->p){
cout<<node->val;
if(node->l != NULL){
pre = node;
node = node->l;
}
else{
if(node->r != NULL){
pre = node;
node = node->r;
}
else{
pre = node;
node = node->p;
}
}
}
else if(pre == node->l){
if(node->r != NULL){
pre = node;
node = node->r;
}
else{
pre = node;
node = node->p;
}
}
else if(pre == node->r){
pre = node;
node = node->p;
}
}
} void in_order2(Node* root)
{
Node *pre = NULL;
Node *node = root;
while(node != NULL){
if(pre == node->p){
if(node->l != NULL){
pre = node;
node = node->l;
}
else{
cout<<node->val;
if(node->r != NULL){
pre = node;
node = node->r;
}
else{
pre = node;
node = node->p;
}
}
}
else if(pre == node->l){
cout<<node->val;
if(node->r != NULL){
pre = node;
node = node->r;
}
else{
pre = node;
node = node->p;
}
}
else if(pre == node->r){
pre = node;
node = node->p;
}
}
} void post_order2(Node* root)
{
Node *pre = NULL;
Node *node = root;
while(node != NULL){
if(pre == node->p){
if(node->l != NULL){
pre = node;
node = node->l;
}
else{
if(node->r != NULL){
pre = node;
node = node->r;
}
else{
cout<<node->val;
pre = node;
node = node->p;
}
}
}
else if(pre == node->l){
if(node->r != NULL){
pre = node;
node = node->r;
}
else{
cout<<node->val;
pre = node;
node = node->p;
}
}
else if(pre == node->r){
cout<<node->val;
pre = node;
node = node->p;
}
}
} void destroy(Node* root)
{
if(root->l != NULL)
destroy(root->l);
if(root->r != NULL)
destroy(root->r);
delete root;
} int main()
{
int n;
cin>>n>>s;
Node *root = build(s, NULL);
pre_order(root);
cout<<endl;
pre_order2(root);
cout<<endl<<endl; in_order(root);
cout<<endl;
in_order2(root);
cout<<endl<<endl; post_order(root);
cout<<endl;
post_order2(root);
cout<<endl<<endl; destroy(root);
return 0;
}

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. hdu 1233 还是畅通工程(最小生成树,基础)

    题目 //也是标准的最小生成树啊,我就改一点点,不重新再打一遍增加熟练度了 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #inclu ...

  2. DataRow.RowState 属性

    RowState 的值取决于两个因素:已对该行执行的操作的类型,以及是否已对 DataRow 调用了 AcceptChanges. private void DemonstrateRowState() ...

  3. 黑马程序员--C#中属性和字段(变量)的区别

    ---------------------- ASP.Net+Android+IOS开发..Net培训.期待与您交流! ---------------------- 属性为类提供了一种很有用的封装数据 ...

  4. 一个很好的php分词类库

    PHPAnalysis源程序下载与演示: PHP分词系统 V2.0 版下载 | PHP分词系统演示 | PHPAnalysis类API文档   原文连接地址:http://www.phpbone.co ...

  5. N皇后//搜索入门

    P1080 N皇后 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列只有一个,每条 ...

  6. SQL Server Profiler监控SQL Server性能

    全面掌握SQL Server Profiler 1.       原理与相关概念介绍 SQL Server Profiler,大家已经非常熟悉.常常在性能优化中使用,本文档详细介绍SQL Server ...

  7. iOS 开发-- Runtime 1小时入门教程

    1小时让你知道什么是Objective-C Runtime,并对它有一定的基本了解,可以在开发过程中运用自如. 三.Objective-C Runtime到底是什么东西? 简而言之,Objective ...

  8. WCF入门(十一)---WCF安全

    一个强大的WCF服务安全系统,拥有两种安全模式或级别预期的客户端可以访问的服务.这是常见的分布式事务的安全威胁正在放缓,在很大程度上由WCF决定. 关键的安全功能 WCF服务有四个主要的安全功能,如下 ...

  9. MyEclipse 2014 + JSP+ Servlet

    来自:http://blog.csdn.net/21aspnet/article/details/21867241 1.安装准备 1).下载安装MyEclipse2014,这已经是最新版本. 2).下 ...

  10. Java API —— TreeSet类

    1.TreeSet类    1)TreeSet类概述         使用元素的自然顺序对元素进行排序         或者根据创建 set 时提供的 Comparator 进行排序          ...