题目描述
我们可以把由“ 00 ”和“ 11 ”组成的字符串分为三类:全“ 00 ”串称为 BB 串,全“ 11 ”串称为I串,既含“ 00 ”又含“ 11 ”的串则称为F串。
FBIFBI 树是一种二叉树,它的结点类型也包括 FF 结点, BB 结点和I结点三种。由一个长度为 2^N2N 的“ 0101 ”串S可以构造出一棵 FBIFBI 树 TT ,递归的构造方法如下:
1) TT 的根结点为 RR ,其类型与串 SS 的类型相同;
2) 若串 SS 的长度大于 11 ,将串 SS 从中间分开,分为等长的左右子串 S_1S1 和 S_2S2 ;由左子串 S_1S1 构造R的左子树 T_1T1,由右子串 S_2S2 构造 RR 的右子树 T_2T2 。
现在给定一个长度为 2^N2N 的“ 0101 ”串,请用上述构造方法构造出一棵 FBIFBI 树,并输出它的后序遍历序列。
输入输出格式
输入格式:
第一行是一个整数 N(0 \le N \le 10)N(0≤N≤10) ,
第二行是一个长度为 2^N2N 的“ 0101 ”串。
输出格式:
一个字符串,即 FBIFBI 树的后序遍历序列。
输入输出样例
输入样例#1: 复制
3 10001011
输出样例#1: 复制
IBFBBBFIBFIIIFF
说明
对于40%的数据, N \le 2N≤2 ;
对于全部的数据, N \le 10N≤10 。
noip2004普及组第3题
思路:
其实完全不用建树,直接循环调用左右;
代码如下
#include <bits/stdc++.h>
#define maxn 100005
typedef long long ll;
using namespace std;
ll mod = 1e9 + 7,n;
char tree[maxn];
void loop(ll be,ll en)
{
if(be != en)
{
ll mid = be + (en - be) / 2;
loop(be,mid);
loop(mid + 1,en);
}
ll is0 = 0,is1 = 0;
for(int i = be; i <= en; i ++)
{
if(tree[i] == '0')is0++;
if(tree[i] == '1')is1++;
}
if(is0&&is1)cout << 'F';
else if(is0)cout << 'B';
else cout << 'I';
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin >> n;
n = pow(2,n);
cin >> (tree + 1);
loop(1,n);
cout << endl;
return 0;
}