您的位置:首页 > 理论基础 > 数据结构算法

Sicily 1210. 二叉树

2013-09-07 20:47 253 查看


1210. 二叉树


Constraints

Time Limit: 1 secs, Memory Limit: 32 MB


Description

在众多的数据结构中,二叉树是一种特殊而重要的结构,有着广泛的应用。二叉树或者是一个结点,或者有且仅有一个结点为二叉树的根,其余结点被分成两个互不相交的子集,一个作为左子集,另一个作为右子集,每个子集又是一个二叉树。

遍历一棵二叉树就是按某条搜索路径巡访其中每个结点,使得每个结点均被访问一次,而且仅被访问一次。最常使用的有三种遍历的方式:

1.前序遍历:若二叉树为空,则空操作;否则先访问根结点,接着前序遍历左子树,最后再前序遍历右子树。

2.中序遍历:若二叉树为空,则空操作;否则先中序遍历左子树,接着访问根结点,最后再前中遍历右子树。

3.后序遍历:若二叉树为空,则空操作;否则先后序遍历左子树,接着后序遍历右子树,最后再访问根结点。

例如图(1)所示的二叉树:



前序遍历的顺序是ABCD,中序遍历的顺序是CBAD,后序遍历的顺序是CBDA。

对一棵二叉树,如果给出前序遍历和中许遍历的结点访问顺序,那么后序遍历的顺序是唯一确定的,也很方便地求出来。但如果现在只知道前序遍历和后序遍历的顺序,中序遍历的顺序是不确定的,例如:前序遍历的顺序是ABCD,而后序遍历的顺序是CBDA,那么就有两课二叉树满足这样的顺序(见图(1)和图(2))。

现在的问题是给定前序遍历和后序遍历的顺序,要求出总共有多少棵不同形态的二叉树满足这样的遍历顺序。


Input

整个输入有两行,第一行给出前序遍历的访问顺序,第二行给出后序遍历的访问顺序。

二叉树的结点用一个大写字母表示,不会有两个结点标上相同字母。输入数据不包含空格,且保证至少有一棵二叉树符合要求。


Output

输出一个整数,为符合要求的不同形态二叉树的数目。


Sample Input


ABCD
CBDA



Sample Output


2



Problem Source

ZSUACM Team Member

题目解析:很明显,就是已知树的前序遍历和后序遍历,求该树有几种形态。

              先复习一下树的三种遍历:

              前序遍历:根->左子树->右子树;中序遍历:左子树根->根->右子树;后序遍历:左子树->右子树->根。

             由前后两种遍历不能确定一颗树,是因为前后序遍历中,左子树和右子树(或者说左节点和右节点)在遍历顺序上是相邻的,不像中序遍历那样有根节点可以加以区分。而问题就出现在,若果当前节点是单子树的,在前后序遍历上就无法区分它究竟是左子树还是右子树。若这种情况出现了n次,那么结果就有2的n次方个可能。所以,解决这个问题的关键就转移到了寻找单子树节点的个数上。

               通过简单的构图,可以发现对于单子树的存在,根节点和子树节点在前后序遍历上是相邻的,而出现的顺序是相反的。通过这个规律就可以找到这种特殊存在的个数。

             这题坑就坑在,不用输出换行啊%>_<%,两次PE,囧死了。注意看输出要求就行。。。

代码如下:

#include<iostream>
#include<string>
#include<cmath>
using namespace std;

string pre,post;
int ans;

int solve(string x,string y)
{
int len1=x.size();
int len2=y.size();
int cnt=0;
for(int i=0;i<len1;i++)
{
for(int j=len2-1;j>=0;j--)
{
if(x[i]==y[j]&&x[i+1]==y[j-1])
{
cnt++;
break;
}
}
}
return cnt;
}

int main()
{
cin>>pre>>post;
ans=solve(pre,post);
cout <<(int)pow(2.0,ans);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息