【递归与递推】遍历问题
题目描述
我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。然而给定一棵二叉树的前序和后序遍历,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树:
a a a a
/ / \ \
b b b b
/ \ / \
c c c c
所有这些二叉树都有着相同的前序遍历和后序遍历,但中序遍历却不相同。
输入
共两行,第一行表示该二叉树的前序遍历结果s1,第二行表示该二叉树的后序遍历结果s2。
输出
输出可能的中序遍历序列的总数,结果不超过长整型数。
样例输入
abc cba
样例输出
4
分析:
前序遍历:根节点->左子树->右子树
中序遍历:左子树->根节点->右子树
后序遍历:左子树->右子树->根节点
已知前序遍历,后序遍历,当仅当当前结点不存在兄弟结点时答案加倍(该结点或为左儿子或右儿子),即存在反串时cnt++,最终答案为1<<cnt;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <queue> #include <stack> #include <vector> #include <list> #include <ext/rope> #define rep(i,m,n) for(i=m;i<=n;i++) #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++) #define vi vector<int> #define pii pair<int,int> #define mod 1000000007 #define inf 0x3f3f3f3f #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) const int maxn=1e5+10; const int dis[][2]={0,1,-1,0,0,-1,1,0}; using namespace std; using namespace __gnu_cxx; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} int n,m,len,f; string a,b; int main() { int i,j,k,t; cin>>a>>b; len=a.size(); for(i=1;i<len;i++) for(j=len-1;j>=0;j--)if(a[i]==b[j]&&a[i-1]==b[j+1])f++; printf("%lld\n",1LL*(1<<f)); //system("pause"); return 0; }