#include<bits/stdc++.h>
using namespace std;
struct node{//定义节点
int num;//赋的值
string str;//所在的串
int father_num;//父节点
int sonl=0,sonr=0,visit;//sonl:左孩子,sonr:右孩子,visit:判断输没输出,用于后序遍历函数
}n [2048];//已经讲过2048的来历啦!
int t=1;//所赋的值的变量,说实话也就是给每个点标的号
string a;//输入的字符串
void gou_zao_shu(int from/*字符串起始点*/,int to/*字符串截止点*/,int l/*从哪里来(所谓的父节点)*/,int pds/*判断是父节点的左或右孩子*/){
n[t].num=t;//标号
n[t].father_num=l;//把l标记成父节点(因为1个点只有一个父节点)
string s;//本节点的字符串
for(int i=from;i<=to;i++){
s+=a[i];//连接(+在这里是连接的意思)
}
n[t].str=s;//存储字符串
if(pds==0){//来路是左孩子
n[l].sonl=n[t].num;//存为父节点的左孩子
}else{//来路是右孩子
n[l].sonr=n[t].num;//存为父节点的右孩子
}
t++;//标记的值++
if(from==to){//字符串长度为1(叶节点)
return;//免得死循环
}
int root=t-1;//把此次设成根(叶节点已经return了,不用担心叶节点死循环)
gou_zao_shu(from,(from+to)/2,root,0);//已验证过开始和结束,搜索左孩子,标记父节点。
gou_zao_shu((from+to)/2+1,to,root,1);//已验证过开始和结束,搜索左孩子,标记父节点。
return;//完美
}
void hou_xu_bian_li(int x){//后序遍历函数 注明一下:结构体visit其实并没有什么用,因为一个点只可能走一遍,但并不影响
if(n[x].num==0){//超出范围(想了想没太大用,但安全)
return;//拽回来
}
if(n[x].sonl==0&&n[x].sonr==0){//叶节点(左右孩子均为0)
bool fbi=true;//输出判断的变量
for(int i=0;i<n[x].str.length();i++){//循环判断
if(n[x].str[i]!=n[x].str[0]){//与第一个不一样
fbi=false;//有重的说明有重复,记为false
cout<<"F";//混合输出F
break;//跳出循环
}
}
if(fbi==true){//无重
if(n[x].str[0]=='1'){//第一个为1
cout<<"I";//输出I
}else{//第一个为0
cout<<"B";//输出B
}
}
n[x].visit=1;//标记已经处理过
return;//返回上一级
}
hou_xu_bian_li(n[x].sonl);//后序左孩子 (先遍历左)
hou_xu_bian_li(n[x].sonr);//后序右孩子 (先遍历右)
if(n[n[x].sonl].visit==1&&n[n[x].sonr].visit==1){//左右孩子都被遍历
bool fbi=true;//和上面叶节点的做一样处理进行输出
for(int i=0;i<n[x].str.length();i++){//循环每个字符
if(n[x].str[i]!=n[x].str[0]){//不一样
fbi=false;//改值
cout<<"F";//输出混合的要求
break;//跳出循环
}
}
if(fbi==true){//无重
if(n[x].str[0]=='1'){//按照要求输出
cout<<"I";
}else{
cout<<"B";
}
}
n[x].visit=1;//标记
return;//返回
}
return;//更安全
}
int main(){//终于到主函数了!
int nothing;//我认为给2^n无用
scanf("%d",¬hing);//把这个无用的玩意输入进来
cin>>a;//输入字符串
if(a.length()==1){//长度为1,注意!有点卡这这里!
if(a=="0"){//为0
cout<<"B";//输出B
}else{//为1
cout<<"I";//输出I
}
return 0;
}
//进行正常处理
//进行根节点处理
n[t].num=1;//整个串标为1,根节点
n[t].father_num=0;//无父节点
n[t].str=a;//储存字符串
t++;//把标记的变量++
//构造字符串树
gou_zao_shu(0,a.length()/2-1,1,0);//构造树(左孩子们)
gou_zao_shu((a.length()+1)/2,a.length()-1,1,1);//构造树(右孩子们)
//下面开始遍历
n[0].visit=1;//设置范围,避免越界
n[0].str="3";//设置,更保险
hou_xu_bian_li(1);//后序遍历
return 0;
}
P1087 [NOIP2004 普及组] FBI 树
于 2024-02-09 11:13:18 首次发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)