在因子中查找具有n个尾随零的自然数

时间:2017-05-11 09:31:49

标签: algorithm python-2.7 factorial trailing

我需要以下问题的帮助。

给定一个整数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个尾随零的数字。

由于

2 个答案:

答案 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个训练零