当前位置: 首页 > news >正文

牛客NC16660 [NOIP2004]FBI树(递归 + 二叉树后序遍历)

题目描述

我们可以把由 “0” 和 “1” 组成的字符串分为三类:

  • 全“0”串称为 B串
  • 全“1”串称为 I串
  • 既含“0”又含“1”的串称为 F串

FBI 树是一种二叉树,它的结点类型也包括 F 结点、B 结点和 I 结点三种。由一个长度为 2N2^N2N 的 “01” 串 SSS 可以构造出一棵 FBI 树 TTT,递归构造的方法如下:

  1. TTT 的根结点为 RRR,其类型与串 SSS 的类型相同;
  2. 若串 SSS 的长度大于 1,将串 SSS 从中间分为等长的左右子串 S1S_1S1S2S_2S2
    • 由左子串 S1S_1S1 构造 RRR 的左子树 T1T_1T1
    • 由右子串 S2S_2S2 构造 RRR 的右子树 T2T_2T2

现在给定一个长度为 2N2^N2N 的 “01” 串,请用上述构造方法构造出一棵 FBI 树,并输出它的后序遍历序列

后序遍历:先后序遍历左子树,再后序遍历右子树,最后访问根节点。

输入格式

  • 第一行是一个整数 NNN,表示输入字符串的长度为 2N2^N2N
  • 第二行是一个长度为 2N2^N2N 的“01”串。

输出格式

输出一行字符串,表示 FBI 树的后序遍历序列。

样例输入

3
10001011

样例输出

IBFBBBFIBFIIIFF

数据范围与说明

  • 对于 40% 的数据,N≤2N \leq 2N2
  • 对于 100% 的数据,0≤N≤100 \leq N \leq 100N10
  • 输入字符串保证长度为 2N2^N2N

提交链接

https://ac.nowcoder.com/acm/problem/16660

思路分析

🧠构建过程概括(DFS + 后序遍历)

我们使用 递归(DFS) 的方式模拟构造这棵 FBI 树。

每个结点对应一个字符串区间,对于每个区间:

  • 先递归构造左子树(处理左半段)
  • 再递归构造右子树(处理右半段)
  • 然后判断当前区间的类型
    • 全为 '0':类型为 'B'
    • 全为 '1':类型为 'I'
    • '0''1':类型为 'F'
  • 最后使用 后序遍历(左 → 右 → 根)输出所有结点的类型

树的大小分析

  • 输入字符串的长度为 2n2^n2n,表示叶子结点数量为 2n2^n2n
  • 构造出的 FBI 树是一棵 满二叉树
  • 总结点数为:2n+1−12^{n+1} - 12n+11

例如:

n字符串长度总节点数
011
123
247
3815

输出要求

输出 FBI 树的 后序遍历 序列:

  • 顺序为:左子树 → 右子树 → 根节点
  • 每个结点输出其对应类型(F / B / I

✅ 整体结构划分

函数名作用
check(l, r)判断区间 [l, r] 的字符串属于 F / B / I 类型
dfs(l, r, id)构造以 str[l..r] 为区间的子树,存在数组 a 的下标 id
change(root)后序遍历二叉树并输出对应类型

参考代码

#include<bits/stdc++.h>
using namespace std;
vector<char>a(1000000);
int n;
string str;
char check(int l , int r)  //判断字符串的构成 FBI 哪一种
{int zero = 0 , one = 0;for(int i = l; i <= r; i++){if(str[i] == '0')zero++;elseone++;}if(zero && one)return 'F';else if(zero)return 'B';elsereturn 'I';
}
void dfs(int l , int r , int id)  //构造二叉树
{if(l == r){a[id] = check(l , r);return;}int mid = l + (r - l) / 2;dfs(l , mid , id * 2);dfs(mid + 1 , r , id * 2 + 1);a[id] = check(l , r);
}
void change(int root)
{if(a[root] == 0)return;change(2 * root);change(2 * root + 1);cout << a[root];
}
int main()
{cin >> n >> str;dfs(0 , str.size() - 1 , 1);change(1);return 0;
}
http://www.dtcms.com/a/298450.html

相关文章:

  • electron中IPC 渲染进程与主进程通信方法解析
  • 常用设计模式系列(十二)—享元模式
  • 如何在 FastAPI 中玩转 GraphQL 和 WebSocket 的实时数据推送魔法?
  • C++中使用Essentia实现STFT/ISTFT
  • git 连接GitHub仓库
  • 强化学习之策略熵坍塌优化-clip conv kv conv
  • 若依搭建详解
  • Android Paging 分页加载库详解与实践
  • 第七章 愿景11 琦琦复盘测试
  • Keepalived 深度技术解析与高可用实践指南
  • C++编程学习(第15天)
  • ServletRegistrationBean相关知识点
  • 用 Docker 一键部署 Flask + Redis 微服务
  • NX848NX854美光固态闪存NX861NX864
  • 截稿倒计时 TrustCom‘25大会即将召开
  • C++中AC、WA、RE、CE、TLE、MLE、PE、OLE的意思
  • 【ResNet50图像分类部署至RK3588】模型训练→转换RKNN→开发板部署
  • 安装本地python文件到site-packages
  • 专题:2025电商增长新势力洞察报告:区域裂变、平台垄断与银发平权|附260+报告PDF、原数据表汇总下载
  • Linux运维新人自用笔记(Rsync远程传输备份,服务端、邮箱和客户端配置、脚本)
  • 【c++思维题】洛谷 P1496 火烧赤壁
  • 【js(8) for...in和for...of】
  • NVM踩坑实录:配置了npm的阿里云cdn之后,下载nodejs老版本(如:12.18.4)时,报404异常,下载失败的问题解决
  • LeetCode|Day25|389. 找不同|Python刷题笔记
  • IOPaint 图像修复工具,学习笔记
  • clFlush和clFinish的区别 (来自deepseek)
  • ZYNQ芯片,SPI驱动开发自学全解析个人笔记【FPGA】【赛灵思
  • 电子电气架构 --- 车载软件与样件产品交付的方法
  • 【HarmonyOS】鸿蒙应用开发中常用的三方库介绍和使用示例
  • QT6 源,七章对话框与多窗体(14)栈式窗体 QStackedWidget:本类里代码很少。举例,以及源代码带注释。