2025年4月15日 星期二 乙巳(蛇)年 正月十六 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

基督徒问题的三种python实现方式

时间:12-06来源:作者:点击数:17

问题:

有15个基督徒和15个非基督徒在海上遇险,为了能让一部分人活下来不得不将其中15个人扔到海里面去。

有个人想了个办法就是大家围成一个圈,由某个人开始从1报数,报到9的人就扔到海里面,他后面的人接着从1开始报数,报到9的人继续扔到海里面,直到扔掉15个人。

由于上帝的保佑,15个基督徒都幸免于难,问这些人最开始是怎么站的,哪些位置是基督徒哪些位置是非基督徒。

方案一:位置标记

思路:

由于需要标记哪些位置是非基督徒(被扔海里的人),所以30个人的位置不能变,被扔海里的人的位置还需要留着。

所以用people来轮询报数的人的位置,由于是个圈,所以超过30之后要取余数。

用'1'表示活着,用'0'表示丢海里死掉了,是个空位置。

所以刚开始的时候有30个'1'。

然后每次数到9,就把'1'变成'0',报数的时候先判断那个位置上有没有人(是‘1’还是‘0’),没人(‘0’)就跳过。

  • people_list = list('1'*30) # 用1表示活着
  • people = 0 # 位置索引
  • dead = 0 # 统计死掉的人
  • count = 1 # 报数
  • while dead < 15:
  • people = people % 30 # 围成一个圈,所以30个人不停循环
  • if people_list[people] == '1': # 如果这个人还没死
  • if count == 9: # 如果他报了9
  • people_list[people] = '0' # 那他就死了
  • dead = dead + 1 # 死掉的人+1
  • count = 1 # 重新报数
  • else: # 如果不是报的9
  • count = count + 1 # 下一个人报数+1
  • people = people + 1 # 下一个人继续
  • print(people_list)

结果:

类似的思路也可以用来解决灯开关的问题:

有100盏灯,初始状态为关闭,全由拉绳开关控制。

第一次:被3整除的灯拉一次开关。

第二次:被5整除的灯拉一次开关。

第三次:被7整除的灯拉一次开关 。

最后有几盏灯亮,分别是哪几盏灯?

  • deng = list('开'*100)
  • def on_down(i):
  • global deng
  • if deng[i] == '开':
  • deng[i] = '关'
  • else:
  • deng[i] = '开'
  • for i in range(100):
  • if (i+1)%3 ==0:
  • on_down(i)
  • if (i+1)%5 ==0:
  • on_down(i)
  • if (i+1)%7 ==0:
  • on_down(i)
  • print(deng)

方案二:重新组队

双向队列可以同时在左右两边进行增加和删除,每次把队列左边的8个人拿出来放到队列右边,这时候最左边的人就是报数9的人,毫不犹豫地杀掉,然后继续从左边取8个人放到队列右边,重复15次就完事了。

  • import collections
  • q = collections.deque([i for i in range(1, 31)]) # 从130的队列
  • for _ in range(15): # 重复15次,杀掉15个人
  • for _ in range(8): # 每次拿出8个人
  • q.append(q.popleft()) # 把这8个人从左边放到右边
  • q.popleft() # 拿完8个人就杀掉最左边的人(第9个人)
  • print(q)

结果:

其实用列表也可以更简单地实现:

  • lists = [i for i in range(1, 31)]
  • for i in range(15):
  • lists = lists[9:] + lists[:8] # 第9个人之后的队伍和前8个人重新组成数组
  • print(lists)

结果:

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