【递归】Vijos P1114 FBI树(NOIP2004普及组第三题)

题目链接:

  https://vijos.org/p/1114

题目大意

  把01串一分为二,左半边描述当前节点左子树,右半边描述右子树,子树全为1则为I节点,全为0则为B节点,混合则为F节点,直到当前串长度为1停止。

  给定01串,求FBI树后序。

题目思路:

  【递归】

  每次操作先操作左子树,再操作右子树,之后统计左右子树01状态,按照要求得到当前节点是 F B I中的哪一个。

  由于输出后序,所以可以每次操作完左右子树后直接输出该节点,当前串长度为1则输出完返回。

 

 1 //
 2 //by coolxxx
 3 //
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<string>
 7 #include<iomanip>
 8 #include<memory.h>
 9 #include<time.h>
10 #include<stdio.h>
11 #include<stdlib.h>
12 #include<string.h>
13 #include<stdbool.h>
14 #include<math.h>
15 #define min(a,b) ((a)<(b)?(a):(b))
16 #define max(a,b) ((a)>(b)?(a):(b))
17 #define abs(a) ((a)>0?(a):(-(a)))
18 #define lowbit(a) (a&(-a))
19 #define sqr(a) ((a)*(a))
20 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
21 #define eps 1e-8
22 #define J 10000
23 #define MAX 0x7f7f7f7f
24 #define PI 3.1415926535897
25 #define N 1504
26 using namespace std;
27 int n,m,lll,ans,cas;
28 int e[]={1,2,4,8,16,32,64,128,256,512,1024};
29 char s[N];
30 char p[]={'B','I','F'};
31 int work(int l,int r)
32 {
33     int ll,rr,mid=(l+r)>>1;
34     if(l==r)
35     {
36         printf("%c",p[s[l]=='1']);
37         return (s[l]=='1');
38     }
39     ll=work(l,mid);
40     rr=work(mid+1,r);
41     if(ll==rr)
42     {
43         printf("%c",p[ll]);
44         return ll;
45     }
46     else
47     {
48         printf("%c",p[2]);
49         return 2;
50     }
51 }
52 int main()
53 {
54     #ifndef ONLINE_JUDGE
55 //    freopen("1.txt","r",stdin);
56 //    freopen("2.txt","w",stdout);
57     #endif
58     int i,j,k;
59 //    while(~scanf("%s",s1))
60     while(~scanf("%d",&n))
61     {
62         scanf("%s",s);
63         work(0,e[n]-1);
64         puts("");
65     }
66     return 0;
67 }
68 
69 
70 /*
71 //
72 
73 //
74 */
View Code

 

posted @ 2016-04-18 17:39  Cool639zhu  阅读(626)  评论(0编辑  收藏  举报