之前做的银联题目有一道题目就是1000的阶乘尾部有多少个0,记得这样的题目之前是做过的,但是当时就是时间太紧了没想起来,今天又遇到这个题目,索性查查看看是怎么算的,然后程序计算一下,加深理解,对于这样的题目网上也有很多的解法,核心的思想就是找规律看问题的本质是什么的,因为不可能让你求一下n!的阶乘然后自己去数一下一共末尾有多少个0,会溢出的。
思路:
如果想要尾部出现0必然离不开10的出现,而10的出现可以简化为2*5的结果,而在数字的分解中2的出现频数远高于5的出现频数,在这里的规律就是直接找n的因子分解中5的个数即可。
要找到n!的阶乘中尾部1的下标的思路同上,只需要寻找n中因数2的个数即可,因为这里返回的下标是从末尾开始数的所以在返回的结果中加1取反即可,因为Python中的末尾下标是从-1开始的。
有了这样的规律做起来就比较简单了,下面是具体的实现了:
#!usr/bin/env python #encoding:utf-8 ''' __Author__:沂水寒城 功能:给定一个整数N,求N!末尾有多少个0,求N!的二进制中最低位1的位置 ''' def count_0_nums1(n): ''' 求N!末尾有多少个0 ''' num=n tmp=0 while num: tmp+=num/5 num/=5 print '{0}的阶乘末尾有{1}个0'.format(n, tmp) return tmp def count_0_nums2(n): ''' 求N!末尾有多少个0 ''' res=0 for i in range(5,n+1,5): index=i while index%5==0: res+=1 index/=5 print '{0}的阶乘末尾有{1}个0'.format(n, res) def find_tail_1_position(n): ''' 求N!的二进制中最低位1的位置 ''' temp=n res=0 while temp: temp>>=1 res+=temp print '{0}的二进制中最低位1的位置在{1}'.format(n, -(res+1)) if __name__ == '__main__': num_list=[4,10,6,12,100,1000] for one in num_list: count_0_nums1(one) print '----------------------------------------' for one in num_list: count_0_nums2(one) print '------------------------------------------' for one in num_list: find_tail_1_position(one)
结果如下:
4的阶乘末尾有0个0 10的阶乘末尾有2个0 6的阶乘末尾有1个0 12的阶乘末尾有2个0 100的阶乘末尾有24个0 1000的阶乘末尾有249个0 ---------------------------------------- 4的阶乘末尾有0个0 10的阶乘末尾有2个0 6的阶乘末尾有1个0 12的阶乘末尾有2个0 100的阶乘末尾有24个0 1000的阶乘末尾有249个0 ------------------------------------------ 4的二进制中最低位1的位置在-4 10的二进制中最低位1的位置在-9 6的二进制中最低位1的位置在-5 12的二进制中最低位1的位置在-11 100的二进制中最低位1的位置在-98 1000的二进制中最低位1的位置在-995 [Finished in 0.3s] 顺便说一下,考试遇到的那个题目问1000!末尾有 多少个0,它给的选项都是四位数的,我选的是2499,貌似所有选项尾部都是9,应该是题目出错了吧,其实当时就怀疑不可能会有几千个0的,差点想写个小程序算一下,毕竟服务器的话还是ok的。