微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

前 N 个阶乘的积的尾随零

如何解决前 N 个阶乘的积的尾随零

我正在尝试解决这个编码问题。

对于正整数 n,其阶乘定义为从 1 到 n 的所有整数的乘积,表示为 n!。现在 n double factorial 是 1 factorial,2 factorial,... 的乘积,直到 n factorial: 1! · 2! · 3! · ... · n!。给定 n(1 ≤ n ≤ 10^18),找出 n 个双阶乘的十进制表示的尾随零的个数。

我试图通过将其从 1 到 n 除以 5 来解决它,但是 n 太大而无法及时解决。 (时间限制为1s)

cnt = 0
for i in (1,n+1):
    while i >= 5:
        cnt += i//5
        i //= 5
    

因此,我尝试了其他方法,例如斯特林近似法和任何其他方法。但我无法解决这个问题。

我该如何解决这个问题?

解决方法

举个例子:n = 15。

5s的次数可以计算为:

5/5 = 1、6/5 = 1、7/5 = 1、8/5 = 1、9/5 = 1 和

10/5 = 2,11/5 = 2,12/5 = 2,13/5 = 2,14/5 = 2,

现在 15 : 15/5 = 3

可以看到15之前有组,第一组(5-9)贡献了5个5s, 第二组贡献了 5x2 = 10 个 5s。

一般每组贡献的 5 个数为 5 * group

15 落在第三组,但贡献的 5 的数量计为 3,即

它的 position_in_the_group * group = 1*3 = 3

因此

n = 的 5s 总数 (之前所有组贡献的5s总数)+ (自己贡献的5s在自己的组和之前组的成员的数量)

您可以使用 n*(n+1)/2(前 n 个数字之和的公式)来计算组数之和。

这样计算 5 秒的公式将是:

5*((group-1)*(group-1+1)/2) + pos*group

= 5*(group*(group-1)/2) + pos*group

这只是为了5

现在您需要对 25,75,125 等重复相同的过程,直到您的组为

python 代码将是:

 def get_trailing_zeros_double_factorial(n):
   res = 0
   group = n//5
   m = 5
   pos = n%m + 1
   n0 = n
   while group >= 1:
     res += m*(group*(group-1)//2) + pos*group
     n = n//5
     group = n//5
     m = m*5
     pos = (n0 % m) + 1
   return res

输出:

print(get_trailing_zeros_double_factorial(2))
print(get_trailing_zeros_double_factorial(5))
print(get_trailing_zeros_double_factorial(8))
print(get_trailing_zeros_double_factorial(11))
print(get_trailing_zeros_double_factorial(25))
print(get_trailing_zeros_double_factorial(50))
print(get_trailing_zeros_double_factorial(3443134134))
print(get_trailing_zeros_double_factorial(10 ** 18))

0
1
4
9
56
262
1481896560464509130
124999999999999987370803833007812495

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。