算法笔记_029:约瑟夫斯问题(Java)
目录
1 问题描述
2 解决方案
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~nint 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: 6 请输入约瑟夫斯问题的报数设定值k: 2 共6人,依次报数,当报到2的人自杀,其自杀顺序为: 2 4 6 3 1 5 请输入约瑟夫斯问题的总人数n: 7 请输入约瑟夫斯问题的报数设定值k: 2 共7人,依次报数,当报到2的人自杀,其自杀顺序为: 2 4 6 1 5 3 7 请输入约瑟夫斯问题的总人数n: 10 请输入约瑟夫斯问题的报数设定值k: 3 共10人,依次报数,当报到3的人自杀,其自杀顺序为: 3 6 9 2 7 1 8 5 10 4
参考资料:
1.简单的约瑟夫环算法
算法笔记_029:约瑟夫斯问题(Java)相关推荐
- 约瑟夫斯问题 java代码及注释
import java.util.Scanner; /** created by Mokk1 */ public class 约瑟夫斯问题 { public static void main(Stri ...
- 约瑟夫斯问题-java版数组解法和链表解法
10个人围成一圈,从1到10编号,从1开始数,数到3或3的倍数的位置,则该位置的人出局,求最后剩下哪一个号? 数组解法: 数组存放数组:a[10]存在1到10编号人 数组遍历到尾部又从头遍历:遍历数组 ...
- 算法笔记_132:最大流量问题(Java)
目录 1 问题描述 2 解决方案 1 问题描述 何为最大流量问题? 给定一个有向图,并为每一个顶点设定编号为0~n,现在求取从顶点0(PS:也可以称为源点)到顶点n(PS:也可以称为汇点)后,顶点 ...
- 算法笔记_137:二分图的最大匹配(Java)
目录 1 问题描述 2 解决方案 1 问题描述 何为二分图的最大匹配问题? 引用自百度百科: 首先得说明一下何为匹配: 给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于 ...
- 算法笔记_218:花朵数(Java)
目录 1 问题描述 2 解决方案 1 问题描述 一个N位的十进制正整数,如果它的每个位上的数字的N次方的和等于这个数本身,则称其为花朵数. 例如: 当N=3时,153就满足条件,因为 1^3 + ...
- 排序算法笔记:堆排序 HeapSort in java
2019独角兽企业重金招聘Python工程师标准>>> /*** 堆排序* 简述:* 首先使用建立最大堆的算法建立好最大堆,然后将堆顶元素(最大值)与最后一个值交换,同时使得堆的长度 ...
- java heapsort_排序算法笔记:堆排序 HeapSort in java
/** * 堆排序 * 简述: * 首先使用建立最大堆的算法建立好最大堆,然后将堆顶元素(最大值)与最后一个值交换,同时使得堆的长度减小1 ,调用保持最大堆性质的算法调整,使得堆顶元素成为最大值,此时 ...
- 算法笔记_036:预排序(Java)
目录 1 问题描述 2 解决方案 2.1 检验数组中元素的唯一性 2.2 模式计算 1 问题描述 在计算机科学中,预排序是一种很古老的思想.实际上,对于排序算法的兴趣很大程度上是因为这样一个事实: ...
- 算法笔记_227:填写乘法算式(Java)
目录 1 问题描述 2 解决方案 1 问题描述 观察下面的算式: * * × * * = * * * 它表示:两个两位数字相乘,结果是3位数.其中的星号(*)代表任意的数字,可以相同,也可以不同, ...
最新文章
- excel 中编程:vba 入门
- J2EE事务并发控制策略总结
- 清明小长假不无聊:分享一大波影视网站和APP,轻松看全网视频
- DVWA教程(一) —— Low级别
- watir学习系列--Watir API介绍
- XML编辑器oXygen XML Editor V19大版本更新 | 附下载
- java中榨汁机的代码_《榨汁机食谱大全》(不断更新中)
- C++ : Hello, World! (基本输出)
- c语言射击类打飞机小游戏感悟
- 柏拉图和他的三个弟子的故事:如何寻找幸福?如何寻找理想伴侣?
- 用Python绘制各国新冠肺炎确诊病例发展趋势图
- 计算机桌面颜色异常怎样修复,电脑显示器变色怎么办?显示器颜色异常的原因及解决方法...
- C语言中如何定义全局变量
- 多领域 ASR 英语语料库——GigaSpeech 基本介绍——附有效下载教程
- sklearn——转换器(Transformer)与预估器(estimator)
- 如何在WPS 2019中将图片背景设置为透明
- JAVAEE 实训日志 一
- 【图像处理】获取图片像素点
- Shell 二进制转换成十六进制的方案
- 组合逻辑中的竞争与冒险