【面向学渣编程】囚犯问题(十分详解,含表格,适合新手)

囚犯问题

问题描述

囚犯问题是这样的:
一群囚犯将被带到牢房里坐牢。看守们把他们集中在一起,宣布:

  1. 每个囚犯将被单独关在一个牢笼里。
  2. 每天会随机的抽取一个囚犯放风。
  3. 放风的地方有一盏电灯,囚犯可以任意开关这盏灯。
  4. 电灯永远有电,永远不会损坏。
  5. 囚犯在放风的地方以及回来的路上都不会被其他囚犯看见。
  6. 牢房相互之间隔绝,囚犯相互之间不可能传递任何消息。
  7. 囚犯在放风时,除了开关电灯除了开关电灯不能留下任何痕迹或者信息。
  8. 看守只负责随机抽取囚犯,不会帮助囚犯传递信息。
  9. 如果有人确定所有人都放过风,则可以通知看守,看守确认之后可以把所有囚犯释放;如果永远没有人通知,或者通知的人弄错了(并不是所有人都被放风过),则所有人将永久坐牢,永无出头之日。
  10. 囚犯们可以商议一个方法出来以避免永久坐牢,商议好之后就会被关进各自的牢房。

问题:囚犯们会商议出什么方法?

概括

问题很长,但简单来说,就是在***一定范围内一直生成随机数,当范围内所有数都被生成一遍后停止并报告。***

这是一个简单的一进制问题,类似于我们掰手指头,有一个就伸出一根手指。直到所有手指全部伸出来。这个问题的点就是在于我们什么时候去伸出拿一根手指,即:我们如何知道有一个囚犯是第一次出来放风。突破点就在那盏电灯上。

解法

这个题应当这么解:
找一个人当计数员,在现实中可以随意找一个人,在计算机程序中为了方便,选取最后一个人作计数员。

不同囚犯对灯的操作
如图,有没有多新的放过风的囚犯,计数员是以灯的开关为标准的,如果灯是开的就说明有人是第一次出来放风,放过风的人数就可以+1,直到所有普通囚犯计数完毕,再把自己加上,就是刚刚好。
现在,直接上代码:::::

import random


# n个囚犯,让随便一个做计数员
# 计数员见灯亮要关灯
# 普通囚犯第一次开灯,以后灭灯


def prison(n):  # n个囚犯
    counter = n - 1  # 计数员要知道一共有这么多人
    switch = [False] * n  # 所有人没开过灯
    lamb = False  # 灯一开始是关的
    persons = 1  # 人数统计
    while True:
        num = random.randint(0, n - 1)  # 随机拉一个囚犯
        if num == n - 1:  # 是计数员,如果灯开着,就关掉并+1,如果关着,就不管
            if lamb:
                persons += 1
                lamb = False  # 关灯
                if persons == n:  # 当计数等于所有人的时候
                    print('\n报告!所有人放风完毕')
                    break
                else:  # 人数不够继续
                    continue
            else:  # 灯是关着的不管
                continue
        else:
            if lamb:
                continue
            else:  # 如果灯是关着的
                if switch[num]:  # 如果该名囚犯开过灯,不开灯
                    continue
                else:  # 如果改名囚犯是第一次,打开灯
                    lamb = True
                    switch[num] = True
                    print('\n',num + 1, end='号囚犯开灯\n-------')


if __name__ == '__main__':
    prison(100)

运行结果
"G:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\python.exe" E:/study/python/coding/PythonApplication1/PythonApplication1/囚犯问题.py

 56号囚犯开灯
-------
 57号囚犯开灯
-------
 9号囚犯开灯
-------
 83号囚犯开灯
-------
 23号囚犯开灯
-------
 93号囚犯开灯
-------
 26号囚犯开灯
-------
 36号囚犯开灯
-------
 63号囚犯开灯
-------
 37号囚犯开灯
-------
 11号囚犯开灯
-------
 39号囚犯开灯
-------
 2号囚犯开灯
-------
 43号囚犯开灯
-------
 13号囚犯开灯
-------
 55号囚犯开灯
-------
 27号囚犯开灯
-------
 70号囚犯开灯
-------
 79号囚犯开灯
-------
 89号囚犯开灯
-------
 85号囚犯开灯
-------
 8号囚犯开灯
-------
 34号囚犯开灯
-------
 28号囚犯开灯
-------
 46号囚犯开灯
-------
 7号囚犯开灯
-------
 62号囚犯开灯
-------
 80号囚犯开灯
-------
 14号囚犯开灯
-------
 21号囚犯开灯
-------
 53号囚犯开灯
-------
 68号囚犯开灯
-------
 58号囚犯开灯
-------
 61号囚犯开灯
-------
 54号囚犯开灯
-------
 48号囚犯开灯
-------
 17号囚犯开灯
-------
 35号囚犯开灯
-------
 59号囚犯开灯
-------
 67号囚犯开灯
-------
 91号囚犯开灯
-------
 24号囚犯开灯
-------
 38号囚犯开灯
-------
 20号囚犯开灯
-------
 66号囚犯开灯
-------
 77号囚犯开灯
-------
 6号囚犯开灯
-------
 65号囚犯开灯
-------
 60号囚犯开灯
-------
 12号囚犯开灯
-------
 47号囚犯开灯
-------
 98号囚犯开灯
-------
 1号囚犯开灯
-------
 69号囚犯开灯
-------
 78号囚犯开灯
-------
 92号囚犯开灯
-------
 84号囚犯开灯
-------
 72号囚犯开灯
-------
 31号囚犯开灯
-------
 71号囚犯开灯
-------
 64号囚犯开灯
-------
 16号囚犯开灯
-------
 4号囚犯开灯
-------
 73号囚犯开灯
-------
 87号囚犯开灯
-------
 96号囚犯开灯
-------
 42号囚犯开灯
-------
 40号囚犯开灯
-------
 82号囚犯开灯
-------
 19号囚犯开灯
-------
 90号囚犯开灯
-------
 41号囚犯开灯
-------
 22号囚犯开灯
-------
 5号囚犯开灯
-------
 10号囚犯开灯
-------
 44号囚犯开灯
-------
 30号囚犯开灯
-------
 95号囚犯开灯
-------
 97号囚犯开灯
-------
 33号囚犯开灯
-------
 81号囚犯开灯
-------
 75号囚犯开灯
-------
 52号囚犯开灯
-------
 99号囚犯开灯
-------
 86号囚犯开灯
-------
 45号囚犯开灯
-------
 88号囚犯开灯
-------
 18号囚犯开灯
-------
 3号囚犯开灯
-------
 49号囚犯开灯
-------
 29号囚犯开灯
-------
 25号囚犯开灯
-------
 76号囚犯开灯
-------
 15号囚犯开灯
-------
 94号囚犯开灯
-------
 51号囚犯开灯
-------
 74号囚犯开灯
-------
 32号囚犯开灯
-------
 50号囚犯开灯
-------
报告!所有人放风完毕

进程已结束,退出代码为 0

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

计科老学渣

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

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

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

打赏作者

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

抵扣说明:

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

余额充值