我需要以下问题的帮助。
给定一个整数m,我需要找到正整数n和整数的数量,这样n的阶乘就以m个零结束。
我写了这段代码,它工作得很好,我得到了正确的输出,但随着数字的增加需要花费太多时间。
a=input()
while a:
x=[]
m,n,fact,c,j=input(),0,1,0,0
z=10*m
t=10**m
while z-1:
fact=1
n=n+1
for i in range(1,n+1):
fact=fact*i
if fact%t==0 and ((fact/t)%10)!=0:
x.append(int( n))
c=c+1
z=z-1
for p in range(c):
print x[p],
a-=1
print c
有人可以建议我采用更有效的方式来做到这一点。目前,一个测试用例需要30秒才能获得在其阶乘中有250个尾随零的数字。
由于
答案 0 :(得分:3)
关注构成数字的2和5的数量。例如150由2 * 3 * 5 * 5组成,有1对2& 5,因此其中一个为零。每次增加测试数量时,请尝试确定数字中有多少2和5。由此,添加以前的结果,您可以很容易地知道它的因子包含多少零。
例如,15!= 15 * ... * 5 * 4 * 3 * 2 * 1,从2开始:
Number 2s 5s trailing zeros of factorial
2 1 0 0
3 1 0 0
4 2 0 0
5 2 1 1
6 3 1 1
...
10 5 2 2
...
15 7 3 3
..
24 12 6 6
25 12 8 8 <- 25 counts for two 5-s: 25 == 5 * 5 == 5**2
26 13 8 8
..
参考Peter de Rivaz和Dmitry Bychenko的评论,他们有一些很好的建议。
答案 1 :(得分:2)
要有效地获取n!
的尾随零,您可以
def zeroes(value):
result = 0;
d = 5;
while (d <= value):
result += value // d; # integer division
d *= 5;
return result;
...
# 305: 1234! has exactly 305 trailing zeroes
print zeroes(1234)
为了解决问题(n
中有n!
尾随零的数字),您可以使用以下事实:
f(x + a) >= f(x)
如果a >= 0
。f(x) = y
然后x <= y * 5
(我们只计算5
个因素)。f(x) = y
然后x >= y * 4
(让我留下来让你证明)然后实现二进制搜索(在单调的函数上)。
E.g。在250
零的情况下,我们有初始范围来测试[4*250..5*250] == [1000..1250]
。二进制搜索将范围缩小到[1005..1009]
。
1005,1006,1007,1008,1009 所有数字都是这样的,它们在factorial中具有正好250
个训练零