n!末尾零的个数 -hoj-1039
一、解法1
很显然,当每次有5的整数倍时,都会增加一个0,因为5的倍数乘以一个偶数会得到一个0,而偶数的数目显然多于5整数倍的数目。但我们也同时发现如果该数 是5^k时,能产生k个零。因为2^k*5^k会得到k个0。因此我们不难得到结论:零的个数
f(n!) = n/5 + n/(5^2) + n/(5^3) + ...+ n/(5^k),其中5^k <= n <= 5^(k+1)。
二、解法2
我们同时发现,如果对n!进行因式分解,则所求0的个数就是因式分解中以5为个位数的因子的个数。其中我们能够发现n!可以分解为5^k*k!*a,其中 k =n/5,而a为1~n中不能为5整除的所有数的积。令f(n!)表示正整数n!末尾所含有的0的个数,g(n!)表示正整数n!的因式分解中因子5的个数,则有:
f(n!) = g(n!) = g(5^k * k! * a) = g( 5^k*k!) = k + g(k!) = k + f(k!) (其中 k = n/5 )我的代码当然就是解法2啦。
函数如下:
int f(int n)
{
if(n/5==0)
return 0;
return n/5+f(n/5);
}
小小的收获啦,高兴!
----------------------------------朴实的分割线-----------------------------------------
对解法2的证明:
令f(x!)表示正整数x!末尾所含有的“0”的个数,则有:
f(n!) = 0 0 < n < 5
f(n!) = k + f(k!) n >= 5 ;k=n/5(取整)
结论1: 对于n的阶乘n!,其因式分解中,如果存在一个因子“5”,那么它必然对应着n!末尾的一个“0”。
下面对这个结论进行证明:
(1)当n <
5时,
结论显然成立。
(2)当n >=
5时,令n!= [5k * 5(k-1) * ... * 10 * 5] *
a,其中 n = 5k + r (0
<= r <=
4),a是一个不含因子“5”的整数,a即是除去5的倍数剩下的数的总乘积。
对于序列5k,
5(k-1), ..., 10,
5中每一个数5i(1 <= i <=
k),都含有因子“5”,并且在区间【5(i-1),5i】(1
<= i <=
k)内存在偶数,也就是说每一个区间【5(i-1),5i】中都存在一个数有一个因子“2”与5i相对应。那么,这里的k个因子“5”与n!末尾的k个“0”一一对应。所以,计算n的阶乘n!末尾的“0”的个数,可以转换为计算其因式分解中“5”的个数。
我们进一步把n!表示为:n!= 5^k * k! * a,其中5^k表示5的k次方。
令f(x)表示正整数x末尾所含有的“0”的个数, g(x)表示正整数x的因式分解中因子“5”的个数,则有:f(n!) = g(n!) = g(5^k * k! * a) = k + g(k!) = k + f(k!)
命题得证。
----------------------------------朴实的分割线-----------------------------------------
浙公网安备 33010602011771号