1. 程式人生 > >python求解給定一個整數N,求N!末尾有多少個0,求N!的二進位制中最低位1的位置

python求解給定一個整數N,求N!末尾有多少個0,求N!的二進位制中最低位1的位置

   之前做的銀聯題目有一道題目就是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的。