FBI树

 

 

 

 

 

 

 

 

提示:

这道题有两种解法,可以用麻烦的字符串解法,也可以直接从下往上构建树,不需要字符串,因为数据保证所给的树是满二叉树,所以整棵树的节点数为pow(2,n+1)-1,而非叶子节点的数量我pow(2,n)-1。

 根据这个规律就可以从第2^n个节点开始编号,若此节点对应字母为1,则此节点类型为I,否则为B。

由于在叶子节点处每一个节点只对应一个字母,所以不可能出现兼备1和0的F型节点

接下来以此类推得出所以叶子节点的类型,继续判断他们的父亲节点的类型(父亲节点的编号为左右任意儿子的编号除以2

这道题中可以通过左右儿子节点的类型判断一个节点的类型,

若该节点左儿子为I,即1,右儿子为B,即0,则他们的父亲为10,即F,

反之,若左右儿子类型一致,那么父亲的类型也一致,就像血型一样,直到他们的元谋人祖先根节点

最后再从根节点开始后续输出(左儿子编号为父亲编号乘2,右儿子编号则比左儿子大1)

满分代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 char p[5000];//这道题可以直接利用父子关系解决,不需要结构体,用一个数组储存节点类型就OK
 4 int x;
 5 int n;
 6 char pd(char a){//判断叶子节点类型
 7     if(a=='1')return 'I';
 8     return 'B';
 9 }
10 void build(int a){
11     if(a==1)return ;
12     if(p[a]==p[a-1]){//不需要字符串,利用左右儿子的类型关系判断即可
13         p[a/2]=p[a];
14     }
15     else{
16         p[a/2]='F';
17     }
18     build(a-2);
19 }
20 void hx(int a){//后续输出
21     if(p[a*2])hx(a*2);
22     if(p[a*2+1])hx(a*2+1);
23     cout<<p[a];
24 }
25 int main(){
26     cin>>n;
27     x=pow(2,n)-1;
28     int z=pow(2,n+1)-1;
29     for(int i=1;i<=pow(2,n);i++){
30         char s;
31         cin>>s;
32         p[x+i]=pd(s);
33     }
34     build(z);
35     hx(1);
36     return 0;
37 } 

 

 

posted @ 2021-01-02 15:30  九州霜  阅读(134)  评论(0编辑  收藏  举报