一.单向链表模拟

class Node:def __init__(self, num, next):self.num = numself.next = nexta = []
# n个人
n = 3
# 数到k的人死去
k = 2
for i in range(0, n):a.append(Node(i, (i + 1) % n))
# 计数器
counter = 1
# 现在的人
now = a[0]
while True:next = a[now.next]if next == now:#就剩下一个人了,游戏结束breakelse:counter += 1if counter == k:#计数器为k,要死人了counter = 0now.next = next.nextprint(str(next.num)+" has died",end='\n')else:#不死人,now=next,向后走一格now=next
#打印唯一的幸存者
print(now.num)

二.递推公式法

f(n)=[f(n-1)+k]%n

编号从0开始,f(n)表示n个人数到k的死去最后的幸存者,显而易见第一个死去的人是(k-1)%n,死者后面一人编号为0,再后面为1,以此类推,构成一个新的f(n-1).所以f(n)中的幸存者就是f(n)=[f(n-1)+k]%n.

#n个人
n=100
a=[0]*n
#数到k的人死去
k=2
a[1]=0
for i in range(1,len(a)):a[i]=(a[i-1]+k)%i
for i in range(1,len(a)):print(a[i],end=' ')

输出为

0 0 2 0 2 4 6 0 2 4 6 8 10 12 14 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 

很显然可以找到规律,数字周期为第0个周期长度为1,第1个周期长度为2,第2个周期长度为4,第三个周期长度为8....对于数字n,它所在的周期为log2(n),数字n在周期中的列数为n-2^log2(n).

当k=2时,f(n)=[n-2^log2(n)]*2

验证上述结论:

from math import  *
for i in range(1,100):print((i-2**int(log2(i)))<<1)

在上述表述中,一切计数都从0开始.从0开始,你会发现问题的表达形式会简单很多,从0开始计数确实应该成为一种习惯.

三.k=2时的另一种递推公式

f(2n)=2*f(n)

f(2n+1)=f(n)+1

下标一律从0开始,当有2n个人,数完一圈之后,奇数号人全跪了.给剩下的人重新编号,原来的0号还是0号,原来的2号变成1号,原来4号变成2号....即原来的2n号变成了现在的n号.剩下n个人的幸存者为第f(n)号,这个人对应原来的f(n)*2号.所以f(2n)=2f(n).

当有2n+1个人,数完一圈之后,奇数号人全跪了,最后一个人2n号没有跪,下一个跪的是0号.这样第一圈算跪了n+1个人.对剩下的n个人重新编号,原来的2号变成0号,原来的4号变成1号,原来的6号变成2号,原来的8号变成3号....即原来的2n号变成了现在的n-1号.剩下n个人的幸存者为f(n)号,对应原来的(f(n)+1)*2号,所以f(2n+1)=2f(n)+2.

对于这种问题,关键在于重新编号.

四.比较快的递推公式法

递推公式f(n)=(f(n-1)+k)%n,复杂度为O(n).有一个更快的递推式:

f(n)=[f(n-n/k)+n-n%k+f(n-n/k)/(k-1)]%n

f(n-n/k)第一轮输完之后,n/k个人死了,就剩下n-n/k个人.剩下的任务就是找到f(n-n/k)这个人对应f(n)中的哪个人.f(n-n/k)每(k-1)个人中可以插入一个死者,这些死者是要算数的.最后一个死者是n-n%k,他的下一个为0号,这是偏移量.这个递推公式复杂度

f(n)=常数*f(n-n/k)

复杂度为log(n)级别.

五.关于约瑟夫环

约瑟夫环花样繁多,比如给定一个数组

1 4 当第一个人死去,下一个死去的人是第一个人左边的第4个人

2 3 当2号人死去,下一个死去的人是第二个人左边第3个人

3 4 当3号人死去,下一个死的人是他左边的第4个人

...

给定一个数组,问最后的幸存者是谁.

这个问题可以用线段树来求解.

