您的位置:首页 > 编程语言 > Python开发

FCTRL - Factorial的python实现

2016-04-25 02:31 656 查看

题目说明

该题目来源于SPOJ:http://www.spoj.com/problems/FCTRL/

大体意思是给定一个数n,求n的阶乘有多少个0结尾。

由于n最大可以是1000000000,笔者初步的算法1,虽然相比整个n遍历一次O(n)时间复杂度减少了80%,但还是无法满足需求;于是有了算法2;

算法2使用递归实现,对于n = 1000000000,只需要递归12次就可以结束,时间复杂度上大大降低。

算法1

0的产生只能是5的倍数乘以2,也就是5*n*2,而偶数的数量在50%左右,因此不缺2,只缺5;因此只需要找到5或5的倍数的个数,就可以知道0的个数了。
定义0计数器count = 0
定义mod5(n)函数返回n能被5整除的次数;
1、n小于5时,count = 0直接返回;
2、n大于等于5时,从5开始遍历n,间隔为5,也就是遍历的顺序是5,10,15,20..,n-n%5;count +=mod5(i)
3、遍历结束后输出count就是0的个数。

算法2

通过算法1可以发现,对于给定的正整数N,去算0的个数,只需要用所有5的倍数乘起来去算即可,定义:

a(n) = 5n

当n>1时,s(n) = s(n-1)*a(n)

推出s(n) = (1*5)*(2*5)(3*5)*...*(n*5) = 5^n * n!

所以对于给定的正整数N,N!当中所有5的乘积可以简化为N! ~ 5^(N/5)*(N/5!);

看到上面的式子,就应该想到递归了,完整递归定义:

当n<5时,Z(n) = 0

当n=5时,Z(n) = 1

当n>5时,Z(n) = n/5 + Z(n/5)

算法2代码实现

def z(n):
if n < 5:
return 0
elif n == 5:
return 1
else:
return z(n/5)+n/5
line = input()
for t in range(line):
n = input()
print(z(n))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: