Josephus环的四种解法(约瑟夫环)基于java详解
作者:---dgw博客 发布时间:2022-02-28 23:29:13
标签:josephus,环,解法,约瑟夫环,java
约瑟夫环
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解
引用别人的一个图:直观说明问题
分析:
第一步:从1开始报数为3的时候就删除3号结点
第二步:从4号结点开始报数,当为3的时候删除6号结点;
第三步:从7号结点开始报数,当为3的时候删除1号结点;
第四步:从2号结点开始报数,当为3的时候删除5号结点;
第五步:从7号结点开始报数,当为3的时候删除2号结点;
第六步:从4号元素开始报数,当为3的时候删除8号结点;
第七步:又从4号开始报数,当为3的时候删除4号结点,此时链表中只有一个7号结点,所以最后的结点就是7号结点;
1.模拟解法
public class 模拟 {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
//总人数
int n=in.nextInt();
// 数到m的那个人出列
int m=in.nextInt();
// 初始化为0 都没有出去
int [] arr=new int[n];
//剩下的人数
int peopleLeft=n;
//初始化下标
int index=0;
// 下标计算器
int count=0;
// >0 出循环为负
while (peopleLeft>1){
if(arr[index]==0){
// count为计步器 不是下标指向
count++;
if(count==m){
arr[index]=1;
count=0;
peopleLeft--;
}
}
index++;
if(index==arr.length){
index=0;
}
}
for (int i = 0; i < arr.length; i++) {
if(arr[i]==0){
System.out.println(i+1);
}
}
}
}
2.递归解法
/**
* 递归式:
* f(1)=0; 第一个位置永远为0
* f(i)=f(i)+m%n;
*/
public static int yuesefu(int n,int m){
if(n==1){
return 0;
}else {
return (yuesefu(n-1,m) + m) % n;
}
}
public static void main(String[] args) {
System.out.println(yuesefu(41,3)+1);
vailCode(41,3);
}
//逆推验证代码
public static void vailCode(int a,int b){
System.out.print(b);
int reslut;
for (int i = a; i >=2 ; i--) {
reslut=2;
for (int j = i; j <=a ; j++) {
reslut=(reslut+b)%j;
}
System.out.printf("->%d",reslut+1);
}
}
3.循环链表解法
public class CircularLinkedList {
public static void main(String[] args) {
/**
* 节点类
*/
class Node{
private int data=1;
private Node next;
Node(){
next=null;
}
}
Node head,temp;
head=new Node();
head.data=1;
int a=41;
int b=3;
// 临时节点
temp=head;
for (int i = 0; i < a; i++) {
Node new_node=new Node();
new_node.data=i+1;
temp.next=new_node;
temp=new_node;
}
temp.next=head.next;
while (head.next!=head){
for (int i = 0; i < b-1; i++) {
head=head.next;
}
System.out.print("->"+(head.data+1));
head.next=head.next.next;
}
System.out.println(head.data);
}
}
4.Collection解法
public static void main(String[] args) {
int a=41;
int b=3;
LinkedList<Integer> list = new LinkedList<>();
for (int i = 0; i < a; i++) {
list.add(i+1);
}
while (list.size()>1){
for (int i = 0; i < b-1; i++) {
list.add(list.remove());
}
System.out.print("->"+list.getFirst());
list.remove();//remve head
}
System.out.println(list.getFirst());
}
来源:https://www.cnblogs.com/dgwblog/p/10086189.html


猜你喜欢
- 1. System.Char 字符char 是 System.Char 的别名。System.Char 占两个字节,16个二进制位。Syst
- 本文实例讲述了java使用Hashtable过滤数组中重复值的方法。分享给大家供大家参考,具体如下:package org.eline.co
- Java NIO读取大文件已经不是什么新鲜事了,但根据网上示例写出的代码来处理具体的业务总会出现一些奇怪的Bug。针对这种情况,我总结了一些
- 如下所示: /** * 判断某个界面是否在前台 * * @param context
- 目录springboot autoconfig的一些实验SpringBoot autoconfig部分注解说明SpringBoot auto
- 先看下效果图:这个需要用到1个开源的 库,这个后面也会说下的。工程目录:1. MainActivity.javapublic class M
- 工厂模式定义:提供创建对象的接口。为何使用工厂模式工厂模式是我们最常用的模式了,著名的Jive论坛,就大量使用了工厂模式,工厂模式在Java
- 1.内部类概念及分类将一个类定义在另一个类的内部或者接口内部或者方法体内部,这个类就被称为内部类,我们不妨将内部类所在的类称为外围类,除了定
- 一般我们在controller层调用service时,只需要使用@Autowired注解即可,例如如下代码我们经常看到:@RestContr
- 前言Kafka是现在非常热门的分布式消息队列,常用于微服务间异步通信,业务解耦等场景。kafka的性能非常强大,但是单个微服务吞吐性能是有上
- 本文实例讲述了android同时控制EditText输入字符个数和禁止特殊字符输入的方法。分享给大家供大家参考。具体分析如下:这里总结了三种
- JAVA 静态代理模式代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。代理模式说白了就是“真实对象”的代表,在访问对象
- 我们在使用一些开源调度系统(比如:elastic-job等)的时候,对于任务的执行时间通常都是有规律性的,可能是每隔半小时执行一次,或者每天
- 一、WIndow和windowManagerWindow是一个抽象类,它的具体实现是PhoneWindow,创建一个window很简单,只需
- 使用HttpServletRequest可以防止盗链行为,什么是盗链行为,比如说在一个别的网站上超链接,指向我们的网页中的某个数据,这样从他
- 由于公司的开发团队偏向于使用Java技术,而且公司倡导学习开源技术,所以我选择用Java语言来进行Selenium WebDriver的自动
- 详解 Java Maximum redirects (100) exceeded这些是可以用于定制默认HttpClient实现行为的参数:&
- 前言在JDK当中给我们提供的各种并发工具当中,比如ReentrantLock等等工具的内部实现,经常会使用到一个工具,这个工具就是LockS
- Java与Scala创建List与Map//JavaList<String> languages = new ArrayList
- 大家好,欢迎来到老胡的博客,今天我们继续了解设计模式中的职责链模式,这是一个比较简单的模式。跟往常一样,我们还是从一个真实世界的例子入手,这