加油 ( •̀ ω •́ )y!

51nod 1832 前序后序遍历

 

思路:设只有一颗子树的节点有ans个设前序边历数组为pre[100],后序遍历数组为pos[100];前序遍历的第二个元素是A的一个子节点左右节点不知,设ax-ay表示一个树的前序遍历,bx-by表示后序遍历,可知如果pre[ax+1] = pos[i] 且 i = by-1,上一个根节点只有一个子树,此时令计数变量ans++;如果i != b2-1,很明显存在左右子树,此时应分别处理此时左子树为的前后序边历分别为:ax+1~ax+1+i-bx,bx~i,右子树为:ax+1+i-bx~ay,i+1~by-1;最后计算2^ans即为数的数目。值得注意的是:由于ans比较大,2^ans太大,需要用到大数乘法

 

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 typedef long long LL;
 7 const int maxn = 10005;
 8 int n, pre[maxn], pos[maxn], ans, index[maxn];
 9 int a[maxn * 10];
10 void dfs(int ax, int ay, int bx, int by)
11 {
12     if (ax >= ay)return;
13     int i = index[pre[ax + 1]];
14     if (i == by - 1)ans++;
15     dfs(ax + 1, ax + 1 + i - bx, bx, i);
16     dfs(ax + 1 + i - bx + 1, ay, i + 1, by - 1);
17 }
18 int main()
19 {
20     ios::sync_with_stdio(false);
21     while (cin >> n) {
22         ans = 0;
23         for (int i = 1; i <= n; i++)cin >> pre[i];
24         for (int i = 1; i <= n; i++) {
25             cin >> pos[i]; index[pos[i]] = i;
26         }
27         dfs(1, n, 1, n);
28         memset(a, 0, sizeof(a));
29         a[1] = 1; n = 1;
30         for (int i = 1; i <= ans; i++) {
31             for (int j = 1; j <= n; j++)
32                 a[j] *= 2;
33             for (int j = 1; j <= n; j++)
34                 if (a[j] >= 10) {
35                     a[j + 1] = a[j + 1] + a[j] / 10;
36                     a[j] %= 10;
37                     n = max(n, j + 1);
38                 }
39         }
40         for (int i = n; i >= 1; i--)
41             cout << a[i]; cout << endl;
42     }
43     return 0;
44 }

 

posted @ 2018-08-13 11:47  皮皮虎  阅读(158)  评论(0编辑  收藏  举报