`

Joseph—约瑟夫环 线性复杂度

阅读更多
    说有n个要被处决的人(编号0~(n-1)),从0开始报数,报到(m-1)的会被杀掉,剩下的人继续从0开始报数,如此下去最后剩的一个人会存活下来。说Joseph发现了这个规律而且把他透露了出来,现在假如你在这n个人里面,你会选择几号位置站下。

  很显然你会选择能活下来的那个位置,所以问题就是如何得到这个位置。

  首先想到的是模拟(至少我笨脑子是这么想的),但无论是用链表还是用数组这个时间复杂度都是比较高的,至少交题的时候会TLE,这里介绍一种线性时间的解法,出自大师Knuth的哦。

  考虑下第一次杀人的时候,编号为k = (m - 1) % n的同学挂了,那我们从k + 1重新从0开始编号

  k + 1 ==> 0

  k + 2 ==> 1

  ……

  ……

  k - 2 ==> n - 2

  k - 1 ==> n - 1

  好了,剩余的n - 1个同学又组成了一个新的Joseph环,对新环来说,编号k = (m - 1) % (n - 1)的同学会挂,如此下去,这里面似乎有某种规律可寻。

  考虑到不会死的同学一直不会被杀(废话),我们设i个同学时的不会挂的同学的编号(即解)为x,那么当死掉一个同学剩余i - 1个同学的时候,x仍然不会被杀,但此时的x已经由编号变换变成了x’,即x’是i - 1的情况时的解!一直推下去直到i - (i - 1)即1的情况,那1的时候解明显是0嘛!(注意编号是从0开始的),倒推回来,那问题不就解决了么!

  好了,分析清楚了剩下的就只是数学推导了,这个我比较烦,直接给公式吧:

  向下变换:x’ = (x - (k + 1)) % i;

  向上变换:x = (x' + k + 1) % i;

  其中:  k = (m - 1) % i;

  带入可得:x = (x’ + m) % i;

令f[i]表示i个人玩游戏报m退出,最后胜利者的编号自然是f[n],递推公式:
f[1]=0;
f[i]=(f[i-1]+m)%i; (i>1)
分享到:
评论

相关推荐

    Joseph约瑟夫环算法

    非常简单的约瑟夫环算法:用C++语言编译,采用键表功能实现约瑟夫环问题的实现。

    Joseph Ring 约瑟夫环

    C++实现的约瑟夫环 Joseph Ring

    VC MFC Joseph Link约瑟夫环出列顺序动画演示 源代码

    VC MFC Joseph Link约瑟夫环出列顺序动画演示 源代码 数据结构课程设计优秀作品

    约瑟夫环实验报告

    用vc6.0环境实现的约瑟夫环的上机实验报告

    joseph约瑟夫.砍头函数

    joseph约瑟夫.砍头函数joseph约瑟夫.砍头函数joseph约瑟夫.砍头函数

    Joseph.c约瑟夫环源码

    Joseph环,约瑟夫环,源代码 自己没事写的- -

    joseph环joseph环joseph环joseph环joseph环

    joseph环joseph环joseph环joseph环joseph环joseph环joseph环joseph环joseph环joseph环joseph环joseph环

    joseph约瑟夫环

    joseph code约瑟夫环用C++6。0编写。

    约瑟夫环程序代码(顺序表实现)

    通过简单的程序解决约瑟夫环问题 c++文件

    约瑟夫环_约瑟夫环c++_

    完成约瑟夫环的c++实现,适合大一c++新学习者借鉴The C + + implementation of Joseph Ring is completed which is suitable for freshmen to learn from

    约瑟夫环的实现代码及结果截图

    提供用户从键盘输入,Joseph约瑟夫环的必要数据,并显示出列顺序。 以单向循环链表实现该结构。

    约瑟夫环(C/C++实现)

    约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到...

    约瑟夫环代码 c语言约瑟夫

    约瑟夫环(Joseph)问题的一种描述是:编号为1、2、3……n的n个人按照顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数的上限值m,从第一个人开始按照顺时针的方向自1开始顺序报数,...

    约瑟夫环(Joseph)问题

    一开始任选一个报数上限值m,从第一个人开始按顺时针方向自1开始报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他顺时针方向上的下一个人开始,重新从1开始报数,如此下去直至所有人全部出列为止。...

    数据结构 约瑟夫环 C++

    数据结构C语言版-严蔚敏里的约瑟夫环问题,用C++实现。Visual Studio 2005/2008

    C语言课程设计—约瑟夫环.doc

    C语言课程设计—约瑟夫环

    约瑟夫环-数据结构.doc

    数据结构期末 试验报告 学院: 专业: 学号: 班级: 姓名: 2010.12.12 Joseph约瑟夫环上机实验报告 实验名称:joseph约瑟夫环 题目要求的约瑟夫环操作:编号是1,2,……,n的n个人按照顺时针方向 围坐一圈,每个人...

    约瑟夫环(Joseph)问题

    约瑟夫(Joseph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数...

    约瑟夫环(C++)

    cout**************************约瑟夫环课程设计***********************\n\n"; cout软件1001: 许海\n"; cout日期: 2012.7.26\n\n"; cout*****************************************************************...

Global site tag (gtag.js) - Google Analytics