转贴:Josephus问题
1. 问题的由来
我们用一个循环连表来模拟他们的行为。为了省事,我直接找了一个一个java代码:
class Josephus
{
static class Node
{
int val; Node next;
Node(int v) { val = v; }
}
public static void main(String[] args)
{
int N = Integer.parseInt(args[0]);
int M = Integer.parseInt(args[1]);
Node t = new Node(1);
Node x = t;
for (int i = 2; i <= N; x = (x.next=new Node(i++)));
x.next = t;
while (x != x.next)
{
for (int i = 1; i < M; i++) x = x.next;
x.next = x.next.next;
}
Out.println( "Survivor is " + x.val);
}
}
3. 递归公式
喜欢这个问题的朋友肯定不满足上面的方法,很想知道更简单的算法。
其实Josephus问题中的序列确实存在递归的公式。但是递归公式的推导
比较麻烦,我就直接给出结果。如果想了解详细过程可以查阅相关资料。
假设有n个人,每次杀第m个人,则k为第k个被杀死的人...
j1: x <- k*m
j2: if(x <= n) 输入结果x
j3: x <- floor((m*(x-n)-1) / (m-1)), goto j1
以C语言实现如下:
unsigned josephus(unsigned m, unsigned n, unsigned k)
{
unsigned x = km;
while(x <= n) x = (m*(x-n)-1)/(m-1);
return x;
}
现在考虑一种m为2的特殊情形。
这时候有更简单的递归公式:
x = 2*n + 1 - (2*n+1-2*k)*2^log2((2*n)/(2*n+1-2*k))
其中,log2((2*n)/(2*n+1-2*k))为计算(2*n)/(2*n+1-2*k)以2为底的对数,
结果向下取整数。
联系2^log2((2*n)/(2*n+1-2*k))整体,可以理解为将(2*n)/(2*n+1-2*k)向下
舍取到2的幂。有些地方把这中运算称为地板函数,我们定义为flp2,下面是
C语言的实现:
unsigned flp2(unsigned x)
{
unsigned y;
do { y = x; x &= x-1; }while(x);
return y;
}
其中x &= x-1;语句是每次把x二进制最右边的1修改为0,直到最左边的1为止.
这种方法也可以用来计算x二进制中1的数目,当x二进制中1的数目比较小的
时候算法的效率很高。
{
unsiged t = (n<<1) - (k<<1) + 1;
return (n<<1)+1 - t*flp2((n<<1)/t);
}
现在考虑更为特殊的,m为2的情况, k为n的情形。
即,x = 2*n + 1 - 2^log2(2*n)
将n左移1位(即乘以2),然后将最右端设置为1(既加1),
最后将左端的1置为0(既减去2*n的向下取的2的幂)。
例如: n为1011001 -> 0110011 -> 110011
{
return ((n-flp2(n))<<1)|1;
}
{
static class Node
{
int val; Node next;
Node(int v) { val = v; }
}
public static void main(String[] args)
{
int N = Integer.parseInt(args[0]);
int M = Integer.parseInt(args[1]);
Node x = t;
x.next = t;
{
for (int i = 1; i < M; i++) x = x.next;
x.next = x.next.next;
}
Out.println("Survivor is " + x.val);
}
}
{
unsigned x = km;
while(x <= n) x = (m*(x-n)-1)/(m-1);
return x;
}
{
unsigned y;
do { y = x; x &= x-1; }while(x);
return y;
}
{
return ((n-flp2(n))<<1)|1;
}
{
unsiged t = (n<<1) - (k<<1) + 1;
return (n<<1)+1 - t*flp2((n<<1)/t);
}
参考knuth相关著作
using namespace std;
typedef struct Josephus
{
int value;
Josephus *next;
}JS,*pJS;
int main()
{
pJS l,p,q;
l=new JS;
l->value =1;
l->next =l;
q=l;
for (int i=2;i<=2000;i++)
{
p=new JS;
p->value =i;
p->next =l;
q->next =p;
q=q->next;
}
{
p=q->next;
q->next=q->next->next;
q=q->next;
delete p;
}
cout<<q->value<<endl;
system("pause");
return 0;
转贴:Josephus问题相关推荐
- Josephus Problem的详细算法及其Python, Java语言的实现
笔者昨天看电视,偶尔看到一集讲述古罗马人与犹太人的战争--马萨达战争,深为震撼,有兴趣的同学可以移步:http://finance.ifeng.com/a/20170627/15491157_0. ...
- 数据结构源码笔记(C语言):Josephus问题之顺序表
/*josephus_seq.c*/ /*Josephus问题: 顺序表实现*/#include <stdio.h> #include <stdlib.h>#define FA ...
- 数据结构源码笔记(C语言):Josephus问题之循环链接表
/*josephus_clist.c*/ /*Josephus问题:循环链接表实现*/#include <stdio.h> #include <stdlib.h>#define ...
- Josephus 问题相关
package com.bupt.syc;import java.util.Iterator; import java.util.LinkedList;import org.junit.Test;pu ...
- 约瑟夫问题(Josephus Problem)的两种快速递归算法
参考:http://haoyuanliu.github.io/2016/04/18/Josephus/ 转载于:https://www.cnblogs.com/xiaoshayu520ly/p/102 ...
- C/C++02: Josephus问题
据说著名犹太历史学家Josephus有过以下的故事: 在罗马人占领乔塔帕特後,39个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被人抓到,于是决定了一个自杀方式,41个 ...
- Josephus问题的Java解决方法
问题描述: 有N个人被困荒岛,岛上的资源只够1个人生存.他们决定通过以下方式减少生存人数. 所有人围成一圈,并依次编号为0至N-1.从第0号开始报数,报数从1至M,报到M号的人会被杀死. 被杀者后面的 ...
- Josephus问题(最后一个退出的人)
[问题:]如果有 m 个人围成一圈而坐,每个人的位置都带编号,编号从 1 到 m (没有重复的),从第一个位置开始数数,当数到 n 时,那个人退出圈子,再从退出的那个人的下一个位置开始数(假定是顺时针 ...
- (python)约瑟夫(Josephus)个人围成一圈,并按顺时针依次编号1-n。从编号为1的人开始,按顺时针方向每隔一 人选出一个,剩下的人重新围成一圈,如此循环直到剩下两人,这剩下的两人就是幸运儿
约瑟夫(Josephus)环问题 题目:n个人围成一圈,并按顺时针依次编号1-n.从编号为1的人开始,按顺时针方向每隔一 人选出一个,剩下的人重新围成一圈,如此循环直到剩下两人,这剩下的两人就是幸运儿 ...
最新文章
- 【C++】Google C++编码规范(一):作用域
- 忽悠神经网络指南:教你如何把深度学习模型骗得七荤八素
- SEL:世界土壤日Stefan Geisen报告(朱永官院士主持,12月4日)
- python计算学习_跟老齐学Python之用Python计算
- 曲阜有学计算机的学校吗,曲阜职业中专计算机专业课程上几年
- Sublime text 2/3 中 Package Control 的安装与使用方法
- 怎么更进一步学python_【百尺竿头,更进一步学Python】Python进阶课程——进程,线程和协程的区别...
- 文件写入的6种方法,这种方法性能最好
- 您认为有关垃圾收集的7件事-完全错了
- Python的特殊成员
- 数组——询问学号(洛谷 P3156)
- Python4班平均成绩统计_回首过去,展望未来 | 欢迎大家来到E班第一次主题班会!...
- MCU——简易单片机按键驱动程序分析
- 儒豹手机搜索发布2008年各频道关键词排行榜
- TI单芯片毫米波雷达代码走读(十四)—— 多普勒维(2D)处理之静态杂波滤除
- selenium 复制粘贴
- 可汗学院公开课:线性代数笔记-10-三元线性方程
- 1.1你是谁?你从哪来?你到哪去? -交给学习来解答
- java获取虎牙直播弹幕消息,虎牙直播弹幕筛选器
- 华为p9如何恢复手机删除的照片
热门文章
- Windows DNS Server 远程代码执行漏洞 (CVE-2021-24078) 的详细原理分析
- active-class属于Vue哪一个modules,有什么作用
- Jenkins任务优先分配到原来的执行节点上
- react native 0.50 源码解析 再出发 持续更新
- 寻求web和数据库开发的小哥哥
- locust===注意事项
- 转:GCC,LLVM,Clang编译器对比
- IE浏览器下常见的CSS兼容问题
- VC98\mfc\lib' specified in 'LIB environment variable' 系统找不到指定路径
- cshop是什么开发语言_mes用什么语言开发?mes开发平台