1. 程式人生 > >51nod 1832 前序後序遍歷

51nod 1832 前序後序遍歷

ret == false urn stream 上一個 大數 存在 ans

技術分享圖片

思路:設只有一顆子樹的節點有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 }

51nod 1832 前序後序遍歷