P1087 FBI树 二叉树

时间:2022-04-25 09:37:54

  

题目描述

我们可以把由“00”和“11”组成的字符串分为三类:全“00”串称为BB串,全“11”串称为I串,既含“00”又含“11”的串则称为F串。

FBIFBI树是一种二叉树,它的结点类型也包括FF结点,BB结点和I结点三种。由一个长度为2^N2N的“0101”串S可以构造出一棵FBIFBI树TT,递归的构造方法如下:

1) TT的根结点为RR,其类型与串SS的类型相同;

2) 若串SS的长度大于11,将串SS从中间分开,分为等长的左右子串S_1S1S_2S2;由左子串S_1S1构造R的左子树T_1T1,由右子串S_2S2构造RR的右子树T_2T2

现在给定一个长度为2^N2N的“0101”串,请用上述构造方法构造出一棵FBIFBI树,并输出它的后序遍历序列。

输入输出格式

输入格式:

 

第一行是一个整数N(0 \le N \le 10)N(0N10),

第二行是一个长度为2^N2N的“0101”串。

 

输出格式:

 

一个字符串,即FBIFBI树的后序遍历序列。

 

输入输出样例

输入样例#1:  复制
3
10001011
输出样例#1:  复制
IBFBBBFIBFIIIFF

说明

对于40%的数据,N \le 2N2;

对于全部的数据,N \le 10N10。

noip2004普及组第3题

 

水题 

但是代码写的很糟

(L+R)>>1 会陷入死循环

P1087 FBI树 二叉树P1087 FBI树 二叉树
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define LL long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 2147483647
#define N 500000+50
char s[1<<11];
void build(int L,int R)
{
    int one=0,zero=0;
    int mid=(L+R)>>1;
    if(L==R)
    {
        if(s[L]=='1')
            printf("I");
        else printf("B");return ;
    }
    build(L,mid);
    build(mid+1,R);
    rep(i,L,R)
    {
        if(s[i]=='1')one++;
        else zero++;
    }
    if(one&&zero)
        printf("F");
    else if(one&&!zero)
        printf("I");
    else printf("B");
    return ;
}
int main()
{
    int n;
    RI(n);
    RS(s+1);
    build(1,pow(2,n));
    return 0;
}
View Code

 

修改一下即可:

P1087 FBI树 二叉树P1087 FBI树 二叉树
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define LL long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 2147483647
#define N 500000+50
char s[1<<11];
void build(int L,int R)
{
    int mid=(L+R)>>1;
    
    if(R>L)
    {
        build(L,mid);
        build(mid+1,R);
    }
    int one=0,zero=0;
    rep(i,L,R)
    {
        if(s[i]=='1')one++;
        else zero++;
    }
    if(one&&zero)
        printf("F");
    else if(one&&!zero)
        printf("I");
    else printf("B");
    return ;
}
int main()
{
    int n;
    RI(n);
    RS(s+1);
    build(1,pow(2,n));
    return 0;
}
View Code