Finding natural numbers having n Trailing Zeroes in Factorial

核能气质少年 提交于 2019-12-11 05:57:43

问题


I need help with the following problem.

Given an integer m, I need to find the number of positive integers n and the integers, such that the factorial of n ends with exactly m zeroes.

I wrote this code it works fine and i get the right output, but it take way too much time as the numbers increase.

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

Could someone suggest me a more efficient way to do this. Presently, it takes 30 seconds for a test case asking for numbers with 250 trailing zeros in its factorial.

Thanks


回答1:


To get number of trailing zeroes of n! efficiently you can put

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) 

In order to solve the problem (what numbers have n trailing zeroes in n!) you can use these facts:

  • number of zeroes is a monotonous function: f(x + a) >= f(x) if a >= 0.
  • if f(x) = y then x <= y * 5 (we count only 5 factors).
  • if f(x) = y then x >= y * 4 (let me leave this for you to prove)

Then implement binary search (on monotonous function).

E.g. in case of 250 zeroes we have the initial range to test [4*250..5*250] == [1000..1250]. Binary search narrows the range down into [1005..1009].

1005, 1006, 1007, 1008, 1009 are all numbers such that they have exactly 250 trainling zeroes in factorial

Edit I hope I don't spoil the fun if I (after 2 years) prove the last conjecture (see comments below):

Each 5**n within facrtorial when multiplied by 2**n produces 10**n and thus n zeroes; that's why f(x) is

f(x) = [x / 5] + [x / 25] + [x / 125] + ... + [x / 5**n] + ...

where [...] stands for floor or integer part (e.g. [3.1415926] == 3). Let's perform easy manipulations:

f(x) = [x / 5] + [x / 25] + [x / 125] + ... + [x / 5**n] + ... <= # removing [...]
        x / 5  +  x / 25  +  x / 125  + ... +  x / 5**n  + ... =
        x * (1/5 + 1/25 + 1/125 + ... + 1/5**n + ...) =
        x * (1/5 * 1/(1 - 1/5)) =
        x * 1/5 * 5/4 =
        x / 4

So far so good

 f(x) <= x / 4 

Or if y = f(x) then x >= 4 * y Q.E.D.




回答2:


Focus on the number of 2s and 5s that makes up a number. e.g. 150 is made up of 2*3*5*5, there 1 pair of 2&5 so there's one trailing zero. Each time you increase the tested number, try figuring out how much 2 and 5s are in the number. From that, adding up previous results you can easily know how much zeros its factorial contains.

For example, 15!=15*...*5*4*3*2*1, starting from 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 
..   

Refer to Peter de Rivaz's and Dmitry Bychenko's comments, they have got some good advices.



来源:https://stackoverflow.com/questions/43911621/finding-natural-numbers-having-n-trailing-zeroes-in-factorial

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!