51nod 1832 先序遍历与后序遍历二叉树+高精度

Posted GraceSkyer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1832 先序遍历与后序遍历二叉树+高精度相关的知识,希望对你有一定的参考价值。

题目链接:51nod 1832 先序遍历与后序遍历

基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
对于给定的一个二叉树的先序遍历和后序遍历,输出有多少种满足条件的二叉树。
两棵二叉树不同当且仅当对于某个x,x的左儿子编号不同或x的右儿子编号不同。
Input
第一行一个正整数n(3<=n<=10000),表示二叉树的节点数,节点从1到n标号。
第二行n个整数a[i](1<=a[i]<=n),表示二叉树的先序遍历。
第三行n个整数b[i](1<=b[i]<=n),表示二叉树的后序遍历。
Output
输出一个整数表示有多少种方案。保证至少有1种方案。
Input示例
3
1 2 3
2 3 1
Output示例
1

题解:找出只有一个儿子的节点数,则这种节点的儿子可以放在左子树或右子树即两种选择,然后将每种情况相乘即可,结果太大,再抄个高精度的板子嘛。
//yy:唉,我都快不记得怎么敲二叉树了。。类似的还可以拓展到n叉树,都是一类已知先序遍历和后序遍历求可构造树的方案数。。
技术分享
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #define CLR(a,b) memset((a),(b),sizeof((a)))
  6 using namespace std;
  7 typedef long long ll;
  8 const int N = 10005;
  9 struct BigInt
 10 {
 11     const static int mod = 10000;
 12     const static int DLEN = 4;
 13     int a[600],len;
 14     BigInt()
 15     {
 16         memset(a,0,sizeof(a));
 17         len = 1;
 18     }
 19     BigInt(int v)
 20     {
 21         memset(a,0,sizeof(a));
 22         len = 0;
 23         do
 24         {
 25             a[len++] = v%mod;
 26             v /= mod;
 27         }while(v);
 28     }
 29     BigInt(const char s[])
 30     {
 31         memset(a,0,sizeof(a));
 32         int L = strlen(s);
 33         len = L/DLEN;
 34         if(L%DLEN) len++;
 35         int index = 0;
 36         for(int i = L-1;i >= 0;i -= DLEN)
 37         {
 38             int t = 0;
 39             int k = i - DLEN + 1;
 40             if(k < 0) k = 0;
 41             for(int j = k;j <= i;j++)
 42                 t = t*10 + s[j] - 0;
 43             a[index++] = t;
 44         }
 45     }
 46     BigInt operator +(const BigInt &b)const
 47     {
 48         BigInt res;
 49         res.len = max(len,b.len);
 50         for(int i = 0;i <= res.len;i++)
 51             res.a[i] = 0;
 52         for(int i = 0;i < res.len;i++)
 53         {
 54             res.a[i] += ((i < len)?a[i]:0)+((i < b.len)?b.a[i]:0);
 55             res.a[i+1] += res.a[i]/mod;
 56             res.a[i] %= mod;
 57         }
 58         if(res.a[res.len] > 0) res.len++;
 59         return res;
 60     }
 61     BigInt operator *(const BigInt &b)const
 62     {
 63         BigInt res;
 64         for(int i = 0; i < len; i++)
 65         {
 66             int up = 0;
 67             for(int j = 0;j < b.len;j++)
 68             {
 69                 int temp = a[i] * b.a[j] + res.a[i+j] + up;
 70                 res.a[i+j] = temp%mod;
 71                 up = temp/mod;
 72             }
 73             if(up != 0)
 74             res.a[i + b.len] = up;
 75         }
 76         res.len = len + b.len;
 77         while(res.a[res.len - 1] == 0 &&res.len > 1)
 78             res.len--;
 79         return res;
 80     }
 81     void output()
 82     {
 83         printf("%d",a[len-1]);
 84         for(int i = len-2;i >=0 ;i--)
 85             printf("%04d",a[i]);
 86         printf("\n");
 87     }
 88 };
 89 BigInt ans(1);
 90 int pre[N], post[N];
 91 int n;
 92 void dfs(int l1, int r1, int l2, int r2) {
 93     if(l1 > r1) return;
 94     if(r1 - l1 == 1) return;
 95     l1++; r2--;
 96     int num = 0;
 97     int p = l2;
 98     while(post[p] != pre[l1]) p++;
 99     int r11 = l1 + (p - l2 + 1), r22 = p + 1;
100     num++;
101     dfs(l1, r11, l2, r22);
102     if((r1-l1)-(p-l2+1)!=0) {
103         num++;  dfs(r11, r1, p+1, r2);
104     }
105     num = num == 1 ? 2 : 1;
106     ans = ans * BigInt(num);
107 }
108 int main() {
109     int i, j;
110     scanf("%d", &n);
111     for(i = 0; i < n; ++i) scanf("%d", &pre[i]);
112     for(i = 0; i < n; ++i) scanf("%d", &post[i]);
113     dfs(0,n,0,n);
114     ans.output();
115     return 0;
116 }
46ms

 



以上是关于51nod 1832 先序遍历与后序遍历二叉树+高精度的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1832 先序遍历与后序遍历(dfs+高精度)

pascal给出一棵二叉树的中序与后序排列。求出它的先序排列(帮忙解释一下程序)

树的前序遍历与中序遍历构造二叉树和树的中序遍历与后序遍历构造二叉树

codevs 1013 求先序排列(二叉树遍历)

二叉树遍历的三种方法:先序遍历,中序遍历,后序遍历

51nod 1832 前序后序遍历