python求解给定一个整数N,求N!末尾有多少个0,求N!的二进制中最低位1的位置

320 篇文章 88 订阅
151 篇文章 4 订阅

   之前做的银联题目有一道题目就是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的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Together_CZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值