NC16660 [NOIP2004]FBI树

题目

  • 原题地址:[NOIP2004]FBI树
  • 题目编号:NC16660
  • 题目类型:分治
  • 时间限制:C/C++ 1秒,其他语言2秒
  • 空间限制:C/C++ 131072K,其他语言262144K

1.题目大意

  • 给一个长度为 2^n 的由 0 和 1 构成的序列,从根节点开始每次对半分,构成一个二叉树
  • F:节点中的字符串同时包含 0 和 1
  • B:节点中的字符串只包含 0
  • I:节点中的字符串只包含 1
  • 输出后序遍历的对应FBI序列

2.题目分析

  • 按题意模拟即可,但也可以不建树

3.题目代码

纯模拟

#include <bits/stdc++.h>

using namespace std;

typedef struct FBI{
    int type;
    string s;
    FBI *lc,*rc;
}FBI;

int init(FBI *n){
    int len = n->s.length();
    if(len!=1)
    {
        int mid = len/2;
        FBI *l = new FBI();
        FBI *r = new FBI();
        n->lc = l;
        n->rc = r;
        l->s = n->s.substr(0,mid);
        r->s = n->s.substr(mid,mid);
        int t = init(l) + init(r);
        if(t==0)
            n->type = 0;// 0 0
        else if(t==1)
            n->type = 4;// 0 1
        else if(t==2)
            n->type = 1;// 1 1
        else
            n->type = 4;
        return n->type;
    }
    else
    {
        n->type = n->s[0] - '0';
        return n->type;
    }
}

void after(FBI *n){
    if(n->lc)
    {
        after(n->lc);
        after(n->rc);
    }
    if(n->type==0)
        cout << 'B';
    else if(n->type==1)
        cout << 'I';
    else if(n->type==4)
        cout << 'F';
}

int main() {
    int n;
    FBI *head = new FBI();
    cin >> n;
    cin >> head->s;
    init(head);
    after(head);
}

直接求解

#include <bits/stdc++.h>

using namespace std;

char FBI(string s) {
    if (s.length() > 1) {
        cout << FBI(s.substr(0, s.length() / 2));
        cout << FBI(s.substr(s.length() / 2, s.length() / 2));
    }
    if (s == string(s.length(), '0')) return 'B';
    if (s == string(s.length(), '1')) return 'I';
    return 'F';
} 

int main() {
    int n;
    string s;
    cin >> n >> s;
    cout << FBI(s) << endl;
    return 0;
}
posted @ 2022-07-26 19:46  仪战群儒  阅读(46)  评论(0)    收藏  举报