洛谷T236450 美国血统

题目描述

农夫约翰非常认真地对待他的奶牛们的血统。然而他不是一个真正优秀的记帐员。他把他的奶牛 们的家谱作成二叉树,并且把二叉树以更线性的“树的中序遍历”和“树的前序遍历”的符号加以记录而 不是用图形的方法。

你的任务是在被给予奶牛家谱的“树中序遍历”和“树前序遍历”的符号后,创建奶牛家谱的“树的 后序遍历”的符号。每一头奶牛的姓名被译为一个唯一的字母。(你可能已经知道你可以在知道树的两 种遍历以后可以经常地重建这棵树。)显然,这里的树不会有多于 26 个的顶点。 这是在样例输入和 样例输出中的树的图形表达方式:

         C
         /  \
        /  \
       B    G
      / \  /
       A   D  H
        / \
       E   F

树的中序遍历是按照左子树,根,右子树的顺序访问节点。

树的前序遍历是按照根,左子树,右子树的顺序访问节点。

树的后序遍历是按照左子树,右子树,根的顺序访问节点。

输入格式

第一行: 树的中序遍历

第二行: 同样的树的前序遍历

输出格式

单独的一行表示该树的后序遍历。

输入输出样例

输入 #1
ABEDFCHG
CBADEFGH 
输出 #1
AEFDBHGC

说明/提示

题目翻译来自NOCOW。

USACO Training Section 3.4

 

解题思路:

 

LG上还有一道差不多的题【P1030 求先序排列】可供大家练手

 

下面进入正文:

 

-------------------------潇洒的分割线-------------------------

 

树的前序遍历有一个特点:

 

第一个字符即为它的根节点!

 

举个梨子其实是样例

 

中序遍历为:ABEDFCHG,前序遍历为:CBADEFGH。

 

那么根节点就是C。

 

于是找到了中序遍历的左子树:ABEDF 和右子树:HG。

 

紧接着,前序遍历找到了左子树:BADEF 和右子树:GH。

 

于是,我们可以继续递归下去,直至字符串为空。

//substr方法的使用方法。

string s;
s.substr(order,k);

参数传入一个order,一个k。

函数将会从下标为order的位置开始,连续截取k个字符。返回截取后的字符串。

order显然不能超出0~s.size()-1的范围。

但是,如果order+k超过了s.size()-1,函数会自动只截取到s的末尾。

如果不传入k,那么默认截取到末尾。

 CODE:

#include<bits/stdc++.h>

using namesapce std;

string a, b;

void dfs(string x, string y){

       if(!(int)y.size()) return;//递归边界

       int pos = x.find(y[0]);//在中序遍历中找到根节点

       dfs(x.substr(0, pos), y.substr(1, pos));//递归1

       dfs(x.substr(pos + 1), y.substr(pos + 1));//递归2

       printf("%c", y[0]);//再输出根节点

       return;

}

int main(){

       cin >> a >> b;

       dfs(a, b);

        

       return 0;

}

posted @ 2022-05-04 13:39  LuoJMeng  阅读(32)  评论(0编辑  收藏  举报