哈尔滨理工大学2016新生赛G题

FBI Tree的描述如下:

我们可以把由0和1组成的字符串分为3类,全0的串成为B串,全1的串成为I串,既含0又含1的串则称为F串。FBI树是一种二叉树,它的节点类型也包括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的01串,请用上述构造方法构造出一棵FBI树,并输出它的后续遍历序列。

Input

第一行为一个正整数T,表示测试数据组数。

每组测试数据第一行为一个整数N(0 <= N <= 10),第二行是一个长度为2^N的01串。

Output

输出FBI树的后续遍历序列。

Sample Input

2

1

10

3

10001011

Sample Output

IBF

IBFBBBFIBFIIIFF

利用指针建立二叉树,再进行后续遍历。

直接构造一棵二叉树即可,可以用最后一层节点来保存2^N个值,则他们的父亲结点的字符值就已经由左右儿子的B,I决定了,故不用保存串,只需要记录字符值。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <cmath>
 5 using namespace std;
 6 char s1[2]="0",s2[2]="1";
 7 char s[1200];
 8
 9 struct FBI
10 {
11     char s;
12     FBI *lchild,*rchild;
13 };
14
15 void showtree(FBI *head)//后序遍历树
16 {
17     if(head==NULL)
18     return;
19     showtree(head->lchild);
20     showtree(head->rchild);
21     printf("%c",head->s);
22 }
23
24 void maketree(FBI *node,char *p,int len)
25 {
26     if(len==1)
27     {
28         if(strstr(p,s1)&&strstr(p,s2))
29         node->s=‘F‘;
30         else if(strstr(p,s1)&&!strstr(p,s2))
31         node->s=‘B‘;
32         else if(!strstr(p,s1)&&strstr(p,s2))
33         node->s=‘I‘;
34         node->lchild=NULL;
35         node->rchild=NULL;
36         return;
37     }
38     char q[520],*r=new char;
39     FBI *z=new FBI;
40     strncpy(q,p,len/2);
41     r=p;
42     int i=len/2;
43     while(i--)
44     r++;        //将p一分为二 q和r两个字符串
45     if(strstr(q,s1)&&strstr(q,s2))   //判断左儿子的类型
46     z->s=‘F‘;
47     else if(strstr(q,s1)&&!strstr(q,s2))
48     z->s=‘B‘;
49     else if(!strstr(q,s1)&&strstr(q,s2))
50     z->s=‘I‘;
51     node->lchild=z;
52     FBI *c=new FBI;
53     if(strstr(r,s1)&&strstr(r,s2))    //判断右儿子的类型
54     c->s=‘F‘;
55     else if(strstr(r,s1)&&!strstr(r,s2))
56     c->s=‘B‘;
57     else if(!strstr(r,s1)&&strstr(r,s2))
58     c->s=‘I‘;
59     node->rchild=c;
60     maketree(z,q,len/2);   //递归构建
61     maketree(c,r,len/2);
62 }
63
64 int main()
65 {
66     int T;
67     scanf("%d", &T);
68     while(T--)
69     {
70         int n;
71         scanf("%d", &n);
72         scanf("%s",&s);
73         if(strlen(s)==1)
74         {
75             if(!strcmp(s,"0"))
76             printf("B\n");
77             else if(!strcmp(s,"1"))
78             printf("I\n");
79             continue;
80         }
81         FBI *head=new FBI;
82         char s1[2]="0",s2[2]="1";
83         if(strstr(s,s1)&&strstr(s,s2))
84         head->s=‘F‘;
85         else if(strstr(s,s1)&&!strstr(s,s2))
86         head->s=‘B‘;
87         else if(!strstr(s,s1)&&strstr(s,s2))
88         head->s=‘I‘;
89         maketree(head,s,(int)pow(2.0,(double)n));
90         showtree(head);
91         printf("\n");
92     }
93     return 0;
94 }
时间: 2024-10-10 14:35:25

哈尔滨理工大学2016新生赛G题的相关文章

哈尔滨理工大学2016新生赛F题

给出两个正整数m,n,在笛卡尔坐标系中选出四个不同的点,满足: (1)   点的横坐标是一个在区间[0,m]的整数. (2)   点的纵坐标是一个在区间[0,n]的整数. (3)   这四个点做顶点构成一个菱形. 有多少种满足以上条件的选择方法呢? Input 多组测试数据,每组输入两个正整数m,n(m <= 1000, n <= 1000). 处理到文件结束. Output 每行输出一个整数,表示有多少满足条件的选择方法. Sample Input 2 2 Sample Output 6 #

哈尔滨理工大学2016新生赛J题

