提示:
这道题有两种解法,可以用麻烦的字符串解法,也可以直接从下往上构建树,不需要字符串,因为数据保证所给的树是满二叉树,所以整棵树的节点数为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 }