/ Vijos / 题库 / FBI树 /

题解

157 条题解

  • 0
    @ 2016-08-28 00:54:48

    用枚举类加上了线段树的建树思想,醉了。。
    C++
    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    enum treeType {B,I,F};
    ostream & operator<<(ostream & out, const treeType & display)
    {
    switch (display)
    {
    case B:out << 'B'; break;
    case I:out << 'I'; break;
    case F:out << 'F'; break;
    default:break;
    }
    return out;
    }
    treeType operator+(treeType & a, treeType & b)
    {
    treeType ans;
    if (a == b) ans = a;
    else ans = F;
    return ans;
    }
    template <typename T>
    void LRD(vector<T> &tree,int root=1)
    {
    if (root < tree.size())
    {
    LRD(tree, root * 2);
    LRD(tree, root * 2 + 1);
    cout << tree[root];
    }
    }
    int main()
    {
    int n;
    cin >> n;
    int numOfnode = pow(2, n+1)-1;
    int leafBegin = pow(2, n );
    // cout << numOfnode << endl << leafBegin << endl;
    vector<treeType> tree(numOfnode+1);
    char temp;
    for (int i = leafBegin; i <= numOfnode; i++)
    {
    cin >> temp;
    if (temp == '0') tree[i] = B;
    else tree[i] = I;
    }
    for (int i = leafBegin - 1; i >= 1; i--)
    {
    tree[i] = tree[2 * i] + tree[2 * i + 1];
    }
    LRD(tree);
    //system("pause");
    return 0;
    }

  • 0
    @ 2016-08-12 18:30:29
    var n:longint;
      s:ansistring;
    procedure fbi(s:ansistring);
    var len,a,b:longint;
      begin
        len:=length(s);
        if len=1 then if s[1]='0' then write('B') else write('I')
        else
          begin
            fbi(copy(s,1,len div 2));
            fbi(copy(s,len div 2+1,len-len div 2));
            a:=pos('0',s);
            b:=pos('1',s);
            if (a<>0) and (b<>0) then write('F');
            if (a=0) and (b<>0) then write('I');
            if (a<>0) and (b=0) then write('B');
          end;
      end;
    begin
      readln(n);
      readln(s);
      fbi(s);
      readln;
      end.
    

    楼下好6,我的15ms

  • 0
    @ 2016-07-17 15:49:08

    水题不多说,**以空间换时间**
    0ms与1240kb的苦逼程序
    直接分治~
    注意**string过不了要ansistring!!**
    ```pascal
    program FBI;
    var bi:array[1..10000]of char;
    n,i,count:longint;
    s:ansistring;

    function judge(a:ansistring):char;
    var i:longint;
    t:char;
    begin
    t:=a[1];
    for i:=2 to length(a) do
    if t<>a[i] then exit('F');
    if t='0' then exit('B');
    exit('I');
    end;

    procedure merge(s:ansistring;n:longint);
    var i:longint;
    begin
    if n=1 then
    begin
    if s='0' then write('B') else write('I');
    exit;
    end;
    merge(copy(s,1,length(s)div 2),n div 2);
    merge(copy(s,length(s)div 2 +1,length(s)),n div 2);
    write(judge(s));
    end;

    begin
    readln(n);
    readln(s);
    count:=1;
    for i:=1 to n do count:=count*2;
    merge(s,count);
    end.

  • 0
    @ 2016-07-09 23:09:22
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <cctype>
    #include <string>
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <queue>
    #include <utility>
    #include <map>
    #include <set>
    #include <climits>
    #include <stack>
    
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    
    struct TreeNode
    {
        char value;
        TreeNode* left_child;
        TreeNode* right_child;
    };
    
    char str[1030];
    int n;
    
    TreeNode* BuildTree(char* str, int len)
    {
        if (len == 0)
            return 0;
    
        int type = str[0] - '0';
        if (len != 1)
        {
            for (int i = 1; i < len; i++)
            {
                if (str[i] != str[0])
                {
                    type = -1;
                    break;
                }
            }
        }
    
        TreeNode* node = new TreeNode;
    
        if (type == -1)
        {
            node->value = 'F';
        }
        else if (type == 0)
        {
            node->value = 'B';
        }
        else
        {
            node->value = 'I';
        }
    
        if (len == 1)
        {
            node->left_child = 0;
            node->right_child = 0;
        }
        else
        {
            node->left_child = BuildTree(str, len / 2);
            node->right_child = BuildTree(str + len / 2, len - len / 2);
        }
    
        return node;
    }
    
    void PostOrder(TreeNode* node)
    {
        if (node == 0)
            return ;
        PostOrder(node->left_child);
        PostOrder(node->right_child);
        printf("%c", node->value);
    }
    
    int main()
    {
        while(~scanf("%d", &n))
        {
            getchar();
            gets(str);
            //puts(str);
            TreeNode* node = BuildTree(str, strlen(str));
            //cout << "build success" << endl;
            PostOrder(node);
            printf("\n");
        }
    
        return 0;
    }
    
  • 0
    @ 2016-07-09 15:51:57
    #include <iostream>
    #include <cstring> 
    #include <cstdio>
    using namespace std;
    int n;
    char a[1025];
    inline void fbi(int i,int j){
        if(i<=j){
            int mid=(i+j)/2,I=0,B=0;
            if(i!=j){
            fbi(i,mid);
            fbi(mid+1,j);
            }
            while(i<=j)if(a[i++]=='0')B++;else I++;
            if(B>0&&I>0)cout<<'F';
            else if(B>0)cout<<'B';
            else cout<<'I';
        }
    }
    int main(int argc, char const *argv[]){
        /* code */
        //freopen("155.in","r",stdin);
        //freopen("155.out","w",stdout);
        ios::sync_with_stdio(false);
        cin.tie(NULL);
        cin>>n>>a;
        fbi(0,strlen(a)-1);
        return 0;
    }
    
  • 0
    @ 2016-05-27 21:04:26

    发一个弱弱的题解,思路是模拟栈,并在栈里面增设一个flag数组,遇到栈中超过两个字符并且两个字符的flag相同就进行处理成一个字符并且这个字符的flag+1;

    include <stdio.h>

    include <math.h>

    char a[1500][2];

    void puttree(char c)
    {
    if (c == '1')
    putchar('I');
    else if (c == '0')
    putchar('B');
    else
    putchar('F');
    }

    int stack_push(int top)
    {
    if (a[top][0] != a[top-1][0]) {
    a[top-1][0] = '2';
    }
    a[top-1][1]++;
    puttree(a[top-1][0]);
    return top-1;
    }

    int main (void)
    {
    int top = -1, n, flag, i, power;
    char c;
    scanf("%d",&n);
    getchar();
    power = pow(2,n);
    for (i=0; i<power; i++) {
    c = getchar();
    a[++top][0] = c;
    a[top][1] = flag;
    puttree(c);
    while (top >= 1 && a[top][1] == a[top-1][1]) {
    top = stack_push(top);
    }
    }
    putchar('\n');
    return 0;
    }

  • 0
    @ 2016-05-01 17:17:24

    水题
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N = 100003;
    int n, t[1025];
    char s[1025];
    void dfs(int l, int r) {
    if (l == r) {putchar(t[l] == 1 ? 'I' : 'B'); return;}
    int mid = (l + r) >> 1;
    dfs(l, mid); dfs(mid + 1, r);
    bool flag0 = 0, flag1 = 0;
    for(int i = l; i <= r; ++i)
    if (t[i] == 0) flag0 = 1;
    else flag1 = 1;
    if (flag0 && flag1) putchar('F');
    else putchar(flag0 ? 'B' : 'I');
    }
    int main() {
    scanf("%d", &n);
    scanf("%s", s);
    int len = strlen(s);
    for(int i = 0 ;i < len; ++i)
    t[i + 1]=s[i]-'0';
    dfs(1, len);
    return 0;
    }

  • 0
    @ 2016-04-20 19:28:28

    var
    i,n:longint;
    a:array[1..1024] of char;

    procedure try(p,q:longint);
    var
    n0,n1,i:longint;
    begin
    n0:=0;
    n1:=0;
    for i:=p to q do
    if a[i]='0' then inc(n0)
    else inc(n1);
    if p=q then
    begin
    if n1=1 then begin write('I'); exit; end;
    if n0=1 then begin write('B'); exit; end;
    end;
    try(p,(p+q) div 2);
    try((p+q) div 2+1,q);
    if q-p+1=n0 then write('B')
    else if q-p+1=n1 then write('I')
    else write('F');
    end;

    begin
    readln(n); n:=1 shl n;
    for i:=1 to n do read(a[i]);
    try(1,n);
    end.

  • 0
    @ 2016-04-18 17:52:13
  • 0
    @ 2016-04-18 13:03:29
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long LL;
    const int N = 5000 + 24;
    inline int LC(int x) {return x << 1;}
    inline int RC(int x) {return x << 1 | 1;}
    int n;
    char s[N];
    char sum[N << 2];
    void Update(int x)
    {
        if(sum[LC(x)] == sum[RC(x)])
            sum[x] = sum[LC(x)];
        else
            sum[x] = 'F';
        printf("%c",sum[x]);
    }
    void Buile(int x, int l, int r)
    {
        if(l == r)
        {
    
            s[l-1] == '0' ? sum[x] = 'B' : sum[x] = 'I';
            printf("%c",sum[x]);
            return;
        }
        int mid =(l + r) >> 1;
        Buile(LC(x),l, mid);
        Buile(RC(x),mid+1,r);
        Update(x);
    }
    int main()
    {
        while(~scanf("%d",&n))
        {
            scanf("%s",&s);
            Buile(1,1,1 << n);
            printf("\n");
        }
    }
    
  • 0
    @ 2016-01-09 02:20:21

    不知道为什么出错啊

    import java.io.IOException;
    import java.util.Scanner;

    public class Main {

    static char a[] = new char[1100];
    public static void main(String[] args) throws IOException {
    Scanner sc = new Scanner(System.in);

    int n = sc.nextInt();
    int sum = 1;
    for(int i=0;i<n;i++)
    sum = sum*2;
    for(int i=0;i<sum;i++){
    a[i] = (char)System.in.read();
    }
    judge(0,sum-1);
    }
    private static char judge(int a1,int a2){
    int i,t0,t1;
    if(a1 == a2){
    if(a[a1] == '0') {System.out.print("B");return 'B';}
    else System.out.print("I");return 'I';
    }
    else{
    i = (a2-a1-1)/2;
    char j1 = judge(a1,a1+i);
    char j2 = judge(a2-i,a2);
    t0=0; t1=0;
    if(j1 == 'I'&&j2 == 'I') {System.out.print("I");return 'I';}
    else if(j1 == 'B'&&j2 == 'B') {System.out.print("B");return 'B';}
    else System.out.print("F");return 'F';
    }
    }
    }

  • 0
    @ 2015-11-26 20:28:28

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long LL;
    const int N = 5000 + 24;
    inline int LC(int x) {return x << 1;}
    inline int RC(int x) {return x << 1 | 1;}
    int n;
    char s[N];
    char sum[N << 2];
    void Update(int x)
    {
    if(sum[LC(x)] == sum[RC(x)])
    sum[x] = sum[LC(x)];
    else
    sum[x] = 'F';
    printf("%c",sum[x]);
    }
    void Buile(int x, int l, int r)
    {
    if(l == r)
    {

    s[l-1] == '0' ? sum[x] = 'B' : sum[x] = 'I';
    printf("%c",sum[x]);
    return;
    }
    int mid =(l + r) >> 1;
    Buile(LC(x),l, mid);
    Buile(RC(x),mid+1,r);
    Update(x);
    }
    int main()
    {
    while(~scanf("%d",&n))
    {
    scanf("%s",&s);
    Buile(1,1,1 << n);
    printf("\n");
    }
    }

  • 0
    @ 2015-10-31 21:36:14

    构造完全二叉树即可。
    就是不知道为什么在本地测试时输出到文件总是有问题。
    问下:cin不是会过滤行末的空格么,为什么cin>>n后还要加一句getchar()........
    /*
    ID:
    LANG:
    TESK:
    */
    #include <iostream>
    #include <fstream>
    //#include <cstdio>
    //#include <cstdlib>
    #include <string>
    //#include <cstring>
    //#include <cmath>
    //#include <algorithm>
    using namespace std;
    typedef long long longint;
    const string file_name = "p1114";
    const string file_in_name = file_name+".in";
    const string file_out_name = file_name+".out";
    const int N=2048;
    //const int M=100;
    longint n,m;
    string st;
    string t[N];
    char f[N];
    char cha(string s)
    {
    longint i=1,l=s.length();
    while(s[i]==s[i-1]&&i<l)i++;
    if(i==l)
    if(s[0]=='1')return 'I';
    else return 'B';
    else return 'F';
    }
    int pro(longint i)
    {
    longint l=t[i].length();
    if(l<=1)return 0;
    l=l>>1;
    longint l1=i<<1,l2=l1+1;
    t[l1].assign(t[i],0,l);
    f[l1]=cha(t[l1]);
    t[l2].assign(t[i],l,l);
    f[l2]=cha(t[l2]);
    pro(l1);
    pro(l2);
    return l;
    }
    int print(longint i)
    {
    if(i>=(1<<n)&&i<(1<<(n+1))){cout<<f[i];return 0;}
    print(i<<1);
    print((i<<1)+1);
    cout<<f[i];
    return 0;
    }
    int main()
    {
    //ifstream cin(file_in_name.c_str(),ios::in);
    //ofstream cout(file_out_name.c_str(),ios::out);
    //freopen(file_in_name.c_str(),"r",stdin);
    //freopen(file_out_name.c_str(),"w",stdout);
    cin>>n;
    getchar();
    getline(cin,t[1]);
    f[1]=cha(t[1]);
    //cout<<t[1];
    //cout<<cha(t[1]);
    pro(1);
    //for(int i=1;i<(1<<(n+1));i++)cout<<i<<':'<<f[i]<<endl;
    print(1);
    //cout<<f[1];
    //cin.close();
    //cout.close();
    return 0;
    }

  • 0
    @ 2015-08-01 17:39:15

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;

    int num[1030];
    char k[1030];

    void check(int a,int b){
    int c0 = 0, c1= 0;
    for(int i=a; i<=b; i++){
    if(num[i] == 1)
    c0 = 1;
    if(num[i] == 0)
    c1 = 1;
    if(c0 == 1 && c1 == 1){
    cout<<"F";
    return;
    }
    }
    if(c0 == 1)
    cout<<"I";
    else
    cout<<"B";
    }

    void back(int a, int b){
    if(a == b){
    check(a, b);
    return;
    }
    if(a > b)
    return;
    back(a, (a+b)/2);
    back((a+b)/2+1, b);
    check(a, b);
    }

    int main()
    {
    int n;
    cin>>n;
    int bri=1;
    for(int i=1; i<=n; i++)
    bri *= 2;
    for(int i=1; i<=bri; i++){
    cin>>k[i];
    num[i] = k[i] - '0';

    }
    back(1, bri);
    system("pause");
    return 0;
    }
    水一发。。。

  • 0
    @ 2015-06-02 09:53:45

    完全不懂树结构,只好直接按题目模拟过程

    #include<stdio.h>
    int main( )
    {
    char a[12][1500],t;
    int i,n,l=1,j,k,flag[11]={0},mol[11]={0};

    scanf("%d\n",&n);

    for(i=1;i<=n;i++)
    l=l*2;

    for(i=1;i<=l;i++)
    {
    scanf("%c",&t);
    if (t=='0') a[1][i]='B';
    else a[1][i]='I';
    }

    k=l;

    for(i=2;i<=n+1;i++)
    {

    for(j=2;j<=k;j=j+2)
    {
    if(a[i-1][j]!=a[i-1][j-1]) a[i][j/2]='F';
    else a[i][j/2]=a[i-1][j];
    }

    k=k/2;

    }

    for(i=1;i<=l;i++)
    {
    printf("%c",a[1][i]);
    flag[1]++;

    for(j=1;j<=n+1;j++)
    if(flag[j]%2==0 && flag[j]!=mol[j]) {printf("%c",a[j+1][flag[j]/2]);mol[j]=flag[j];flag[j+1]++;}
    }

    return 0;

    }

  • 0
    @ 2015-03-26 23:50:55

    var
    s:ansistring;
    n,sq:longint;

    procedure wtf(str:string);
    var
    i,j,k,m:longint;
    s1,s2:ansistring;
    begin
    j:=0; k:=0; m:=length(str) div 2;
    if length(str)=1 then
    begin
    if str='0' then write('B')
    else write('I');
    end;
    if (length(str)>1) then
    begin
    s1:=copy(str,1,m);
    s2:=copy(str,m+1,m);
    wtf(s1); wtf(s2);
    for i:=1 to length(str) do
    begin
    if str[i]='0' then inc(j)
    else inc(k);
    end;
    if (j=0) then write('I');
    if (k=0) then write('B');
    if (j<>0) and (k<>0) then write('F');
    end;
    end;

    begin
    readln(sq);
    readln(s);
    if (sq=0) then write('B')
    else wtf(s);
    readln();
    end.

    各位大神,请问为什么一直是80分,第一个和最后一个数据过不去

  • 0
    @ 2015-02-12 18:51:39

    测试数据 #0: Accepted, time = 15 ms, mem = 196764 KiB, score = 10
    测试数据 #1: Accepted, time = 0 ms, mem = 196504 KiB, score = 10
    测试数据 #2: Accepted, time = 0 ms, mem = 196504 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 196500 KiB, score = 10
    测试数据 #4: Accepted, time = 0 ms, mem = 196504 KiB, score = 10
    测试数据 #5: Accepted, time = 0 ms, mem = 196508 KiB, score = 10
    测试数据 #6: Accepted, time = 0 ms, mem = 196500 KiB, score = 10
    测试数据 #7: Accepted, time = 15 ms, mem = 196500 KiB, score = 10
    测试数据 #8: Accepted, time = 0 ms, mem = 196504 KiB, score = 10
    测试数据 #9: Accepted, time = 0 ms, mem = 196760 KiB, score = 10
    Accepted, time = 30 ms, mem = 196764 KiB, score = 100
    代码
    var
    x,y,k,i,j,n,l,t,nv,nan,m:longint;
    b,c,a:array[0..20001]of longint;
    f:array[0..10000,0..10000]of integer;
    s:ansistring;
    procedure shuchu(s,w:longint);
    var
    i,j,k:longint;
    begin
    if s<w then shuchu(s,(s+w)div 2);
    if s<w then shuchu((s+w)div 2+1,w);
    case f[s,w] of
    0:write('B');
    1:write('I');
    2:write('F');
    end;
    end;

    procedure fbi(s,w:longint);
    var
    j,l,k:longint;
    begin
    if s=w then exit;
    fbi(s,(s+w)div 2);
    fbi((s+w)div 2+1,w);
    if f[s,(s+w)div 2]=f[(s+w)div 2+1,w] then f[s,w]:=f[s,(s+w)div 2] else f[s,w]:=2; // writeln(f[s,w]);
    end;

    begin

    readln(n); m:=1;
    for i:=1 to n do m:=m*2;
    readln(s);
    for i:=1 to m do f[i,i]:=ord(s[i])-48;
    //for i:=1 to m do write(f[i,i]);
    readln;

    fbi(1,m);
    shuchu(1,m);

    writeln;
    readln;
    end.

  • 0
    @ 2015-02-07 16:23:06

    不用后序遍历,只要按照后序遍历的顺序构建就行了,根结点直接输出。
    还有,string不够长,要用ansistring。

    Pascal Code

    var
    s:ansistring;
    n:longint;
    function fbi(s:ansistring;len:longint):char;
    var
    i:longint;
    flag0,flag1:boolean;
    begin
    flag0:=false;
    flag1:=false;
    for i:=1 to len do
    begin
    if s[i]='0' then flag0:=true;
    if s[i]='1' then flag1:=true;
    if flag0 and flag1 then exit('F');
    end;
    if flag0 then exit('B');
    if flag1 then exit('I');
    end;
    procedure createtree(s:ansistring;len:longint);
    begin
    if len>1 then createtree(copy(s,1,len div 2),len div 2);
    if len>1 then createtree(copy(s,len div 2+1,len div 2),len div 2);
    write(fbi(s,len));
    end;
    begin
    readln(n);
    readln(s);
    createtree(s,length(s));
    end.

  • 0
    @ 2014-11-07 13:26:57

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    char p[15000];
    char x[15000];
    char f(char ,int);
    int main()
    { memset(x,'#',sizeof(x));
    //freopen("fbi.in","r",stdin);
    //freopen("fbi.out","w",stdout);
    int n;
    cin>>n;
    scanf("%s",p);
    void create(char
    ,int,int);
    create(p,1,strlen(p));
    void h(int);
    h(1);
    return 0;

    }

    void h(int m)
    {
    if(x[m*2]!='#') h(m*2);
    if(x[m*2+1]!='#') h(m*2+1);
    cout<<x[m];
    }

    void create(char *s,int i,int len)
    {

    x[i]=f(s,len);
    if(len>1)
    {
    create(s,i*2,len/2);
    create(s+len/2,i*2+1,len/2);
    }
    }

    char f(char *s,int len)
    { bool t1=false;
    bool t2=false;
    for(char *i=s;i!=s+len;++i)
    {
    if(*i=='0') t1=true;
    if(*i=='1') t2=true;
    }
    if(t1==true&&t2!=true) return 'B';
    if(t1!=true&&t2==true) return 'I';
    if(t1==true&&t2==true) return 'F';
    }

  • 0
    @ 2014-11-01 15:34:46

    type nn=record
    f,l,r:longint;
    n:char;
    end;

    var
    i,n,t,l,top:longint;
    s:ansistring;
    a:array[1..10000]of longint;
    f:array[1..10000]of nn;

    procedure lala(i:longint);
    begin
    f[i].f:=i div 2;
    f[i].l:=i*2;
    f[i].r:=i*2+1;
    i:=i+1;
    if i>l then exit;
    lala(i);
    end;

    procedure ee(i:longint);
    begin
    if (f[i].l<>0)and(f[i].l<l*2) then ee(f[i].l);
    if (f[i].r<>0)and(f[i].r<l*2) then ee(f[i].r);
    write(f[i].n);
    end;

    Begin
    readln(n);
    l:=1;
    for i:=1 to n do l:=l*2;
    readln(s);
    for i:=1 to l do a[i]:=ord(s[i])-ord('0');
    top:=2*l-1;
    lala(1);
    for i:=l to top do if a[i-l+1]=0 then f[i].n:='B' else f[i].n:='I';
    for i:=l-1 downto 1 do begin
    f[i].n:='F';
    if (f[f[i].l].n='I') and (f[f[i].r].n='I') then f[i].n:='I';
    if (f[f[i].l].n='B') and (f[f[i].r].n='B') then f[i].n:='B';
    end;
    ee(1);
    End.

信息

ID
1114
难度
3
分类
数据结构 | 点击显示
标签
递交数
4150
已通过
2215
通过率
53%
被复制
25
上传者