第一次写题解,挺有纪念意义的。。
刚看本题有点懵逼,但静心就能看出端倪,解读题意:题目中的黑体字就是引导你构造S这个01串的二叉树,然后结合题目中给的FBI的定义,把这棵树变成FBI树的形式(通过后序遍历)。还有一种思路:FOR循环判断该树有没有'1''0'决定此树是FBI中的一个,时间复杂度是NlongN,空间复杂度是logn,这种做法干净利索,找准S串的本质剖开,不过显然,FOR重复作业,复杂度没如下代码递归的好。
显然,由题目中所引导:S长度为2的N次方(首先没看见2^n,还设想了一下奇数的情况,但好像跟题目描述对应不起来,回头再看,这才发现。。。)以及二叉树的定义,我们可以想到二分法;又由父子关系,子树会对上一级产生影响,我们可以想到递归,代码可以着手写了(本质就是模拟二分和递归的过程)

```
#include<iostream>
#include<string>
#include <algorithm>
#include <cstdio>
using namespace std;
int l[1050];//2^10==1024,开全局变量,就不用指针传来传去了,容量还大,方便。
int digui(int a,int b)</cstdio></algorithm></string></iostream>

{ int m,n;

    if(b-a==1)//不断向下递归,直到两个相邻节点,如0,1;2,3; 
{
    if(l[a]==1)cout<<"I";//进行判断并输出 
    if(l[a]==0)cout<<"B";
    if(l[b]==1)cout<<"I";
    if(l[b]==0)cout<<"B";
if(l[b]==1&&l[a]==1)//由最底层节点判断倒数第二层树是什么类型 
    {cout<<"I"; return 1;}//而倒数第二层树再返回到上次调用它的地方,对其父产生影响  
else if(l[b]==0&&l[a]==0)
    {cout<<"B"; return 0;}
else {cout<<"F";return 3;}
}
if(b-a!=1)//这个细节不能漏掉,否则卡死在这次调用里。 
{m=digui(a,(a+b)/2);
n=digui((a+b)/2+1,b);
}
if(m==0&&n==0)//注意,if这个判断里必须要引入变量来代替函数,否则会进入判断条件中的函数调用,现学了断点调试才DE出这个BUG 
{  
    cout<<"B";
    return 0;//标志着该子树的身份, 返回到上次调用它的地方,对其父产生影响 (1) 
}
else if(m==1&&n==1)
{
    cout<<"I";
    return 1;//同(1) 
}else  
{
    cout<<"F";
    return 3;//同(1)
}

}
int main()
{
int t,k;
cin>>t;
int j;
k=1;
char h;
char x[1050];
scanf("%s",x);
if(t==0&&x[0]=='0')//刚开始代码总是90分,拜t=0所赐,我审题时一看到2的N次方就默认偶数了,没考虑这种情况,所以造成内存超限,一个点没过。还是由大神的帮助下才发现这个错误,感恩不尽!
{//另:代码超限可能是本身就有错误,而不是太大了跑不了。(我首先以为是递归复杂度的问题,还专门看了看递归优化方法,发现也用不上,我自认为这算法复杂度已经尽可能低了,空间上:树的深度没法变,每次递归空间大小也没啥可变的。时间上:我没有重复调用,返回时就是一直弹栈而已,如果有优化方法,麻烦跟我说一下)
cout<<"B"<<endl;return 0;
}
else if(t==0&&x[0]=='1')//所以来特殊照顾一下t=0
{
cout<<"I"<<endl;return 0;
}
else
{
h=x;
for(j=0;j<t;j++)k
=2;
for(j=0;j<k;j++)
{
l[j]=*h-48;
h++;//用字符串读进来,再将01串对应到L这个数组上去,有一点细节,字符指针未经初始化不可赋值,赋值号左值不能是常量等等,可以看看。
}
digui(0,j-1);//j-1还是j呢。
system("pause");
return 0;
}
}

```总之:这个题的细节还是蛮多的,值得写题解记录一下。
这个题超级长的自我思考,敲代码,DEBUG过程,让我想起了:纸上得来终觉浅,绝知此事要躬行。不过每一步,收获都是很大的。