问题描述
给定参数n(n为正整数),请计算n的阶乘n!末尾所含有“0”的个数。
例如,5!=120,其末尾所含有的“0”的个数为1;10!= 3628800,其末尾所含有的“0”的个数为2;20!= 2432902008176640000,其末尾所含有的“0”的个数为4。
问题分析:
显然,对于阶乘增长速度的非常快的,很容易就溢出了。当然就不可能把阶乘算出来,而是要找规律解决。下面用因式分解的思路来考虑:末尾的0可以分解为2*5,一个5,一个2就对应一个0;
下面给出递推过程:
(1)当n<5 时,f(n) =0; 结论成立
(2)当n>=5 时,可以令 n!=[5k*5(k-1)…10*5]*a ,其中n=5k+r ,r(0<=r<5),a是一个不含因子的整数,可看出是一个满足条件的整数;
对于序列5k,5(k-1)…10*5 中在每一个5i中,在区间(5(i-1),5i)内存在一个偶数,即存在一个2与之对应。因此这里的k个‘5’因子 与n!中的末尾0个数是一一对应的。
所以递推公式转化为:
f(n!)=g(5^k * k! *a) = k + g(k!)= k+f(k!); k!是系数的相乘结果。
f(n!)=k+f(k!);
例如: f(5!)= 1+f(1!)=1;
f(10!)=2+f(2!)=2;
下面给出C++两种实现代码:.递归;非递归:
//递归 int n_jie_tail_zeors_recurise(int n) { int zeros_num =0; int k; if(n < 5) return 0; for(k=5;k<=n;k+=5) { zeros_num++; } return zeros_num + n_jie_tail_zeors_recurise(zeros_num); }
//非递归 int n_jie_tail_zeros_non_recurse(int n) { int zeros_num =0; int temp = n; int k=0; int index=0; while(temp >5) { index =0; for(k =5;k<=temp;k+=5) { zeros_num++; index++; } temp = index; } return zeros_num; }
时间: 2024-12-14 18:08:13