【递归】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 */

时间: 2024-10-13 07:13:57

【递归】Vijos P1114 FBI树(NOIP2004普及组第三题)的相关文章

Vijos P1114 FBI树【DFS模拟,二叉树入门】

描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串. FBI树是一种二叉树1,它的结点类型也包括F结点,B结点和I结点三种.由一个长度为2^N的“01”串S可以构造出一棵FBI树T,递归的构造方法如下: 1) T的根结点为R,其类型与串S的类型相同: 2) 若串S的长度大于1,将串S从中间分开,分为等长的左右子串S1和S2:由左子串S1构造R的左子树T1,由右子串S2构造R的右子树T2. 现在给定一个长度为2^N的“0

【基础练习】【卡特兰数】栈 2003年NOIP全国联赛普及组第三题 题解

卡特兰数,这是一向掌握不大熟练的内容,今天借NOIP2003普及组的第三题来总结一下.当然由于原题数据弱抱,不需要高精.如果有时间我会不断补充这篇文章里的内容. 二话不说上代码 //Catalan #include<iostream> using namespace std; long long n,f[20]={0}; /*NO.1 f[n+1]=f[i]*f[n-i]from 0 to n plus f[0]=1 int main(){ cin>>n; f[0]=1;f[1]=

【递归】Vijos P1132 求二叉树的先序序列(NOIP2001普及组第三题)

题目链接: https://vijos.org/p/1132 题目大意: 给定二叉树的中序和后序遍历,求该二叉树先序遍历. 题目思路: [递归] 这题妥妥递归. 二叉树先序根左右,中序左根右,后序左右根. 对于每一颗子树,它的后序最后一个必定是根,于是可以根据根在中序的位置把左子树和右子树区分开来. 1 // 2 //by coolxxx 3 // 4 #include<iostream> 5 #include<algorithm> 6 #include<string>

vijos P1114 FBI树

二叉树,后续遍历 #include<iostream> using namespace std; string ans; int n; void build(int l,int r) { int mid=(r+l)/2; if(l!=r) { build(l,mid); build(mid+1,r); } int num0=0,num1=0; for(int i=l;i<=r;i++) { if(ans[i]=='0') num0++; else num1++; } if(r-l+1==

C++ P1188 火星人(NOIP2004普及组第3题)

#include<iostream>#include<cstdio>using namespace std; int N[10005],n,m,time,ap[10005],sign[10005];//ap用来表示某一元素在排列中出现的次数: bool get,out;//表示是否已经找到标准排列,是否已经输出: void DFS(int x){ if(x>n) { get=1;//找到标准排列: time++; if(time==m+1) { for(int i=1;i&l

求全排列的数学方法(洛谷1088 火星人noip2004普及组第4题)

人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法.这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学家,科学家破解这个数字的含义后,再把一个很小的数字加到这个大数上面,把结果告诉火星人,作为人类的回答. 火星人用一种非常简单的方式来表示数字――掰手指.火星人只有一只手,但这只手上有成千上万的手指,这些手指排成一列,分别编号为1,2,3…….火星人的任意两根手指都能随意交换位置,他们就是通过这方法计数的. 一

全排列(洛谷1061 Jam的计数法or NOIP 2006 普及组 第三题)

Jam是个喜欢标新立异的科学怪人.他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩. 在他的计数法中,每个数字的位数都是相同的(使用相同个数的字母),英文字母按原先的顺序,排在前面的字母小于排在它后面的字母.我们把这样的“数字”称为Jam数字.在Jam数字中,每个字母互不相同,而且从左到右是严格递增的.每次,Jam还指定使用字母的范围,例如,从2到10,表示只能使用{b,c,d,e,f,g,h,i,j}这些字母.如果再规定位数为5,那么,紧接在Jam数字“bd

Noip2012 普及组 第三题 摆花

博主声明: 新手第一次写动规的题解,如果出现错误请各位大力的喷,但不要骂脏话,最好告诉我怎么改,谢谢~.~ !!! 摆花 (flower.cpp/c/pas) [问题描述] 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共 m 盆. 通过调查顾客的喜好,小明列出了顾客最喜欢的 n 种花,从 1 到 n 标号. 为了在门口展出更多种花,规定第 i 种花不能超过 ai 盆, 摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列. 试编程计算,一共有多少种不同的摆花方案

守望者的逃离(2007年普及组第3题)| 贪心算法

守望者的逃离(2007年普及组第3题) [问题描述] 恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率深藏在海底的那加企图叛变,守望者在与尤迪安的交锋中遭遇了围杀.被困在一个荒芜的大岛上.为了杀死守望者,尤迪安开始对这个荒岛施咒,这座岛很快就会沉下去,到那时岛上的所有人都会遇难:守望者的跑步速度为17m/s, 以这样的速度是无法逃离荒岛的.庆幸的是守望者拥有闪烁法术,可在1s内移动60m,不过每次使用闪烁法术都会消耗魔法值10点.守望者的魔法值恢复的速度为4点/s,只有处在原地休息状态时才能恢复.