问题 D: 求后序遍历
时间限制: 1 Sec 内存限制: 128 MB
提交: 59 解决: 43
[提交][状态][讨论版][命题人: 外部导入]
题目描述
输入一棵二叉树的先序和中序遍历序列,输出其后序遍历序列。
输入
输入数据共两行,第一行一个字符串,表示树的先序遍历,第二行一个字符串,表示树的中序遍历。树的结点一律用小写字母表示。
输出
输出仅一行,表示树的后序遍历序列
样例输入
abdec dbeac
样例输出
debca
#include<iostream>
#include<cstring>
using namespace std;
string s1,s2;
void calc(int l1,int r1,int l2,int r2)
{
int m=s2.find(s1[l1]);
if(m>l2) calc(l1+1,m-l2+l1,l2,m-1);
if(m<r2) calc(m-l2+l1+1,r1,m+1,r2);
cout<<s1[l1];
}
int main()
{
cin>>s1>>s2;
calc(0,s1.length()-1,0,s2.length()-1);
cout<<endl;
return 0;
}
问题 F: 二叉树遍历
时间限制: 1 Sec 内存限制: 128 MB
提交: 45 解决: 33
[提交][状态][讨论版][命题人: 外部导入]
题目描述
树和二叉树基本上都有先序、中序、后序、按层遍历等遍历顺序,给定中序和其它一种遍历的序列就可以确定一棵二叉树的结构。假定一棵二叉树一个结点用一个字符描述,现在给出中序和按层遍历的字符串,求该树的先序遍历字符串。
输入
输入共两行,每行是由字母组成的字符串(一行的每个字符都是唯一的),分别表示二叉树的中序遍历和按层遍历的序列。
输出
输出就一行,表示二叉树的先序序列
样例输入
DBEAC ABCDE
样例输出
ABDEC
#include<iostream>
#include<cstring>
using namespace std;
string s1,s2;
void calc(int l1,int r1,int l2,int r2)
{
int i,j;
for(i=l2;i<=r2;i++)
{
int b=0;
for(j=l1;j<=r1;j++)
{
if(s2[i]==s1[j])
{
cout<<s1[j];
b=1;
break;
}
}
if(b) break;
}
if(j>l1) calc(l1,j-1,0,r2);
if(j<r1) calc(j+1,r1,0,r2);
}
int main()
{
cin>>s1>>s2;
calc(0,s1.length()-1,0,s2.length()-1);
cout<<endl;
return 0;
}
我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串。
FBI树是一种二叉树[ 二叉树:二叉树是结点的有限集合,这个集合或为空集,或由一个根结点和两棵不相交的二叉树组成。这两棵不相交的二叉树分别称为这个根结点的左子树和右子树。],它的结点类型也包括F结点,B结点和I结点三种。由一个长度为2N的“01”串S可以构造出一棵FBI树T,递归的构造方法如下:
T的根结点为R,其类型与串S的类型相同;
若串S的长度大于1,将串S从中间分开,分为等长的左右子串S1和S2;由左子串S1构造R的左子树T1,由右子串S2构造R的右子树T2。
现在给定一个长度为2N的“01”串,请用上述构造方法构造出一棵FBI树,并输出它的后序遍历。
输入
输入的第一行是一个整数N(0 <= N <= 10),第二行是一个长度为2N的“01”串。
输出
输出包括一行,这一行只包含一个字符串,即FBI树的后序遍历序列。
样例输入
3 10001011
样例输出
IBFBBBFIBFIIIFF
提示
对于40%的数据,N <= 2;
对于全部的数据,N <= 10。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
string a;
char print(int left,int right){
int s1=0,s2=0;
for(int i=left;i<=right;i++){
if(a[i]=='0')
s1++;
if(a[i]=='1')
s2++;
}
if(s1!=0&&s2!=0)
return 'F';
if(s1==0&&s2!=0)
return 'I';
else
return 'B';
}
int calc(int left,int right){
if(left!=right){
calc(left,(left+right)/2);
calc((left+right)/2+1,right);
}
cout<<print(left,right);
}
int main(){
int n;
cin>>n>>a;
calc(0,a.length()-1);
return 0;
}
问题 I: 二叉树凹入法输出
时间限制: 1 Sec 内存限制: 128 MB
提交: 17 解决: 15
[提交][状态][讨论版][命题人: 外部导入]
题目描述
树的凹入表示法主要用于树的屏幕或打印输出,其表示的基本思想是兄弟间等长,一个结点要不小于其子结点的长度。二叉树也可以这样表示,假设叶结点的长度为1,一个非叶结点的长并等于它的左右子树的长度之和。
一棵二叉树的一个结点用一个字母表示(无重复),输出时从根结点开始:
每行输出若干个结点字符(相同字符的个数等于该结点长度),
如果该结点有左子树就递归输出左子树;
如果该结点有右子树就递归输出右子树。
假定一棵二叉树一个结点用一个字符描述,现在给出先序和中序遍历的字符串,用树的凹入表示法输出该二叉树。
输入
输入共两行,每行是由字母组成的字符串(一行的每个字符都是唯一的),分别表示二叉树的先序遍历和中序遍历的序列。
输出
输出行数等于该树的结点数,每行的字母相同。
样例输入
ABCDEFG CBDAFEG
样例输出
AAAA BB C D EE F G
#include<cstdio>
#include<iostream>
using namespace std;
string s1,s2;
struct node{
char ch;
int len,fa;
}p[10000];
void calc(int l1,int r1,int l2,int r2,int x){
int m=s2.find(s1[l1]);
p[l1].fa=x;
p[l1].ch=s1[l1];
if(m==l2||m==r2)
p[l1].len=1;
else
p[l1].len=0;
if(m>l2) calc(l1+1,m-l2+l1,l2,m-1,l1);
if(m<r2) calc(m-l2+l1+1,r2,m+1,r2,l1);
}
int main(){
cin>>s1>>s2;
calc(0,s1.length()-1,0,s2.length()-1,-1);
for(int i=s1.length()-1;i>=0;i--){
if(p[i].fa>=0)
p[p[i].fa].len+=p[i].len;
}
for(int i=0;i<s1.length();i++){
for(int j=1;j<=p[i].len;j++){
printf("%c",p[i].ch);
}
printf("\n");
}
}