如何解决前 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 举报,一经查实,本站将立刻删除。