也许你早就知道阶乘的含义,N阶乘是由1到N相乘而产生,如: 12!=1×2×3×4×5×6×7×8×9×10×11×12=479,001,600 12的阶乘最右边的非零位为6。 写一个程序,计算N(1<N<N<50,000,000)阶乘的最右边的非零位
时间: 2024-05-03 15:18:01 浏览: 123
简单大数运算
这是一个比较有趣的数学问题。我们可以通过寻找规律,简化计算过程。
首先,我们知道,一个数的阶乘末尾有多少个零,取决于它可以分解出多少个因子 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 的个数时,我们只需要统计它们在因子中的出现次数,而不是每个因子都进行分解。
阅读全文