n的阶乘末尾出现的次数

<?php
function  find($n){
        $count = 0;
           $j = 0;
        for($i = 5; $i <= $n; $i = $i + 5){
            $j = $i;
            while($j % 5 == 0){
                $count ++;
                $j /= 5;
            }
        }
        return $count ;
    }
    $a = find(5);
    var_dump($a);

 

转载于:https://www.cnblogs.com/hanmengya/p/10905678.html

这是一个比较有趣的数学问题。我们可以通过寻找规律,简化计算过程。 首先,我们知道,一个数的阶乘末尾有多少个零,取决于它可以分解出多少个因子 10,而 10 可以分解为 2 和 5 相乘得到。因此,我们只需要计算 N! 因子 2 和因子 5 的个数,取其较小的那个作为 N! 末尾的零的个数。 但是,这个问题要求的并不是末尾的零的个数,而是最右边的非零位。我们可以通过对每个因子进行分解,找出相乘后最右边的非零位的规律。 我们可以发现,对于一个数 x,如果它的最右边的非零位是 k,那么 x 乘以任何一个以 5 为末尾的数字都会让最右边的非零位变成 k。因此,我们只需要找到 N! 所有因子最右边的非零位,然后将它们依次乘以 1、2、3、4……N 末尾为 1、3、7、9 的数字,找到其最右边的非零位即可。 下面是 Python 代码实现: ```python def rightmost_nonzero_digit(n): # 计算因子 2 和因子 5 的个数 num_2, num_5 = 0, 0 for i in range(1, n+1): x = i while x % 2 == 0: num_2 += 1 x //= 2 while x % 5 == 0: num_5 += 1 x //= 5 # 计算所有因子最右边的非零位 last_digit = 1 for i in range(1, n+1): x = i while x % 10 == 0: x //= 10 last_digit = (last_digit * x) % 10 # 将最右边的非零位乘以 1、2、3、4……N 末尾为 1、3、7、9 的数字,找到其最右边的非零位 if num_2 > num_5: for i in [1, 3, 7, 9]: if (i * pow(2, num_2 - num_5, 10) * last_digit) % 10 != 0: return (i * pow(2, num_2 - num_5, 10) * last_digit) % 10 else: for i in [1, 3, 7, 9]: if (i * pow(5, num_5 - num_2, 10) * last_digit) % 10 != 0: return (i * pow(5, num_5 - num_2, 10) * last_digit) % 10 ``` 注意,在计算最右边的非零位时,我们需要用到取模运算,以避免超出计算机能处理的整数范围。同时,我们还需要注意一些细节,例如排除因子末尾为 0 的数字,以及在计算 2 和 5 的个数时,我们只需要统计它们在因子出现次数,而不是每个因子都进行分解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值