cheng_you_know

学而时习之!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

问题描述
    给定参数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;
}
posted on 2013-08-01 20:07  cheng_you_know  阅读(460)  评论(0)    收藏  举报