题目大意: 给一棵递归树,看链接图片,从根节点开始对于每个节点往它的子节点移动,直到叶子节点停止。每个节点选哪一个孩子节点继续往下走是随机的(等概率)。然后叶子节点都会标记一个数值,记为走到该节点的得分。
输入条件:先输入整数n(n=0时结束),接下来有n行(n <= 26),每一行会为前n个小写字母(每个字母作为一个变量)的描述。如a = (1 b)表示 f(a) = 1/2 * (1 + f(b))其中f(x)为x节点的得分期望。
现在对n个小写字母表示的变量节点,求出那个节点的得分期望即f(x) (x=a,b,c ...)。
这个题相当有意思,有意思在于它的输入——基于某个字符集的语义分析。递归向下分析的策略,而且是非常典型LL(1)文法!
S -> XWEWT
X -> (X)|a|b|c|...|z
E -> '='
W -> {Blank}|空
T -> (U)
U -> T|X|I
U -> UwU
w -> {Blank}
I -> [+|-]{Digit}+[.{Digit}]
这道题另外一个关键点是将T转化成方程式,然后综合这n个方程式,使用gauss消元求解。
gauss消元其实就是线性代数中,化简行列式然后进行求解。不会的亲们回去好好看看线性代数的书,不要看网上某些人写的不清不楚的报告。
只是有一点需要注意:计算机中的数字是有界的,要时刻注意数字边界问题!
还有,很多事情需要自己亲身实践,我贡献了很多次WA,一个大原因是听人家要排除输出"-0.000"的问题。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 #include <algorithm> 6 #include <cstdlib> 7 #include <cmath> 8 using namespace std; 9 int alpha[128]={0},n; 10 int getint(char *mes){ 11 int i=0; 12 while(mes[i]!='