空降题目:
题目描述
我们可以把由 0 和 1 组成的字符串分为三类:全 0 串称为 B 串,全 1 串称为 I 串,既含 0 又含 1 的串则称为 F 串。
FBI 树是一种二叉树,它的结点类型也包括 F 结点,B 结点和 I 结点三种。由一个长度为 2^N2N 的 01 串 SS 可以构造出一棵 FBI 树 TT,递归的构造方法如下:
- TT 的根结点为 RR,其类型与串 SS 的类型相同;
- 若串 SS 的长度大于 11,将串 SS 从中间分开,分为等长的左右子串 S_1S1 和 S_2S2;由左子串 S_1S1 构造 RR 的左子树 T_1T1,由右子串 S_2S2 构造 RR 的右子树 T_2T2。
现在给定一个长度为 2^N2N 的 01 串,请用上述构造方法构造出一棵 FBI 树,并输出它的后序遍历序列。
输入格式
第一行是一个整数 N(0 \le N \le 10)N(0≤N≤10),
第二行是一个长度为 2^N2N 的 01 串。
输出格式
一个字符串,即 FBI 树的后序遍历序列。
输入输出样例
输入 #1复制
3 10001011
输出 #1复制
IBFBBBFIBFIIIFF
说明/提示
对于 40\%40% 的数据,N \le 2N≤2;
对于全部的数据,N \le 10N≤10。
noip2004普及组第3题
思路:
我们首先应该知道后序遍历的特点:左右根
所以要用到一个栈
什么是栈不会还有人不知道吧
stack<int> q;
然后用递归反复操作;
有三种情况:
1.长度为1:
1)是B串
2)是I串
2.长度不为1:
1)是B串
2)是I串
3.是F串
先入栈:
string a;//初始输入字符串
if(a.size()==1){
if(a=="1") q.push('I');
else q.push('B');
return;
}
bool flag=true;
for(int i=0;i<a.size();i++){
if(a[i]=='1')flag=false;
}
if(flag){
q.push('B');
}
else{
flag=true;
for(int i=0;i<a.size();i++){
if(a[i]=='0')flag=false;
}
if(flag){
q.push('I');
}
else{
q.push('F');
}
}
然后将字符串分为左右两部分,进行递归
注意,由于是栈,所以要先搜索右子树,再搜索左子树
string b,c;
for(int i=0;i<a.size()/2;i++){
b+=a[i];
}
for(int i=a.size()/2;i<a.size();i++){
c+=a[i];
}
postorder(c);
postorder(b);
最后输出
void print(){
while(!q.empty()){
cout<<q.top();
q.pop();
}
}
完整代码
#include<bits/stdc++.h>
#include<stack>
using namespace std;
stack<char> q;
void print(){
while(!q.empty()){
cout<<q.top();
q.pop();
}
}
void postorder(string a){
if(a.size()==1){
if(a=="1") q.push('I');
else q.push('B');
return;
}
bool flag=true;
for(int i=0;i<a.size();i++){
if(a[i]=='1')flag=false;
}
if(flag){
q.push('B');
}
else{
flag=true;
for(int i=0;i<a.size();i++){
if(a[i]=='0')flag=false;
}
if(flag){
q.push('I');
}
else{
q.push('F');
}
}
string b,c;
for(int i=0;i<a.size()/2;i++){
b+=a[i];
}
for(int i=a.size()/2;i<a.size();i++){
c+=a[i];
}
postorder(c);
postorder(b);
}
int main(){
int n;
string a;
cin>>n>>a;
postorder(a);
print();
return 0;
}