洛谷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);
}
标签:cnt,洛谷,start,int,self,current,P1087,end,FBI
From: https://www.cnblogs.com/rjxq/p/18216090