P1087 FBI树
题目描述
我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串。
FBI树是一种二叉树,它的结点类型也包括F结点,B结点和I结点三种。由一个长度为2^N的“01”串S可以构造出一棵FBI树T,递归的构造方法如下:
1) T的根结点为R,其类型与串S的类型相同;
2) 若串S的长度大于1,将串S从中间分开,分为等长的左右子串S1和S2;由左子串S1构造R的左子树T1,由右子串S2构造R的右子树T2。
现在给定一个长度为2^N的“01”串,请用上述构造方法构造出一棵FBI树,并输出它的后序遍历序列。
输入输出格式
输入格式:
第一行是一个整数N(0 <= N <= 10),第二行是一个长度为2^N的“01”串。
输出格式:
包括一行,这一行只包含一个字符串,即FBI树的后序遍历序列。
输入输出样例
3 10001011
IBFBBBFIBFIIIFF
说明
对于40%的数据,N <= 2;
对于全部的数据,N <= 10。
noip2004普及组第3题
1 #include2 #include 3 4 struct node 5 { 6 char c; 7 node *lc, *rc; //左孩子右孩子 8 }; 9 char a[1030]; 10 11 // node * 要传引用哦 12 void fbicreat(int lr, int rr, node *&p) 13 { 14 p = new node; 15 p->c = 'F'; //先设置成F 后面再判断 16 17 //如果左右位置在一起,则表示此时的结点为叶 18 if(lr == rr) 19 { 20 if(a[lr] == '0') 21 p->c = 'B'; 22 else if(a[lr]=='1') 23 p->c = 'I'; 24 p->lc = p->rc = NULL; 25 return; 26 } 27 28 //这里的判断参考了 keyword_ 的做法 29 bool b0, b1; //标志b0是0是否出现 30 b0 = b1 = 0; //标志b1是1是否出现 31 for(int i=lr; i<=rr; i++) 32 { 33 if(a[i]=='0') b0 = 1; 34 else if(a[i]=='1') b1 = 1; 35 } 36 if(b0 && !b1) //相信大家都能看懂 37 p->c = 'B'; 38 else if(b1 && !b0) 39 p->c = 'I'; 40 41 //二叉树二分咯 42 fbicreat(lr, (lr+rr)/2, p->lc); 43 fbicreat((lr+rr)/2+1, rr, p->rc); 44 } 45 46 47 48 void houxu(node *p) 49 { 50 if(p) //如果是一棵真树 51 { //后序遍历: 左 右 根 52 houxu(p->lc); 53 houxu(p->rc); 54 printf("%c", p->c); 55 } 56 } 57 58 59 int main() 60 { 61 int n; 62 scanf("%d ", &n); //这里记得把回车给读取了 63 n = pow(2, n); 64 for(int i=0; i ) 65 scanf("%c", a+i); 66 67 node *p; 68 //从数组0位置到n-1位置建立FBI树 69 fbicreat(0, n-1, p); 70 houxu(p); 71 return 0; 72 }