丢手帕问题 (约瑟夫问题)Java实现
问题:
丢手帕游戏是约瑟夫问题的一个变种,游戏很简单,N个小孩围成一个圈,标号为1到N,从编号为m的小孩开始报数,报到第L个小孩退出游戏,然后下一个小孩继续从1开始报数,数到第L个小孩退出游戏,如此循环,直到剩下最后一个小孩是胜利者.
使用环形链表方式解决问题:
代码如下:
/**
* 描述:
* @作者:niexiaohui
* @创建时间:2016年12月27日
* @修改记录:
*/
public class Test {
public static void main(String[] args) {
long starttime=System.currentTimeMillis();
CircleLinkList game=new CircleLinkList(10000, 99, 533);
long endtime=System.currentTimeMillis();
game.play();
long time2=System.currentTimeMillis();
System.out.println("创建链表用了"+(endtime-starttime)/1000.0+"秒");
System.out.println("玩游戏共用了"+(time2-starttime)/1000.0+"秒");
}
} class Child{
protected int no;
protected Child nextChild;
public Child(int no){
this.no=no;
}
} class CircleLinkList{
/**
* 参与游戏人数
*/
private int playBoys;
/**
* 从第几个开始数
*/
private int startIndex;
/**
* 数几个小孩退出
*/
private int countNum;
//首个小孩
private Child firstChild;
//标识当前小孩
private Child temp;
/**
*
* @param playBoys 参与游戏人数
* @param startIndex 从第几个开始数
* @param countNum 数几个小孩退出
*/
public CircleLinkList(int playBoys, int startIndex, int countNum) {
super();
this.playBoys = playBoys;
this.startIndex = startIndex;
this.countNum = countNum;
createList();
}
/**
* 创建循环链表
*/
private void createList() {
for (int i = 1; i <=playBoys; i++) {
if (i==1) {//第一个小孩
Child child=new Child(i);
this.firstChild=child;
this.temp=child;
}else if (i==playBoys) {//最后一个小孩
Child child=new Child(i);
this.temp.nextChild=child;
this.temp=child;
this.temp.nextChild=this.firstChild;//最后一个小孩的下一个小孩指向第一个小孩
}else {
Child child=new Child(i);
this.temp.nextChild=child;
this.temp=child;
}
}
} /**
* 玩游戏
*/
public void play(){
temp=firstChild;
//先找到从第几个小孩开始数
for (int i = 1; i < startIndex; i++) {
temp=temp.nextChild;
}
System.out.println("游戏开始,从第"+temp.no+"个小孩开始数,数到第"+this.countNum+"个小孩退出游戏");
while (this.playBoys>1) {
//找到要退出游戏的前一个小孩
for (int i = 1; i < countNum-1; i++) {
temp=temp.nextChild;
}
//当前temp是要退出的前一个小孩
Child leaveChild=temp.nextChild;//要退出的小孩
System.out.println("当前退出的小孩编号为:" +leaveChild.no);
temp.nextChild=leaveChild.nextChild;
if (leaveChild.no==firstChild.no) {//如果要退出的小孩是第一个小孩,则将第一个小孩重置为退出小孩的下一个小孩
this.firstChild=leaveChild.nextChild;
}
temp=temp.nextChild;
this.playBoys--;//玩游戏人数少一个
}
System.out.println("最后剩下的小孩是:"+ temp.no);
}
}
代码虽然不少,但是并不难懂,有过一点数据结构基础的还是很容易理解的.
使用数组方式解决问题:
代码如下:
/**
* 描述:
*
* @作者:niexiaohui
* @创建时间:2017年1月11日
* @修改记录:
*/
public class Test4 { public static void main(String[] args) throws InterruptedException {
long starttime = System.currentTimeMillis();
int childrens=10000;//玩游戏的小孩总数
int countNum=533;//数第几个小孩退出游戏
int startNum=99;//开始从第几个人开始数
int count=1;//计数器
int [] arrays=new int[childrens];
for (int i = 0; i < arrays.length; i++) {//为数组初始化值
arrays[i]=1;
}
loop:while(true){
for (int i = 0; i < arrays.length; i++) {
if (i<startNum-1) {//第一次循环找到从第几个小孩开始数数
continue;
}
startNum=0;//开始后将startNum清零
if (arrays[i]!=0) {//值为0的表示已经退出游戏
if (count%countNum==0) {//数到的小孩退出游戏
if (childrens==1) {
System.out.println("游戏胜利的小孩编号为:"+(i+1));
break loop;
}
arrays[i]=0;//退出游戏的小孩值设为0
count=0;//计数器清零,重新计数
childrens--;//玩游戏的人数减一
System.out.println("编号为"+(i+1)+"的小孩退出游戏");
}
count++;
}
}
}
long time2 = System.currentTimeMillis();
System.out.println("玩游戏共用了" + (time2 - starttime)/1000.0 + "秒");
} }
用数组方式解决问题代码少了很多,效率上,我大致比较了下,随着数到第L个小孩退出游戏,即L的增大,链表的速度会提升,相反数组会下降,如果L值很小的话,数组的效率是高于链表的效率的.
丢手帕问题 (约瑟夫问题)Java实现的更多相关文章
- 丢手帕问题(环形链表)---Java 待优化
/** * * @author Administrator * 功能:丢手帕问题 */ package com.litao; public class Demo4 { /** * @param arg ...
- java丢手帕 约瑟夫问题
一.问题描述: n个人围成一个圈,编号为1~n,从第一号开始报数,报到3的倍数的人离开,一直数下去,直到最后只有一个人,求此人编号. 二.问题提示: 使用一维数组,数组元素初始为1,从1开始 ...
- 丢手帕问题即约瑟夫问题的PHP解法
问题描述:n个人排成一圈.从某个人开始,依次报数,数到m的人被杀死.下一个人重新从1开始报数,数到m的人被杀死.直到剩下最后一个人. 解决思路:从数学角度去看,每一次报数决定谁去死是一个n.m的求余数 ...
- java面向对象编程--Josephu问题(丢手帕问题)
Josephu问题为:设编号为1,2,...n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推 ...
- 约瑟夫环形链表问题、丢手帕问题、剑指offer圆圈中最后一个数问题
public class Solution { // 左神解法,本题本质还是报数为m-1的倍数的人死.求最后一个活着的人是初始时候的哪个人 /* 报数(A) 实际人员编号(B) ...
- j使用数组实现约瑟夫环 java
我们首先来看一下约瑟夫环问题: 给定m个人,m个人围成一圈,在给定一个数n,从m个人中的第一个人每第n个人便将其除去,求被最后一个出去的人的编号. 思路: 建立一个长度为m+1的数组,将其的内容初始化 ...
- 约瑟夫环 java实现
问题: N个人从1到N编号.围城一圈,从1開始报数, 数到X时,将X的编号输出,并将那个人踢出, 下一个从1再開始报数,直到全部人都出去 思路: 就是计数.移除,没有太深的思想,直接上代码: pack ...
- P1996_约瑟夫问题(JAVA语言)_可能是最简单的解法了!
思路:使用队列模拟. 判断是否为出圈的数.如果不是,把数加入队列尾部:如果是,输出并删除. 题目背景 约瑟夫是一个无聊的人!!! 题目描述 n个人(n<=100)围成一圈,从第一个人开始报数,数 ...
- 约瑟夫问题 java
约瑟夫环:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围 ...
随机推荐
- LiveCharts文档-3开始-4可用的图表
原文:LiveCharts文档-3开始-4可用的图表 LiveCharts文档-3开始-4可用的图表 LiveCharts共有5类图表,你将会在后面的章节当中看到这些图表的使用方法. Cartesia ...
- Luogu P2482 [SDOI2010]猪国杀
这道题在模拟界地位不亚于Luogu P4604 [WC2017]挑战在卡常界的地位了吧. 早上到机房开始写,中间因为有模拟赛一直到1点过才正式开始码. 一边膜拜CXR dalao一边写到3点左右,然后 ...
- 分布式全文搜索引擎ElasticSearch
一 什么是 ElasticSearch Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elas ...
- host大法之GitHub上不去
dns解析慢,github上不去,慢 修改host. windows下路径为:C:\Windows\System32\drivers\etc\hosts Linux下路径:/etc/hosts 加入: ...
- 关于HashMap和Hashtable的区别
Hashtable的应用非常广泛,HashMap是新框架中用来代替Hashtable的类,也就是说建议使用HashMap,不要使用Hashtable.可能你觉得Hashtable很好用,为什么不用呢? ...
- Sublime Text3前端必备插件
安装Package Control 在安装插件之前,需要让sublime安装Package Control.打开Sublime Text的控制台,快捷键ctrl + ~,在控制台中输入以下代码. im ...
- Find Amir CodeForces - 805C (贪心+思维)
A few years ago Sajjad left his school and register to another one due to security reasons. Now he w ...
- [2017BUAA软工]第一次个人项目 数独的生成与求解
零.Github链接 https://github.com/xxr5566833/sudo 一.PSP表格 PSP2.1 Personal Software Process Stages 预估耗时(分 ...
- 队列----java实现
FIFO:先进先出 存储单元: public class Node { /* 元素有两部分: 元素 下一个元素的引用 */ Object data;//数据域 Node next; //指针域 pub ...
- 使用PHP + Apache访问有错误的php脚本时不报错
遇到一个问题: 在命令行编辑php脚本后,直接使用php命令行执行该php脚本,如果脚本出现错误,在命令行的情况下会报错,显示错误信息,比如下面的情况. [root@localhost wwwroot ...