题目描述
我们可以把由“ 0 0 0”和“ 1 1 1”组成的字符串分为三类:全“ 0 0 0”串称为 B B B串,全“ 1 1 1”串称为I串,既含“ 0 0 0”又含“ 1 1 1”的串则称为F串。
F B I FBI FBI树是一种二叉树,它的结点类型也包括 F F F结点, B B B结点和I结点三种。由一个长度为 2 N 2^N 2N的“ 01 01 01”串S可以构造出一棵 F B I FBI FBI树 T T T,递归的构造方法如下:
- T T T的根结点为 R R R,其类型与串 S S S的类型相同;
- 若串 S S S的长度大于 1 1 1,将串 S S S从中间分开,分为等长的左右子串 S 1 S_1 S1和 S 2 S_2 S2;由左子串 S 1 S_1 S1构造R的左子树 T 1 T_1 T1,由右子串 S 2 S_2 S2构造 R R R的右子树 T 2 T_2 T2。
现在给定一个长度为 2 N 2^N 2N的“ 01 01 01”串,请用上述构造方法构造出一棵 F B I FBI FBI树,并输出它的后序遍历序列。
输入格式
第二行是一个长度为 2 N 2^N 2N的“ 01 01 01”串。
输出格式
一个字符串,即$FBI$树的后序遍历序列。输入样例
3
10001011
输出样例 #1
IBFBBBFIBFIIIFF
说明
对于全部的数据, N < = 10 N<=10 N<=10。
noip2004普及组第3题
学到的新知识:
str.find() -------find(“要找的内容”,开始位置可省略)
若找到返回第一个地址,否则返回string::npos
str.substr() ----------抽取子串substr(起始位置,长度)
#include<iostream>
#include<cstdio>
int f1,f2;
using namespace std;
struct node
{
char flag;
string am;
node* left;
node *right;
};
int voo(string str,node *root)//此节点是FBI哪一个
{
f1=str.find("01");
f2=str.find("10");
if(f1!=string::npos||f2!=string::npos) root->flag='F';
else
{
if(str[0]=='0') root->flag='B';
else root->flag='I';
}
}
void init(node * root,string str)//递归建立此树
{
root->am=str;
voo(str,root);
if(str.size()>>1!=0)
{
node *tep=new node;
root->left=tep;
init(root->left,str.substr(0,str.size()>>1));
}
else root->left=root->right=NULL;
if(str.size()>>1!=0)
{
node *tep=new node;
root->right=tep;
init(root->right,str.substr(str.size()>>1,str.size()>>1));
}
}
void postordertra(node *root) //后序遍历
{
if(root->left)
{
postordertra(root->left);
}
if(root->right)
{
postordertra(root->right);
}
if(root)
{
cout<<root->flag;
}
}
int main(void)
{
int n;
string str;
cin>>n>>str;
node *root=new node;
init(root,str);
postordertra(root);
}