1 问题描述

引用自《算法设计与分析基础》第三版:

约瑟夫斯问题,是以弗拉瓦斯。约瑟夫斯(Flavius Josephus)的名字命名的。约瑟夫斯是一个著名的犹太历史学家,参加并记录了公元66—70年犹太人反抗罗马的起义。约瑟夫斯作为一个将军,设法守住了裘达伯特的堡垒达47天之久,但在城市陷落了以后,他和40名顽强的将士在附近的一个洞穴中避难。在那里,这些反抗者表决说“要投降毋宁死”。于是,约瑟夫斯建议每个人应该轮流杀死他旁边的人,而这个顺序是由抽签决定的。约瑟夫斯有预谋地抓到了最后一签,并且,作为洞穴中的两个幸存者之一,他说服了他原先的牺牲品一起投降罗马。

上述是约瑟夫斯问题的起源,看完后个人感觉有点抽象,其实约瑟夫斯问题的本质为:n个人(编号由 1,2, …, n)围成一圈,由编号为1的人从1开始报数,报到k的退出自杀,剩下的人继续从1开始报数,直到圈内只剩余1人,求胜利者的编号。(n>0, k>0)

例如:

原n个人编号:

1 2 3 4 … … n-1 n

现在进行报数:

1 2 3 4… k(出列自杀) 1 2 …(循环报数,当到达编号为n的人时,下一个报数的从编号为1的人开始进行)

2 解决方案

约瑟夫斯问题的核心即找出给定n个人从前到后的自杀顺序,最后一个将要进行自杀的人即为幸存者。

具体编码如下:

package com.liuzhen.chapter4;

import java.util.Scanner;

public class JosephProblem {
/*
* 参数n:给定总人数
* 参数k:报数为k的人出列
* 函数功能:返回n个人从前到后的自杀顺序
*/
public int[] getKillOrder(int n,int k){
int[] result = new int[n];
int[] man = new int[n];
for(int i = 0;i < n;i++)
man[i] = i+1; //给n个人编号,编号分别为1~n
int count = 0; //用于计算当前已经自杀的人数
int pos = -1; //用于记录遍历数组man当前下标
int tempK = 0; //用于计算报数大小,一旦tempK = k,则喊到k的人出列
while(count < n){
pos = (pos+1)%n; //遍历过程中,会出现环列,取余可以除去环的影响
if(man[pos] != 0) //man[pos] == 0,表示此人已自杀
tempK++;
if(tempK == k){
result[count++] = man[pos]; //记录当前自杀人的编号
man[pos] = 0;
tempK = 0;
}
}
return result;
} public static void main(String[] args){
JosephProblem test = new JosephProblem();
Scanner in = new Scanner(System.in);
System.out.println("请输入约瑟夫斯问题的总人数n:");
int n = in.nextInt();
System.out.println("请输入约瑟夫斯问题的报数设定值k:");
int k = in.nextInt();
int[] result = test.getKillOrder(n,k);
System.out.println("共"+n+"人,依次报数,当报到"+k+"的人自杀,其自杀顺序为:");
for(int i = 0;i < result.length;i++)
System.out.print(result[i]+" ");
}
}

运行结果:

请输入约瑟夫斯问题的总人数n:
请输入约瑟夫斯问题的报数设定值k:
共6人,依次报数,当报到2的人自杀,其自杀顺序为:
4 6 3 1 5 请输入约瑟夫斯问题的总人数n:
请输入约瑟夫斯问题的报数设定值k:
共7人,依次报数,当报到2的人自杀,其自杀顺序为:
4 6 1 5 3 7 请输入约瑟夫斯问题的总人数n:
请输入约瑟夫斯问题的报数设定值k:
共10人,依次报数,当报到3的人自杀,其自杀顺序为:
6 9 2 7 1 8 5 10 4

详细的可以看另一篇文章约瑟夫斯问题

