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 }