用python實現多隻猴子分桃問題

據說“五猴分桃”問題最先是由大物理學家狄拉克提出來的,這一貌似簡單的問題曾困擾住了他,經過努力,他只是獲得了相當繁瑣的求解方法。爲了獲得簡便的方法,他把問題提供給當時的一些數學家,有意思的是竟然也沒有得到滿意的結果。在後來者的不斷努力下,比較簡捷的方法才逐步涌現。
李政道和楊振寧曾榮獲諾貝爾物理學獎,正是由李政道提議成立了中科大少年班,他在中科大少年班的開班儀式上對“五猴分桃”問題進行適當演繹,提供給了少年班同學。

五猴分桃:

話說花果山水簾洞有5只聰明的猴子,有一天它們得到了一堆桃子,他們發現那堆桃子不能被均勻分5份,於是猴子們決定先去睡覺,明天再討論如何分配。夜深人靜的時候,猴子A偷偷起來,吃掉了一個桃子後,它發現餘下的桃子正好可以平均分成5份,於是它拿走了一份;接着猴子B也起來先偷吃了一個,結果它也發現餘下的桃子恰好可以被平均分成5份,於是它也拿走了一份;後面的猴子C、D、E一次如法炮製,先偷吃一個,然後將餘下的桃子平均分成5份並拿走了自己的一份,問:這一堆桃子至少有幾個?

數學解決思路:

設桃子總數爲N,先借4個,總數則爲N+4個,分成5份,每份相同。
經過第一步後,剩下4(N+4)/5 
經過第二步後,剩下4^2(N+4)/5^2 
經過第三步後,剩下4^3(N+4)/5^3 
經過第四步後,剩下4^4(N+4)/5^4 
經過第五步後,剩下4^5(N+4)/5^5 
顯然,4^5(N+4)/5^5 爲整數,因爲4^5和5^5互質,則:(N+4)肯定能被5^5整除。 所以,N=5^5×K-4,(K=1,2,3,......) 當K=1時,N爲最小值,結果爲5^5-4=3121
實際上只需要往桃堆添四個桃,就會發現,實際上每次猴子都是拿走桃堆的五分之一(包括它吃掉的),然後就是一個公比爲5/4的等比數列。

本文討論多隻猴子分桃,代碼如下:

#!/usr/bin/python
#coding=utf-8
# __author__ = 'cy'
#輸入猴子數量
monkey = input("Input monkey num:")
#定義桃子總數函數
def show(n):
    #循環次數
    for i in xrange(1, monkey+1):
        #下一隻猴子應該帶走的桃子數
        t = (n - 1) / monkey
        #格式化輸出
        print u'%d. 桃子有%d個, 第%i只猴吃1個, 拿走%s個。' % (i, n, i, t)
        #前一隻猴子帶走一份桃子後剩餘的桃子總數
        n = (monkey-1) * t
#定義功能函數
def fun():
    #從1開始
    k = 1
    while True:
        t = k
        #循環次數
        for i in xrange(monkey-1):
            #當前猴子應拿走桃子數爲tc,吃拿之前總量應爲 monkey * tc + 1,前一個猴子拿走桃子數爲tp,則有 (monkey-1) * tp = monkey * tc + 1
            t = monkey * t + 1
            #在for循環中含有break時則直接終止循環,不執行else
            if t % (monkey-1): break
            t /= (monkey-1)
        #當迭代的對象迭代完併爲空時,位於else的子句將執行,即找到符合條件最小整數
        else:
             print u'如果猴子%d只:'% monkey
             print u'桃子總數要%d個:'% (monkey * t + 1)
             show(monkey * t + 1)
             break
        k += 1
fun()

運行結果:
運行結果

發佈了91 篇原創文章 · 獲贊 132 · 訪問量 53萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章