注意:本文只给出作者认为必要的知识点并且可能存在疏漏。 |
目录
一、题目大意
给一颗 深度 为 n 的 完全二叉树 ,每一层的 非终端结点 都有特定值 Xi(1、0)
,从根结点开始向下走,若当前 Xi 的值为1则向右子树深入,否则向左子树深入,输出到达 叶子结点 的值。其有 2n 个叶子结点,叶子结点的值按序给出,但 Xi 的排列为无序。原题链接
二、理论基础
1. 二叉树
1.1 二叉树的定义
一种树型结构,它的特点是每个结点至多只有两颗子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树的左右之分,其次序不能任意颠倒。1
1.2 二叉树的性质
- 在二叉树的第 i 层上至多有 2i-1 个结点。 i ≥ 0 \textcolor{#FF0000}{i \geq 0} i≥0
- 深度为 k 的二叉树最大结点数为 ∑ i = 1 k = 2 k − 1 , k ≥ 1 {\sum_{i=1}^{k}=2^k-1}, \textcolor{#FF0000}{k \geq 1} i=1∑k=2k−1,k≥1
- 对于任意二叉树,若其终端结点数为 x,度为2的结点数为 y,则 x = y + 1 x=y+1 x=y+1。
2. 满二叉树
一颗深度为 k 且有 2k-1 个结点的二叉树,每一层上的结点数都是最大结点数。对满二叉树的结点进行连续编号
(一般从1开始编号)
,约定编号从根结点起,自上而下,从左向右。1
3. 完全二叉树
3.1 完全二叉树的定义
一颗深度为 k 的二叉树并对其结点进行编号,若其与深度同为 k 的满二叉树的编号一一对应
(编号从1到n且连续)
则为完全二叉树。满二叉树一定是完全二叉树,完全二叉树是满二叉树按序删去末尾结点的产物。
3.2 完全二叉树的性质 本题重点
- 对于任意非终端结点 i,若其有左孩子,则必为结点 2 × i 2\times i 2×i。
- 对于任意非终端结点 i,若其有右孩子,则必为结点 2 × i + 1 2\times i +1 2×i+1。
三、解题思路
按完全二叉树的结点编号规律进行递推即可计算出叶子结点的编号,注意本题深度从0开始并且 Xi 的排列为无序。
四、参考代码
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
#define maxn 129
#define INF 0x3f3f3f
typedef long long ll;
int main() {
int n, order[7], Case = 1, T, base;
char c[3], stemp[8], s[maxn];
vector<int> result;
result.reserve(maxn * 4);//优化速度
ios::sync_with_stdio();
cin.tie(0);
cout.tie(0);
while (cin >> n && n) {
result.clear();//清空
base = 1 << n;
for (int i = 0; i < n; ++i) {
cin >> c;
order[i] = c[1] - '1';
}
cin >> s >> T;
for (int i = 0; i < T; ++i) {
int itemp = 1;
cin >> stemp;
for (int j = 0; j < n; ++j) {
itemp <<= 1;
itemp += stemp[order[j]] == '0' ? 0 : 1;//右孩子加1
}
result.push_back(s[itemp - base] - '0');//itemp为叶子结点的编号
}
cout << "S-Tree #" << Case++ << ':' << endl;
for (int i = 0; i < result.size(); ++i)
cout << result[i];
putchar('\n');
putchar('\n');
}
return 0;
}
分类:
UVA题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】