前言:左右移操作一定要检查左右移的位数不是负数,两个等价的表达式,在边界数据输入后,结果天差地别 如:1<<n 和2<<(n-1),输入正数时两者等价,输入0时2<<-1未定义操作,会出现奇奇怪怪的值,使得输入函数的参数出错,最终无限递归,内存超限,所以当时我都想着用short来记录三种情况了,结果一直是90%内存超限(谁知道我改了多久,当时都想着用vector动态分配内存了)。但是下面的代码也没再改回来了,用short算了

PS:早知道用cmath中的pow了,@myself->get.reason(use too 复杂 "<<" replace pow(2,n);)

AC代码:

#include<iostream>
#include<string>
using namespace std;
short s[1025];
//0->B,1->I,2->F
short solve(int l, int r)
{
    if(l==r)//说明已经到了最下面一层了,就一个数了,直接判断
    {
        if (s[l] == 0) {cout<<'B';return 0;}
        else {cout<<'I';return 1;}
    }
    short mid=(l+r)>>1;//即/2
  //下面的操作也可以遍历每一次递归的字符串,有0 flag0=1,有1 flag1=1,但我觉得那样没有充分利用好每一次递归的信息
  //下面的操作符合“左右根”,先左再右,然后根是他们俩的父亲(更上面一层)
    short prel=solve(l,mid);//把左子树的类型判断出来
    short prer=solve(mid+1,r);//把右子树的类型判断出来
    if((prel == 0) && (prer == 0))//左右都只有0,那么合成之后的大的(逆向思维,或者说递归中的归的思想)也只有0
    {
        cout<<'B';return 0;
    }
    else if((prel == 1) && (prer ==1))//左右都只有1
    {
        cout<<'I';return 1;
    }
    else//左右既有0也有1
    {
        cout<<'F';return 2;
    }
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    int n;cin>>n;
    cin.get();//把换行去掉
    for(int i=0; i<(1<<n); ++i)
    {
        s[i]=cin.get()-'0';//一位一位输入,cin.get()得到的是ascii码
    }
    solve(0,(1<<n)-1);//相当于1*pow(2,n)
    return 0;
}