Java实现约瑟夫斯问题的更多相关文章

  1. 算法笔记_029:约瑟夫斯问题(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 引用自<算法设计与分析基础>第三版: 约瑟夫斯问题,是以弗拉瓦斯.约瑟夫斯(Flavius Josephus)的名字命名的.约瑟夫斯是一 ...

  2. 约瑟夫斯问题-java版数组解法和链表解法

    10个人围成一圈,从1到10编号,从1开始数,数到3或3的倍数的位置,则该位置的人出局,求最后剩下哪一个号? 数组解法: 数组存放数组:a[10]存在1到10编号人 数组遍历到尾部又从头遍历:遍历数组 ...

  3. Java 解决约瑟夫问题

    约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为约瑟夫环.又称“丢手绢问题”.) 有这样一个故事,15个教徒和15个非教徒在深海遇险必须讲 ...

  4. Java实现约瑟夫环问题

    约瑟夫环问题起源于一个犹太故事.约瑟夫环问题的大意如下: 罗马人攻占了桥塔帕特,41个人藏在一个山洞中躲过了这场浩劫.这41个人中,包括历史学家Josephus(约瑟夫)和他的一个朋友.剩余的39个人 ...

  5. java中约瑟夫环代码实现

    问题原型: 传说在很久很久以前,有一架搭载着n个人的飞机出现了故障,迫降在了一个荒岛上.飞机彻底报废后,这些人用飞机的残骸建成了一艘只能容纳一个人乘坐的小船,那么怎么去确定这n个人中哪个人有资格上船呢 ...

  6. 用ArrayList(解决约瑟夫问题)

    约瑟夫问题(Josephus problem)又称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,约瑟夫问题类似问题又称为约瑟夫环."丢手绢问题". 据 ...

  7. Java实现 蓝桥杯 算法提高 奥运会开幕式

    试题 算法提高 奥运会开幕式 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 学校给高一(三)班分配了一个名额,去参加奥运会的开幕式.每个人都争着要去,可是名额只有一个,怎么办?班长 ...

  8. java实现蓝桥杯约瑟夫环

    n 个人的编号是 1~n,如果他们依编号按顺时针排成一个圆圈,从编号是1的人开始顺时针报数. (报数是从1报起)当报到 k 的时候,这个人就退出游戏圈.下一个人重新从1开始报数. 求最后剩下的人的编号 ...

  9. javascript中使用循环链表实现约瑟夫环问题

    1.问题 传说在公元1 世纪的犹太战争中,犹太历史学家弗拉维奥·约瑟夫斯和他的40 个同胞被罗马士兵包围.犹太士兵决定宁可自杀也不做俘虏,于是商量出了一个自杀方案.他们围成一个圈,从一个人开始,数到第 ...

随机推荐

  1. [hdu5348]图上找环,删环

    http://acm.hdu.edu.cn/showproblem.php?pid=5348 题意:给一个无向图,现在要将其变成有向图,使得每一个顶点的|出度-入度|<=1 思路:分为两步,(1 ...

  2. Linux 物理卷(PV)、逻辑卷(LV)、卷组(VG)管理

    (一)相关概念 逻辑卷是使用逻辑卷组管理(Logic Volume Manager)创建出来的设备,如果要了解逻辑卷,那么首先需要了解逻辑卷管理中的一些概念. 物理卷(Physical Volume, ...

  3. springmvc 校验--JSR

    1.使用JSR规范是简单使用的,如果使用hibernate校验则需要在工程中添加hibernate-validate.jar,以及其他依赖的jar包. 2,在mvc配置文件中使用<mvc:ann ...

  4. Docker & k8s 系列二:本机k8s环境搭建

    本篇将会讲解k8s是什么?本机k8s环境搭建,部署一个pod并演示几个kubectl命令,k8s dashboard安装. k8s是什么 k8s是kubernetes的简写,它是一个全新的基于容器技术 ...

  5. 你了解C#的协变和逆变吗

    从C# 4.0开始,泛型接口和泛型委托都支持协变和逆变,由于历史原因,数组也支持协变. 里氏替换原则:任何基类可以出现的地方,子类一定可以出现. 协变(out) 协变:即自然的变化,遵循里氏替换原则, ...

  6. goland pojie

    goland pojie 只适用于goland2019.1.3之前的版本,之后的版本没法支持. 1. 步骤 修改vm启动参数 激活正版 2. agent 网上有很多agent都是不能用的,我上传一个可 ...

  7. React面试题汇总

    1.如何理解React中的组件间数据传递? ①父-子  通过props传递 ②子-父  在父中创建一个可以修改state的方法,之后把这个方法通过props传递给子,在子中调用这个方法 从而达到修改父 ...

  8. 关于mysql的metadata lock

    昨天晚上上线,却发现一个ddl语句长时间没有生效 查processlist, 发现包括ddl语句在内的众多查询提示 “Waiting for table metadata lock” 唯一没有该提示的 ...

  9. 三、$JavaScript(1)

    1.闭包 闭包就是能够读取其他函数内部变量的函数 闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以 ...

  10. 【Oracle】CentOS7/CentOS8命令行重启Oracle 11G R2

    写在前面 按照读者朋友的要求写了一篇<[Oracle]CentOS7/CentOS8命令行安装Oracle 11G R2>,由于读者完全是按照我的安装方式安装的Oracle数据库,也是将O ...