给出一棵有N个节点(2 <= N <= 500000)和N-1条边的树,每条边拥有一个长度L(1 <= L <= 500000). 定义: (1)   path(u, v) = 顶点u和v之间的最短路. (2)   xor-distance(u, v) = ⊕e∈path(u,v)length(e), ⊕代表异或操作. 请计算出有多少对点的xor-distance的值等于K(0 <= K <= 500000).(v != u 并且 pair(u,v) = pair(v,

哈尔滨理工大学2016新生赛B题

做为长城上的卫士,影踪派一直守在螳螂高原上防止螳螂人卡拉克西的入侵.影踪派的长城可以近似看做是一条直线上依次编号为1~N的N个基地组成,编号相邻的两个基地之间由长城相连接,而影踪派掌门祝踏岚所在的影踪禅院位于编号为1的基地.     祝踏岚发现,每次螳螂人只会选择长城上的一个基地进行猛烈的攻击,所以,祝踏岚每次都要从影踪禅院赶到被攻击的基地亲临前线指挥战斗.但是,在长城上移动是很耗时的,为了能更快的赶到任何一个可能被攻击的基地,祝踏岚决定修建一对传送门.     一对传送门由两个入口组成,它能实

哈尔滨理工大学2016新生赛D题

陈月亮从小就热爱数学,这天老师讲到任何一个正整数N,我们可以很容易的找出N的所有因子,N1,N2,N3...,Nk,称N一共有k个因子(包含1和N本身). 求出k的值这个问题对于陈月亮来说实在是太简单了,于是她想要求出N所有因子的因子个数(如N1可能包含n1个因子(包含1和N1本身),N2可能包含n2个因子,...,Nk可能包含nk个因子),然后计算出S的值: 第一行为一个整数T(T <= 10000),代表测试数据的组数. 接下来T行每行一个正整数N(N < 2 ^ 31). 对于每组测试数

哈尔滨理工大学2016新生赛H题

陈月亮最喜欢的季节就是冬天了,这不看着窗外飘起了雪花,陈月亮开心的跑出屋来看雪.但是迷迷糊糊的陈月亮不知道自己是在做梦还是真的下起了雪.突然她想起了一句话,在真实世界中是没有两片一样的雪花的.于是你的任务就是比较这场雪中的所有雪花,如果出现了两朵完全一致的雪花,则证明陈月亮是在梦中. 每朵雪花用六个整数表示,范围在(1 – 10000000)之间,表示雪花六个花瓣的长度,六个整数的先后出现顺序可能是顺时针顺序也可能是逆时针顺序,并且可能是从任意一个花瓣开始的.比如说对同一个花瓣,描述方法可能是1

哈尔滨理工大学2016新生赛A题

一名骑着马的强盗闯进了原本平静祥和的棋盘村,为了通知村里的士兵来打败强盗,你必须要通知位于棋盘村最下方的兵营.棋盘村的地形就像是一张棋盘,你所在的位置为A点(0,0),兵营位于棋盘村的右下角B点(n,m).你每次只能走一步,可以选择向下走,也可以选择向右走.但是强盗所在的位置和强盗的马一次所能跳到的位置是不可以走过去的(强盗的马的移动方法与象棋中的马相同).请计算出从A点能够走到B点的所有路径条数. 首先输入一个整数t,代表有t组测试数据. 每组测试数据为四个整数,即B点的坐标(n,m)和强盗的

哈尔滨理工大学2016新生赛C题

一个r行c列的矩阵里的所有元素都为0或1,给出这个矩阵每一行的和以及每一列的和,那么是否存在这样一个矩阵满足条件呢,如果存在任意一个满足条件的矩阵则输出YES,如果不存在则输出NO? 每组测试数据第一行包含两个整数r,c,表示矩阵的行数和列数. 第二行包含r个32位无符号数,表示矩阵每行的和. 第三行包含c个32位无符号数,表示矩阵每列的和. (1 <= r,c <= 100000) 如果存在这样的一个01矩阵,输出YES,否则输出NO 首先需要判断行和列的总和是否相等,因为它们都应该是整个矩

哈尔滨理工大学2016新生赛I题

这次我们要写一个简单的行编辑器,当按下'#'时代表按下了一次退格符,当按下'@'时代表一个退行符(使当前行的字符全部无效).例如,假设从终端接收了这样的两行字符: Whil#lr#e(s#*s) [email protected](*s=#++) 则实际有效的是下列两行: While(*s) putchar(*s++) 请你编写一个程序,输出实际有效的字符串. 第一行是一个整数T,表示测试数据组数. 接下来每行为一个字符串(不含空格和任何空白),表示输入的原始字符串 输出最终的正确字符串. 2

哈尔滨理工大学2016新生赛E题

多组数据,每组测试数据输入9个整数,为1-9的一个全排列.初始状态会被描述为 1 2 3 4 5 6 7 8 9 Output 输出所需要的最小移动步数. Sample Input 1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1 Sample Output 0 12 将每个排列利用康托展开压缩为一个整数,采用广度优先搜索的方式不停的搜索直到得到目标状态即可. #include <stdio.h> #include <string.h> const int M