阶乘得到真的很大真的很快(向下滚动一点以查看列表)。即使是 64 位数字也只能达到20!
。所以在开始乘法之前你必须做一些预处理。
总体思路是对分子和分母进行因式分解,并删除所有公因数。由于帕斯卡三角形的结果始终是整数,因此可以保证在删除所有公因数后分母将为 1。
例如,假设你有row=35
and position=10
。那么计算就是
element = 35! / (10! * 25!)
which is
35 * 34 * 33 * ... * 26 * 25 * 24 * ... * 3 * 2 * 1
---------------------------------------------------
10! * 25 * 24 * ... * 3 * 2 * 1
因此,第一个简化是分母中较大的阶乘抵消了分子中所有较小的项。哪一片叶子
35 * 34 * 33 * ... * 26
-----------------------
10 * 9 * 8 * ... * 1
现在我们需要删除分子和分母中剩余的公因数。它有助于将分子的所有数字放入数组中。然后,对于分母中的每个数字,计算最大公约数(gcd) 并将分子和分母除以 gcd。
以下代码演示了该技术。
array[10] = { 35, 34, 33, 32, 31, 30, 29, 28, 27, 26 };
for ( d = 10; d >= 2; d-- )
{
temp = d;
for ( i = 0; i < 10 && temp > 1; i++ )
{
common = gcd( array[i], temp );
array[i] /= common;
temp /= common;
}
}
这是代码逐步执行的操作
d=10 i=0 temp=10 array[0]=35 ==> gcd(35,10)=5, so array[0]=35/5=7 and temp=10/5=2
d=10 i=1 temp=2 array[1]=34 ==> gcd(34, 2)=2, so array[1]=34/2=17 and temp=2/2=1
inner loop breaks because temp==1
d=9 i=0 temp=9 array[0]=7 ==> gcd(7,9)=1, so nothing changes
d=9 i=1 temp=9 array[1]=17 ==> gcd(17,9)=1, so nothing changes
d=9 i=2 temp=9 array[2]=33 ==> gcd(33,9)=3, so array[2]=11 and temp=3
d=9 i=3 ==> gcd(32,3)=1
d=9 i=4 ==> gcd(31,3)=1
d=9 i=5 temp=3 array[5]=30 ==> gcd(30,3)=3, so array[5]=10 and temp=1
inner loop breaks
当一切都说完并完成后,数组最终为
array[10] = { 1, 17, 11, 1, 31, 1, 29, 14, 3, 26 }
将这些数字相乘,答案是183579396
,并且整个计算可以使用 32 位整数来执行。一般来说,只要答案适合32位,就可以用32位进行计算。