约瑟夫环算法

首先阐述一下问题:n个人(编号0—n-1)围成一圈,从1开始报数,报到m的人出列,然后从出列的人的下一个人开始,从1开始报数,报到m的人出列,求出最后幸存的那个人的原始编号。

如果单纯的是模拟整个游戏过程的话,实现起来并不难。今天我学习到的是另一种算法。举个例子,第一轮以后,假设被淘汰的人编号是k-1,报数是m,那么接下来的n-1的应该是这样排序x`(x),x`表示上一轮的编号,x表示本轮的编号。那么目前的情况应该是这样的k(0)、k+1(1)、k+2(2)、……、k-2(n-2),我们可以得出这么一个公式x`=(x+k)%N因为最后一个幸存者他最后的编号一定是0,那么有此推出他的上一轮编号……直到推出一开始的编号为止

时间: 2024-10-13 07:29:34

约瑟夫环算法的相关文章

关于约瑟夫环算法,数组解决

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止.然而Josephus 和他的朋友并不想遵从.首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人.接着,再越过k-1个人,并杀掉第k个人.这个过程沿着圆圈一直

【转】约瑟夫环算法---------题目:有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的人退出圈子,问最后最后留下的是原来第几号的那位.

提示:用环形链表实现 对于这个题目其实就是用c语言的循环链表实现一个约瑟夫环.我们可以定义一个循环链表,将这n个人加入到链表中,然后定义三个节点指针在链表上循环,移动跨度为3,利用链表的循环功能每次删除第三个节点,这边要注意的一个问题就是你定义的是3个指针,且在循环中他们彼此也都是有 ->next关系,一般我们判断循环结束条件时都是一个节点的下一个节点是否为它本身(如ptr->next == ptr),这里我们要注意循环体中链接方向否则很可能出现无用指针导致错误,因为最后我们要剩下一个节点那么

算法:约瑟夫环问题

算法:约瑟夫环问题 [写在前面] 由于本人天生驽钝,所写代码和描述可能不堪入目,高手请移步.但是我一直在努力记录一下有用的知识点,给自己给朋友用,只是希望对大家有帮助. [问题描述] 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从第一个人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,求最后一个出圈的人的标号. [代码] void JOSEF(int n,int m) //:n个人

【算法题目】约瑟夫环问题

题目来源:<剑指offer>面试题45 题目:0,1,...,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 解法一:经典解法,用环形链表模拟圆圈.这种方法每删除一个数字需要m步运算,总共有n个数字,因此总的时间复杂度是O(mn).同时这种思路还需要一个辅助链表来模拟圆圈,其空间复杂度是O(n). int LastRemaining(unsigned int n, unsigned int m) { if (n < 1 ||

基本算法——约瑟夫环问题

关于约瑟夫环问题,我们可以从两种思路去实现,一种是用数组,另一种是采用链表. 用数组方法实现代码: 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #define M 8 5 int find(int *arr, int len); 6 int main(int argc, char* argv[]) 7 { 8 int size = atoi(argv[1]); 9 int* arr

趣味算法--约瑟夫环问题

问题描述 已知n个人(以编号1,2,3,...,n分别表示)围坐在一张圆桌上.指定编号为k的人开始从1报数,数到m的那个人出列:出列那个人的下一位又从1开始报数,数到m的那个人出列:以此规则重复下去,直到圆桌上的人全部出列. 分析解决 解决方法主要有逻辑分析.数学分析法. 逻辑分析:就是按照游戏规则一个个报数,报到m的人出局,结构层次简单清晰明了.这种方式实现主要采用顺序表实现 数学分析:采用数学方式归纳统计分析出每次出局人的规律,直接得出每次出局的人,然后以代码实现.这种方法需要较强的数学分析

cdoj525-猴子选大王 (约瑟夫环)

http://acm.uestc.edu.cn/#/problem/show/525 猴子选大王 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 有m个猴子围成一圈,按顺时针编号,分别为1到m.现打算从中选出一个大王.经过协商,决定选大王的规则如下:从第一个开始顺时针报数,报到n的猴子出圈,紧接着从下一个又从1顺时针循环报数,...,如此下去,最后剩

HDU 3089 (快速约瑟夫环)

Josephus again Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 652    Accepted Submission(s): 181 Problem Description In our Jesephus game, we start with n people numbered 1 to n around a circle

约瑟夫环的C语言数组实现

约瑟夫环问题的具体描述是:设有编号为1,2,--,n的n个(n>0)个人围成一个圈,从第1个人开始报数,报到m时停止报数,报m的人出圈,才从他的下一个人起重新报数,报到m时停止报数,报m的出圈,--,如此下去,知道剩余1个人为止.当任意给定n和m后,设计算法求n个人出圈的次序. 一开始看到这这个题目就是觉得这是一个环形的,想到了用链表和用指针,然后看题目的要求是使用数组实现.就先暂时放弃用链表的办法,用数组实现之后再用链表来实现. 一开始的思路是: 1.建立一个长度为n的数组. 2.取出位置编号