Josephus环问题
约瑟夫环问题
问题描述:
Josephus问题可以描述为如下的一个游戏:N个人编号从1到N,围坐成一个圆圈,从1号开始传递一个热土豆,经过M次传递后拿着土豆的人离开圈子,由坐在离开的人的后面的人拿起热土豆继续进行游戏,直到圈子只剩下最后一个人。例如:M=0,N=5,则游戏人依次被清除,5号最后留下;如果M=1,N=5,那么被清除的人的顺序是2,4,1,5,最后剩下的是3号。
如下是两种解题方法:
- 建立一个N大小的数组,存储N个人是否还在圈子内(0为在圈子内,-1为已经离开圈子),依次循环遍历整个数组,直到剩下的人数(left)为1。
public static void pass(int m, int n){
int[] num = new int[n];
int left = n; //剩下的人数
int index = 0; //当前遍历到的位置
while(left != 1){
for(int i = 0; i< m; i++){
if(num[index++] != 0) //如果当前人已经清除
i--;
if(index >= n)
index = 0;
}
while(num[index] != 0){
index++;
if(index >= n)
index = 0;
}
System.out.println("out number is " + (index + 1));
num[index] = -1; //将清除的数据下标置-1
index++;
if(index >= n)
index = 0;
left--;
}
}- 第二种方式,将1~N的数添加到一个ArrayList对列中,首先计算偏移量(mPrime),当mPrime小于对列长度的一半时,则从前往后依次遍历找到清除的元素;当mPrime大于对列长度的一半时,从后往前遍历找到清除的元素。
public static void pass2(int m, int n){
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i = 1; i <= n; i++)
list.add(i);
ListIterator<Integer> iter = list.listIterator();
int left = n; //剩下的人数
int item = 0; //the out number
for(int i= 1; i < n; i++){
int mPrime = m % left;
if(mPrime < left/2){ //如果当前的偏移量小于list长度的一半时
if(iter.hasNext())
item = iter.next();
for(int j = 0; j < mPrime; j++){
if(!iter.hasNext())
iter= list.listIterator();
item = iter.next();
}
}
else{ //当偏移量大于list长度的一半时,从后往前找
for(int j = 0; j< left - mPrime; j++){
if(!iter.hasPrevious())
iter = list.listIterator(list.size());
item = iter.previous();
}
}
System.out.println("out number is " + item);
iter.remove();
if(!iter.hasNext()) //有可能下一次循环mPrime就会小于left的一半
iter = list.listIterator();
left--;
}
}
总结
当M,N较大时,则第二种方法时间效率更高,实现表明,当N=100000,M=9000时(省略的两个算法中的syso语句),方法一个执行时间是30713ms,而第二种方法的执行时间仅为4891ms,M越大时方法一的时间效率会更差。
Josephus环问题的更多相关文章
- Josephus环类问题,java实现
写出一个双向的循环链表,弄一个计数器,我定义的是到三的时候,自动删除当前节点,很简单. package Com; import java.util.Scanner; /* * 约瑟夫环问题,有n个人组 ...
- 笔试算法题(11):Josephus环 & Fibonacci序列
出题:Josephus Cycle,约瑟夫环问题.k个数字连成一个环,第一个数字为1.首先从1开始计数删除第m个数字:然后从上次被删除的数字的下一个数字开始计数,删除第m个数字:重复进行第二步直到只剩 ...
- 第一个只出现一次的字符,josephus环,最大子数组和
#include<stdio.h> #include<stdlib.h> #include<string.h> #define MAXINT 0x7fffffff ...
- Josephus环的四种解法(约瑟夫环)
约瑟夫环 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个 ...
- xdu_1009: Josephus环的复仇(线段树)
题目链接 题意不难理解,解法具体看代码及注释吧.. #include<bits/stdc++.h> using namespace std; typedef long long LL; ; ...
- Josephus Problem的详细算法及其Python、Java实现
笔者昨天看电视,偶尔看到一集讲述古罗马人与犹太人的战争--马萨达战争,深为震撼,有兴趣的同学可以移步:http://finance.ifeng.com/a/20170627/15491157_0. ...
- C++编程经验总结1
面向对象的精髓: 主函数其实就是对于类的元素和动作的重新组合来进行一项活动. 一个思想概念:程设是清楚的,完美的. 数学是清楚的,是完美的. 物理是有趣的,尤其是量子物理 生物是清楚的,尤其是基因 外 ...
- 18063-圈中的游戏-(第九章第4题)-"数组指针的使用"-数学分析
代码借鉴CSDN大佬https://blog.csdn.net/weixin_41409140/article/details/88071047(对大佬的大佬代码进行分析) 18063 圈中的游戏 时 ...
- 谁能笑到最后,约瑟夫环-Josephus问题求解
一. 简述Josephus问题 N个人站成一环,从1号开始,用刀将环中后面一个人“消灭“”掉,之后再将刀递给下一个人,这样依次处理,最后留下一个幸存者. 二. 求解方法 1. 约瑟夫问题如果使用 ...
随机推荐
- centos上安装pygame
安装前依赖包检查及安装 python-devel SDL_image-devel SDL_mixer-devel SDL_ttf-devel SDL-devel numpy subversion po ...
- Spring缓存框架原理浅谈
运维在上线,无聊写博客.最近看了下Spring的缓存框架,这里写一下 1.Spring 缓存框架 原理浅谈 2.Spring 缓存框架 注解使用说明 3.Spring 缓存配置 + Ehcache(默 ...
- PHP基础知识之变量
定义: 变量用一个美元符号后面跟变量名来表示,如:$user 变量引用赋值: 引用赋值用一个&后面跟源变量名来表示,如:$copy=&$user(注:$bar = &(24 * ...
- asp.net 使用DroDownList来实现二级联动
今天做新闻发布系统的时候,用到了二级联动,我把使用方法记录下来,以便日后查阅以及帮助新手朋友们.下面是效果图: 下面来讲解一下实现的方法: 1.在.aspx页面中,拖入两个DroDownList控件. ...
- TestNG 与 Junit的比较
转自 http://www.blogjava.net/fanscial/archive/2005/12/14/23780.html 1. JDK 5 Annotations (JDK ...
- web Api 返回json 的两种方式
web api写api接口时默认返回的是把你的对象序列化后以XML形式返回,那么怎样才能让其返回为json呢,下面就介绍两种方法: 方法一:(改配置法) 找到Global.asax文件,在Applic ...
- 【实战Java高并发程序设计6】挑战无锁算法:无锁的Vector实现
[实战Java高并发程序设计 1]Java中的指针:Unsafe类 [实战Java高并发程序设计 2]无锁的对象引用:AtomicReference [实战Java高并发程序设计 3]带有时间戳的对象 ...
- shared_ptr
省去对象指针的显示delete typedef tr1::shared_ptr<int> IntPtr; IntPtr fun() { IntPtr p = new int(3); ret ...
- Zero Copy I: User-Mode Perspective
By now almost everyone has heard of so-called zero-copy functionality under Linux, but I often run i ...
- C# Winform中如何让PictureBox的背景透明
最近做winform程序,其中有个需求:有两个PictureBox完全重叠,上面一个需要透明,不能遮挡下面的,以为设置上面的BackColor为透明色就可以了,结果不行,上网搜了一下,发现对于我这种需 ...