题意:
输入格式:
输出格式:
输入样例1:
输出样例1:
首先要解决这道题就要先了解题意,题目中实际上讲的是二叉树的孩子兄弟表示法
,通常又被称为二叉树表示法
或二叉链表表示法
,那什么是二叉树的孩子兄弟表示法,下面先简单介绍一下:
假设有一棵普通的二叉树如图:
图1
树结构中,位于同一层的节点之间互为兄弟节点。例如,图 1 的普通树中,节点 A、B 和 C 互为兄弟节点,而节点 D、E 和 F 也互为兄弟节点。
- 节点的值;
- 指向孩子节点的指针;
- 指向兄弟节点的指针;
图2
以图 1 为例,使用孩子兄弟表示法进行存储的结果如下图所示:
图3
以上就是图1的普通树转换成孩子兄弟表示法存储的结构图。
至此,明白了什么是二叉树的孩子兄弟表示法,也就可以着手解题了:
这一步的主要代码:
void build(int idx) {
if(tree[t2]==0) {
t2++;
return;
}
childBro[idx]=tree[t2++];
build(2*idx+1);
build(2*idx+2);
}
主要代码:
void build2(int idx,int k) {
if(childBro[k]==0)
return;
common[idx]=childBro[k];
book[childBro[k]]=idx;//将下标与元素联系起来
build2(3*idx+1,2*k+1);
build2(idx+1,2*k+2);
}
完整代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int tree[105];
int childBro[105],common[105],book[105];//book存储元素的下标 ,childBro是孩子兄弟表示法的构造,common是普通树的构造
int t2=0;
//二叉树孩子兄弟表示法:左边存储左孩子,右边存储兄弟节点
//解题思路:先构造二叉树孩子兄弟表示法,再根据孩子兄弟表示法构造出题目所示的二叉树
//构造成孩子兄弟表示法
void build(int idx) {
if(tree[t2]==0) {
t2++;
return;
}
childBro[idx]=tree[t2++];
build(2*idx+1);
build(2*idx+2);
}
//转换成题目所示
void build2(int idx,int k) {
if(childBro[k]==0)
return;
common[idx]=childBro[k];
book[childBro[k]]=idx;
build2(3*idx+1,2*k+1);
build2(idx+1,2*k+2);
}
int main() {
int t;
cin>>t;
while(t--) {
memset(childBro,0,sizeof childBro);
memset(common,0,sizeof common);
memset(tree,0,sizeof tree);
memset(book,0,sizeof book);
int t1=0;
t2=0;
int a,num=0;
while(scanf("%d",&a)) {
if(a==0)
num++;
else {
num=0;
}
tree[t1++]=a;
if(num==3)
break;
}
build(0);
build2(0,0);
int n,m;
cin>>n>>m;
n=book[n];
m=book[m];
if(n<m)
swap(n,m);
while(n>m) {
n=(n-1)/3;
}
if(n==m)
cout<<common[n]<<endl;
else {
while(n!=m) {
m=(m-1)/3;
if(n==m){
break;
}
n=(n-1)/3;
}
cout<<common[n]<<endl;
}
}
return 0;
}
提交结果: