给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3 628 800,N!的末尾有两个0。

思路

这个题拿到我第一个思路是先求出阶乘的结果,然后查看该结果最后一位是否为0,具体就是先%10查看最后一位是否为0,如果是再除以10,消掉最后一位。然后循环一直至最后一位不是0,再把计数器的值返回回去。但是我立马就想到了可能溢出,所以百度了下大概13的阶乘是60多亿,而一个正整数就21亿多。所以这个方法不行。
真正可行的解法是:
因为阶乘是1*2*3*…(n-1)*n ,因为题目要求的是求出末尾有多少个0,所以当这些相乘的式子中出现2^x ,5^y(即2的x次方,5的y次方)这俩个数字时我们可以把它在多项式中分解成由多个2*2*2*5*5*5这种由多个2和多个5相乘(能这样分解是因为这个多项式全是由乘法构成的)的式子。因为每一对2和5的乘积在末尾都会多1个0,又因为能被2整除的数字肯定是多于被5整除的数字。所以这道题就化解成为那些能够被5整数的数字,最终能分解出多少个5。eg: 5=5*1 一个5 ,10=5*2 一个5,25=5*5二个5。

int N_num_zero(int data) //给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3 628 800,N!的末尾有两个0。
{                          // 如果要是用递归先算出N阶乘的结果,再%10看最后一位是否为0,再/10在看倒数第二位是否为0,这个方法很容易造成溢出,13的阶乘
    assert(data >= 0);  // 0的阶乘等于1,这里也正确处理没问题
    int count_zero = 0;
    for (size_t idx = 1; idx <= data; idx++)
    {
        int test = idx;
        while (test % 5 == 0)
        {
            count_zero++;
            test /= 5;
        }
    }
    return count_zero;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值