结尾0的个数
By 白熊花田(http://blog.csdn.net/whiterbear) 转载需注明出处,谢谢。
(注题目来自:http://www.pythontip.com/)
描述:
给你一个正整数列表 L, 如 L=[2,8,3,50], 输出L内所有数字的乘积末尾0的个数,
如样例L的结果为2.(提示:不要直接相乘,数字很多,可能溢出)
分析:
由题意可以想出最简单的办法,即将表中所有元素相乘,最后和10取余得到0的个数。提示中说这样会溢出。但是,我测试发现python的长整型居然是无上限的,即可以使用N个数相乘而完全没有出现溢出的情况。好吧,百度后原因是:python运算时当整型数据溢出时会自动转化为长整型,长整型所能处理的范围依赖于(虚拟)内存大小。
对应的程序:
def zeroCount3():
zcount = 0
if 0 in L:
print 1
else:
res = 1
for i in L:
res = res * i
while res%10 == 0:
zcount += 1
res = res/10
print zcount
或者:
zcount = 0
def zfun(x, y):
global zcount
res = x*y
while res%10 == 0:
zcount += 1
res = res/10
return res
def zeroCount2():
reduce(zfun, L, 1)
print zcount
但是,这样做虽然简单粗暴,但是这样只能适合python,因为其他语言比如C一定会溢出。所以,我们试图分析数据看看能不能找到更好的办法。
我们发现结尾0的个数,取决于最终有多少个10相乘,而10的产生由依赖于有多少个(2,5)对产生。因为一对2和5能够产生一个10。这样,在L中n个数相乘时,我们可以将每个数转化成对应的因数相乘,统计出因数中有多少个2和5对,这样就能直接得出最后0的个数,而不必计算出整个整式值。
比如L=[4,6,32,52,25,79],乘积为=2*2 * 2*3 * 2^5 * 2^2*13 * 5^2 * 79,统计下有2个(2,5)对,这样最后结果中就有2个0。tip:一般因数中2的个数远大于5的出现的个数。
依此给出对应的程序:
def zeroCount1():
if 0 in L:
print 1
else:
five_count = 0
two_count = 0
for l in L:
while l%5 == 0:
l = l/5
five_count += 1
while l%2 == 0:
l = l/2
two_count += 1
print min(five_count, two_count)