洛谷P1087 FBI树
洛谷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);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?