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.

103 lines
2.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
//需要开大一点否则RE,得了90分。
const int N = 1e5 + 10;
/**
以1011为例
1011
10 11
1 0 1 1
F7
F3 I6
I1 B2 I4 I5
后序IBFIIIF(遍历顺序已标注)
(编号为二叉树深度)
1.比如1011很明显是F
2.然后先不输出先遍历左子树10F
3.还是不输出先遍历左子树1I
3.发现不能再分长度为1时停止输出 I
2.回到10 继续遍历右子树0B
3.发现不能再分输出B
2.回到10 所有子树遍历完毕于是输出F
1.回到1011遍历右子树11I
2.先不输出继续遍历左子树1I
3.发现不能再分输出I
2.回到11 遍历右子树1I
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;
}