Vijos 1114 FBI树
描述
我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串。
FBI树是一种二叉树1,它的结点类型也包括F结点,B结点和I结点三种。由一个长度为2^N的“01”串S可以构造出一棵FBI树T,递归的构造方法如下:
- T的根结点为R,其类型与串S的类型相同;
- 若串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树的更多相关文章
- 【递归】Vijos P1114 FBI树(NOIP2004普及组第三题)
题目链接: https://vijos.org/p/1114 题目大意: 把01串一分为二,左半边描述当前节点左子树,右半边描述右子树,子树全为1则为I节点,全为0则为B节点,混合则为F节点,直到当前 ...
- Vijos P1114 FBI树【DFS模拟,二叉树入门】
描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串. FBI树是一种二叉树1,它的结点类型也包括F结点,B结点和I结点三种 ...
- 创建FBI树
需求:数串由2^n个'0' '1'数串组成,对于一个数串,有01混合出现,则视为F,全0数串为B,全1数串为I. 将给定数串进行切割,如10010011可以用二叉树表示为 F(10010011) / ...
- 蓝桥杯之FBI树问题
问题描述 我们可以把由"0"和"1"组成的字符串分为三类:全"0"串称为B串,全"1"串称为I串,既含"0&q ...
- noip普及组2004 FBI树
FBI树 描述 我们可以把由"0"和"1"组成的字符串分为三类:全"0"串称为B串,全"1"串称为I串,既含" ...
- [题解]ybt1365:FBI树(fbi)
ybt1365:FBI树(fbi) [题目描述] 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串. FBI树是一种二叉树,它 ...
- FBI树-数据结构(二叉树)
问题 B: [2004_p4]FBI树-数据结构 时间限制: 1 Sec 内存限制: 125 MB提交: 57 解决: 46 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称 ...
- C语言 · FBI树
算法训练 FBI树 时间限制:1.0s 内存限制:256.0MB 锦囊1 二叉树. 问题描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I ...
- FBI树(第一次做建树题)
试题来源 NOIP2004 普及组 问题描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串. FBI树是一种二叉树,它的结 ...
随机推荐
- java基础知识回顾之javaIO类--File类应用:过滤器接口FilenameFilter和FileFilter
FilenameFilter和FileFilter都是用来过滤文件,例如过滤,以.jpg或者.java结尾的文件,通过看他们的源码:通过使用File类中String[] list(FilenameFi ...
- POJ 1699 Best Sequence(DFS)
題目鏈接 題意 : 將幾個片段如圖所示方法縮成一個序列,求出最短這個序列. 思路 : 其實我也不知道怎麼做.....看網上都用了DP.....但是我不會.....這個DP不錯,還有用KMP+状压DP做 ...
- Ubuntu环境下利用ant编译nutch2.2.1 & 配置nutch2.2.1
/×××××××××××××××××××××××××××××××××××××××××/ Author:xxx0624 HomePage:http://www.cnblogs.com/xxx0624/ ...
- lintcode 中等题:Letter Combinations of a Phone Number 电话号码的字母组合
题目 电话号码的字母组合 给一个数字字符串,每个数字代表一个字母,请返回其所有可能的字母组合. 下图的手机按键图,就表示了每个数字可以代表的字母. 样例 给定 "23" 返回 [& ...
- 【PHPsocket编程专题(实战篇③)】构建基于socket的HTTP请求类
该代码是两年前写的,现在看起来有点渣了,仅仅是提供一个思路,现在做一些Api开发的时候官方会有一些SDK,这些SDK其实原理都是通过socket来通讯的,其实我个人主张用curl更方便,当然前提是你的 ...
- platform_driver_register(),platform_device_register()区别
设备与驱动的两种绑定方式:在设备注册时进行绑定及在驱动注册时进行绑定. 以一个USB设备为例,有两种情形: (1)先插上USB设备并挂到总线中,然后在安装USB驱动程序过程中从总线上遍历各个设备,看驱 ...
- Hello World---C/C++
C #include <stdio.h> void main() { printf("Hello World!\n"); } C++ #include <iost ...
- java:静态成员变量和静态函数
静态成员变量 可以使用类名调用,如 class Dog { static int age; } class Test2{ public static void main(String args[]){ ...
- 1、探究java方法参数传递——引用传递?值传递!
原创博文,转载请注明出处.谢谢~~ java程序运行时,其对象是怎么进行放置和安排的呢?内存是怎么分配的呢?理解好这个很有好处!java有5个地方可以存储数据: 1.寄存器.这是最快的存储区,位于处理 ...
- python获取外网地址
# coding=gbk import sys,urllib.request,re url = "http://www.3322.org/dyndns/getip" #网页地址 m ...