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 Notes
1.java是解释型语言.java虚拟机能实现一次编译多次运行. 2.JDK(java software Development kit 软件开发包),JRE(java Runtime Environ ...
- Android 异步加载
Android 4.0 后 貌似规定了 在主线程中不允许访问网络,在子线程中不允许修改UI. 否则会抛出NetworkOnMainThreadException 异常 解决办法: 采用继承 Async ...
- 欧拉工程第66题:Diophantine equation
题目链接 脑补知识:佩尔方差 上面说的貌似很明白,最小的i,对应最小的解 然而我理解成,一个循环的解了,然后就是搞不对,后来,仔细看+手工推导发现了问题.i从0开始变量,知道第一个满足等式的解就是最小 ...
- Minimum_Window_Substring两种方法求解
题目描述: Given a string S and a string T, find the minimum window in S which will contain all the chara ...
- MySQL错误代码大全【转载】
B.1. 服务器错误代码和消息 服务器错误信息来自下述源文件: 错误消息信息列在share/errmsg.txt文件中."%d"和"%s"分别代表编号和字符串, ...
- Mybatis全部查询遇到的返回类型的小问题
在学习Mybatis3过程中遇到一个小问题,觉得需要注意就把它写下来了 在查询所有数据的时候方法是这样的 public List<User> findAll(){ ..... } 在它的u ...
- 网上图书商城项目学习笔记-011Book模块查询(分页)
一.流程分析 1.图书模块 2.分布分析 二.代码 1.view层 1)list.jsp <%@ page language="java" import="java ...
- lua string函数
lua的string函数: 参数中的index从1开始,负数的意义是从后开始往前数,比如-1代表最后一个字母 对于string类型的值,可以使用OO的方式处理,如string.byte(s.i)可以被 ...
- Linux进程的睡眠和唤醒简析
COPY FROM:http://www.2cto.com/os/201204/127771.html 1 Linux进程的睡眠和唤醒 在Linux中,仅等待CPU时间的进程称为就绪进程,它们被放置在 ...
- android自动更新软件版本
根据网上的然后小改 import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import j ...