用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()

运行结果:
运行结果

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

曹宇飞丶

您的鼓励是我创作的最大动力!

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

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

打赏作者

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

抵扣说明:

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

余额充值