北航算法作业一 约瑟夫环问题相关推荐

  1. 数据结构与算法作业3——约瑟夫环问题(循环链表)

     第二次作业: 习题2 载具杀手与时停高手(约瑟夫环问题) 著名绅士简尚夫有一项特殊的天赋,他可以摧毁任意一辆载具(载具杀手).他的朋友狄傲可以将时间暂停(时停高手).他俩玩一个游戏. 有N辆车,编号 ...

  2. c语言约瑟夫环问题,C++_详解约瑟夫环问题及其相关的C语言算法实现,约瑟夫环问题 N个人围成一圈 - phpStudy...

    详解约瑟夫环问题及其相关的C语言算法实现 约瑟夫环问题 N个人围成一圈顺序编号,从1号开始按1.2.3......顺序报数,报p者退出圈外,其余的人再从1.2.3开始报数,报p的人再退出圈外,以此类推 ...

  3. 【算法经典】 约瑟夫环问题

    [前言]本文讨论经典算法问题约瑟夫环问题的递归解法. 一.问题描述 作为算法中的经典问题,约瑟夫环问题自诞生以来有各种各样的变种描述,丢手绢.游戏获胜者.圆圈中最后剩下的数字.点名游戏等等,但都是同样 ...

  4. 约瑟夫环算法c语言,约瑟夫环的c语言实现(代码已实现)

    # include #define MAXLEN 20 int front=MAXLEN-1;//队列初始化 int rear=MAXLEN-1; enqueue(int q[],int x) //入 ...

  5. 约瑟夫环问题-以python为舟

    约瑟夫环问题-以python为舟 文章目录 约瑟夫环问题-以python为舟 前言 一.约瑟夫环的实现原理 二.具体的实现方法 1.分割列表-用于解决重新报数问题 2.完整代码 运行结果 总结 前言 ...

  6. 一文读懂约瑟夫环算法

    2020-05-25 20:13:40 作者 | 扬帆向海 责编 | 王晓曼 出品 | CSDN博客 问题描述 约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的 ...

  7. 消除左递归c++代码_【每日算法Day 85】图解算法:一行代码解决约瑟夫环的变体...

    题目链接 LeetCode 390. 消除游戏[1] 题目描述 给定一个从 到 排序的整数列表. 首先,从左到右,从第一个数字开始,每隔一个数字进行删除,直到列表的末尾. 第二步,在剩下的数字中,从右 ...

  8. 数据结构与算法--我们来玩丢手绢(约瑟夫环问题)

    我们来玩丢手绢 昨天我们打扑克,今天我们丢手绢 丢手绢我们都知道这个游戏,他的由来由约瑟夫 (Josephus)提出来的 据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,3 ...

  9. C语言约瑟夫报数出圈算法,c语言实现约瑟夫环问题

    (一)基本问题 1.问题描述 设有编号为1,2,-,n的n(n>0)个人围成一个圈,每个人持有一个密码m.从第一个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m ...

最新文章

  1. php doss_php下ddos攻击与防范代码
  2. 中国科协发布20个重大科学问题和工程技术难题
  3. c语言求两者之间最小数,C语言课件第2章基本数据类型.ppt
  4. asp.net使用httphandler打包多CSS或JS文件以加快页面加载速度
  5. Nginx+Supervisor安装部署.NET Core项目
  6. 16行代码AC——紫书| 例题7-3 Fractions Again?! (UVA - 10976)_时间复杂度O(n)
  7. Json 与GeoJson
  8. 银联在线支付---利用测试案例代码模拟支付应用(修改)
  9. GRUB中硬盘和分区编号,UUID
  10. 大数据是企业未来最重要的资源
  11. 刚刚人均国民收入突破1万美元,作为打工人的你有感知吗?
  12. html评论和回复评论_佟丽娅“挑衅”贾玲,评论区晒刘德华合照,贾玲高情商回复佩服...
  13. 电力系统微型计算机继电保护试题及答案,全国2010年7月高等教育自学考试电力系统微型计算机继电保护试题及答案.doc...
  14. 深度学习识别手写字体数字
  15. 时序约束系列之D触发器原理和FPGA时序结构
  16. ECSHOP漏洞集:http://sebug.net/appdir/ECSHOP
  17. stream筛选出集合中对象属性重复值
  18. 小程序开发笔记(二):微信小程序富文本编辑器editor的使用
  19. GIMP 快速入门(2)
  20. win11系统用户账户控制总是弹出来?

热门文章

  1. Android四大组件之BroadCastReceiver
  2. enter your credential for http://dev.azure.....Fatal:Authentication failed for ;;
  3. php 批量修改文件,php如何批量修改文件名
  4. koa mysql 存储过程_Sql中判断数据库、表、临时表、存储过程和列是否存在...
  5. S.O.L.I.D.类设计原则
  6. 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-5 random direction ONB
  7. 字符串,那些你不知道的事
  8. requests不加代理
  9. 运行时异常与一般异常的区别
  10. C#基础(七)虚函数