那么,既然@Spunden已经巧妙地透露了这个秘密,这是一种实现它的方法。
代码:
def zeros(n)
return 0 if n.zero?
k = (Math.log(n)/Math.log(5)).to_i
m = 5**k
n*(m-1)/(4*m)
end
示例
zeros(3)
zeros(5)
zeros(12)
zeros(15)
zeros(20)
zeros(25)
zeros(70)
zeros(75)
zeros(120)
zeros(125)
解释
假设 n = 128
。
那么在介于一和 128
(包括边界)之间,任何一个可以被 5^1=>5
整除的数都提供至少一个因子,这样的数字有 128/5 => 25
个。其中,唯一能提供多于一个因子的是那些可以被 5^2=>25
整除的数,它们共有 128/25 => 5
个(分别为 25, 50, 75, 100, 125
)。其中只有一个数能提供超过两个因子,而由于 125/(5^4) => 0
,没有任何数字能提供超过三个因子。因此,五个因子的总数为:
128/5 + 128/25 + 128/125 #=> 31
(请注意,对于有三个因子为5的125,每个因子在这三个术语中各计算一次; 对于有两个因子为5的25、50等,每个因子在第一个术语中各计算一次。)
对于任意的n,我们首先计算最高幂k,满足:
5**k <= n
这是:
k <= Math.log(n)/Math.log(5)
因此,最大的这种值是:
k = (Math.log(n)/Math.log(5)).to_i
正如@spundun所指出的那样,您也可以通过迭代来计算k
,例如:
last = 1
(0..1.0/0).find { |i| (last *= 5) > n }
因此,五的总因子数为
(n/5) + (n/25) +...+ (n/5**k)
定义:
r = 1/5,
这个总和可以表示为:
n * s
where
s = r + r**2 +...+ r**k
s
的值是一个几何级数的各项之和。我忘记了它的公式,但还记得它是如何推导出来的:
s = r + r**2 +...+ r**k
sr = r**2 +...+ r**(k+1)
s-sr = r*(1-r**k)
s = r*(1-r**k)/(1-r)
我随后进行了一些调整,以便仅使用整数算术来计算结果。