這個題目的分析估計都被寫爛了,我這裡就簡單的說明一下,其實覺得他們寫了好多好多很淺顯的東西,希望我的分析能夠給大家減輕點負擔,雖然我也是看別人的分析之後才更加理解這個題目。
分析如下:
已知前序和後序,
1:我們先知道的,肯定是字符串第一個會等於最後一個
2:既然是m叉樹,那麼我們就要分析m叉樹中有幾個還有子樹,然後我們就需要分析子樹的由來。
3:子樹中又有子樹,這個就是組合數學中的一件事情分步完成,則最終的組合為步步相乘。
所以問題的關鍵就在於我怎麼知道子樹的存在呢?
找子樹的過程,把前一個字符串記為A,後一個記為B
先執行步驟1,即跳過第一個字符,A=A+1;
然後把取出A的第一個字符A[0],在B中找,直到B[i]==A[0],就是一個子樹
就分析下面最簡單的兩個吧
2 abc cba 4 2 abc bca 1
第一個,執行步驟1,剩下bc和cb,找完第一次就發現找完了,所以就只有1個子樹,然後再去對bc進行查找
第二個,執行步驟1,剩下bc和bc,找到兩個子樹
#include#include int result; int Cal(int n,int m)//計算組合數,從n個中選m個; { if(m==n) return 1; else if (m==1) return n; else return Cal(n-1,m)+Cal(n-1,m-1); } void Count(char *A,char *B,int num) { int n=strlen(A); if(n==1) return ; A=A++;//忽略第一個; B[n-1]='';//忽略最後一個; int count=0; while(*A) { int i=0; char newA[27],newB[27]; while(A[0]!=B[i]) { newA[i]=A[i]; newB[i]=B[i]; i++; } newA[i]=A[i]; newB[i]=B[i]; newA[i+1]=''; newB[i+1]=''; count++;//統計在當前這一層有多少個子樹; A=A+i+1; B=B+i+1; Count(newA,newB,num); } result=result*Cal(num,count); } int main() { int n; char A[27],B[27]; //freopen(data.in,r,stdin); while(scanf(%d,&n)!=EOF) { scanf(%s%s,&A,&B); result=1; Count(A,B,n); printf(%d ,result); } }