You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
//需要开大一点,否则RE,得了90分。
|
|
|
|
|
const int N = 1e5 + 10;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
以1011为例
|
|
|
|
|
1011
|
|
|
|
|
10 11
|
|
|
|
|
1 0 1 1
|
|
|
|
|
|
|
|
|
|
F(7)
|
|
|
|
|
F(3) I(6)
|
|
|
|
|
I(1) B(2) I(4) I(5)
|
|
|
|
|
后序:IBFIIIF(遍历顺序已标注)
|
|
|
|
|
|
|
|
|
|
(编号为二叉树深度)
|
|
|
|
|
|
|
|
|
|
1.比如1011,很明显是F
|
|
|
|
|
2.然后先不输出,先遍历左子树10(F)
|
|
|
|
|
3.还是不输出先遍历左子树1(I)
|
|
|
|
|
3.发现不能再分(长度为1时停止)输出 I
|
|
|
|
|
2.回到10 继续遍历右子树0(B)
|
|
|
|
|
3.发现不能再分,输出B
|
|
|
|
|
2.回到10, 所有子树遍历完毕,于是输出F
|
|
|
|
|
|
|
|
|
|
1.回到1011,遍历右子树11(I)
|
|
|
|
|
2.先不输出,继续遍历左子树1(I)
|
|
|
|
|
3.发现不能再分,输出I
|
|
|
|
|
2.回到11, 遍历右子树1(I)
|
|
|
|
|
3.发现不能再分,输出I
|
|
|
|
|
2.回到11,子树全部遍历完毕,于是输出I
|
|
|
|
|
|
|
|
|
|
1.回到1011,输出F
|
|
|
|
|
*/
|
|
|
|
|
//树的结构体+存储数组
|
|
|
|
|
struct Node {
|
|
|
|
|
int id; //id编号
|
|
|
|
|
int left; //左结点
|
|
|
|
|
int right; //右结点
|
|
|
|
|
char value; //当前结点的value值
|
|
|
|
|
} t[N];
|
|
|
|
|
|
|
|
|
|
int n, m;
|
|
|
|
|
string s; //2^n长度的01串
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:获取字符串s的类型
|
|
|
|
|
* @param s
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
char getStype(string s) {
|
|
|
|
|
int zeroCnt = 0, oneCnt = 0;
|
|
|
|
|
for (int i = 0; i < s.length(); i++) if (s[i] == '1') oneCnt++; else zeroCnt++;
|
|
|
|
|
if (oneCnt == 0)return 'B';
|
|
|
|
|
else if (zeroCnt == 0) return 'I';
|
|
|
|
|
return 'F';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:构建FBI树
|
|
|
|
|
* @param start 开始的位置
|
|
|
|
|
* @param end 结束的位置
|
|
|
|
|
*/
|
|
|
|
|
void build(string s, int pos) {
|
|
|
|
|
/**
|
|
|
|
|
递归的构造方法如下:
|
|
|
|
|
T的根结点为R,其类型与串S的类型相同;
|
|
|
|
|
若串S的长度大于1,将串S从中间分开,分为等长的左右子串S_1和S_2
|
|
|
|
|
由左子串S_1构造R的左子树T_1,由右子串S_2构造R的右子树T_2
|
|
|
|
|
*/
|
|
|
|
|
char v = getStype(s);
|
|
|
|
|
t[pos].id = pos;
|
|
|
|
|
t[pos].value = v;
|
|
|
|
|
|
|
|
|
|
if (s.length() > 1) {
|
|
|
|
|
t[pos].left = 2 * pos;
|
|
|
|
|
t[pos].right = 2 * pos + 1;
|
|
|
|
|
//左树
|
|
|
|
|
build(s.substr(0, s.length() / 2), t[pos].left);
|
|
|
|
|
//右树
|
|
|
|
|
build(s.substr(s.length() / 2), t[pos].right);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//利用递归进行后序遍历
|
|
|
|
|
void post_order(Node node) {
|
|
|
|
|
if (node.id) {
|
|
|
|
|
post_order(t[node.left]);
|
|
|
|
|
post_order(t[node.right]);
|
|
|
|
|
cout << node.value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
//这个n是无用的,因为是上古的考题,都是C时代的,要求使用char数组,没有n说不过去,现在都用string了,不需要n了。
|
|
|
|
|
cin >> n >> s;
|
|
|
|
|
//利用递归构建FBI树
|
|
|
|
|
build(s, 1);
|
|
|
|
|
//进行后序遍历
|
|
|
|
|
post_order(t[1]);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|