【a403】遍历树问题

Time Limit: 1 second
Memory Limit: 32 MB

【问题描述】

我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序和中序遍历,你也能求出它的前序遍历。然而,给定一棵二叉树的前序和后序遍历,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树:
 所有这些二叉树都有着相同的前序和后序遍历序列,但中序遍历序列却不相同。

【输入格式】

共两行,第一行表示该二叉树的前序遍历结果S1,第二行表示该二叉树的后序遍历结果S2。

【输出格式】

仅一行,输出可能的中序遍历序列的总数,结果不超过长整型数。

【输入样例】

abc
cba

【输出样例】

4

【题目链接】:http://noi.qz5z.com/viewtask.asp?id=a403

【题意】

【题解】

只有那些没有兄弟节点的节点,它们才能够左右转(即当左子树还是当右子树->不会影响前序遍历和后序遍历)
所以答案就是2^(没有兄弟节点的节点个数)
怎么找那些没有兄弟节点的节点?
如下图
对于1这个没有兄弟节点的节点;
则必有:
先序遍历遍历完1之后就是2
而后序遍历,输出2之后就是输出1
(因为1号节点没有兄弟节点,所以递归完2的子树之后,输出2之后就是直接输出1了)
即s1[i]==s2[j]且s1[i-1]==s2[j+1]
就说明找到了一个没有兄弟节点的节点->s1[i-1]
这里写图片描述

【完整代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x)
#define ref(x) scanf("%lf",&x)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 110;

char s1[N],s2[N];
int len1,len2,ans;

void in()
{
    scanf("%s",s1+1),scanf("%s",s2+1);
    len1 = strlen(s1+1),len2 = strlen(s2+1);
}

void get_ans()
{
    rep1(i,2,len1)
        rep1(j,1,len2-1)
            if (s1[i]==s2[j] && s1[i-1]==s2[j+1])
                ans++;
}

void o()
{
    printf("%d
",1<<ans);
}

int main()
{
    //freopen("F:\rush.txt","r",stdin);
    in();
    get_ans();
    o();
    //printf("
%.2lf sec 
", (double)clock() / CLOCKS_PER_SEC);
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626517.html