洛谷P1087
遞迴建立樹,根據當前樹的型別,選擇“F”“B”“I”
void build(int depth, int start, int end, int root){
if (depth >= n+1) return;
int current = root;
int flag = check(start, end);
if (flag == 0) t[current].self = 'B';
else if (flag == 1) t[current].self = 'I';
else t[current].self = 'F';
t[current].left = ++cnt;
build(depth + 1, start, (start + end) / 2, cnt);
t[current].right = ++cnt;
build(depth + 1, (start + end) / 2 + 1, end, cnt);
}
t[current].left = ++cnt;
build(depth + 1, (start + end) / 2 + 1, end, cnt);
t[current].right = ++cnt;
build(depth + 1, start, (start + end) / 2, cnt);
這一部分保證了子節點不會被重複指向
遞迴建立因為每一次建立,cnt都會加1,所以不會重複指向
AC程式碼
#include<bits/stdc++.h>
using namespace std;
int n, cnt = 1;
vector<int> num;
struct node{
char self;
int left, right;
node(): left(0), right(0), self('*'){}
};
vector<node> t;
int check (int start, int end) {
int flag0 = 0, flag1 = 0;
for (int i = start; i <= end; i++) {
if (num[i] == 0) flag0 = 1;
if (num[i] == 1) flag1 = 1;
}
if (flag0 == 0 && flag1 == 1) return 1;
if (flag0 == 1 && flag1 == 0) return 0;
return 2;
}
void build(int depth, int start, int end, int root){
if (depth >= n+1) return;
int current = root;
int flag = check(start, end);
if (flag == 0) t[current].self = 'B';
else if (flag == 1) t[current].self = 'I';
else t[current].self = 'F';
t[current].left = ++cnt;
build(depth + 1, start, (start + end) / 2, cnt);
t[current].right = ++cnt;
build(depth + 1, (start + end) / 2 + 1, end, cnt);
}
void print(int root) {
if (t[root].self == '*') return;
print(t[root].left);
print(t[root].right);
cout << t[root].self;
}
int main() {
cin >> n;
num.resize((1<<(n+1))+100);
t.resize((1<<(n+2))+100);
char ch;
for (int i = 1; i <= (1<<n); i++) {
cin >> ch;
num[i] = ch-'0';
}
build(0, 1, (1<<n), 1);
print(1);
}