您的位置:首页 > 编程语言

约瑟夫环代码展示,以及理解约瑟夫环

2020-05-11 04:09 701 查看

本人也是刚刚接触算法,如果有不准确的地方,欢迎大家留言评论,一起学习,一起进步,奥利给!

约瑟夫环的简单的图例(画的太抽象,大家理解下,我有必要去学学画画了!)

约瑟夫环的原理

1、一群人围在一起坐成环状(如:N)

2、从某个编号开始报数(如:K)

3、数到某个数(如:M)的时候,此人出列,

4、一直循环,直到所有人出列

不够清晰的话,可以看我上边优秀的画图,一群人N指的就是11,摸个编号开始报数K指的就是数字1(但是记住,他的下标是0哦~~~~~~~~),第一次数到某个数指的就是3,第二次数到某个数指的是6,以此类推哦----------,一直循环,直到所有的人都出列指的是N变为0,就是没人了,出列也就出完了。

简单的约瑟夫环问题(1)

已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1(指的是下标),最后 结果+1(因为我们找的是下标对应的这个数,所以要加 1 哦)即为原问题的解。

代码分析

[code]import java.util.Scanner;

public class 约瑟夫环 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt()
int k = sc.nextInt();
int p = 0;
for (int i = 2; i <= n; i++) {
p = (p + k) % i;
}
System.out.println(p + 1);
}
}

约瑟夫环最经典的问题(2)

       据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。

看完这道题我的第一反应居然不是去解题,而是感慨,那个人真是编程天才,机智的一批,更想说的是不要仅仅指望知识来吃饭,关键时刻,知识能救命的呀!

题目分析

把这道题上相应的数字带入到上面约瑟夫环的原理的分析中。

代码分析,代码学习的位置、https://blog.csdn.net/weixin_43570367/article/details/105896737?utm_source=app

[code]package 约瑟夫环问题;

import java.util.Scanner;

public class 约瑟夫环问题 {

public static void main(String [] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();

if(n<2) {
System.out.println("请您输入大于二的数字:");
return ;
}
//构建链表并获取头结点,把头节点赋值给currentNode
Node currentNode = buildData(n);
//用来计数
int count =0;
//循环链表当前节点的上一个节点
Node beforeNode = null;
//循环遍历列表
while(currentNode!= currentNode.next) {
count++;
if(count == 3) {
//向后移动节点
beforeNode.next = currentNode.next;
System.out.println("出环的标号是:"+ currentNode.data);
count = 0;
currentNode = currentNode.next;
}else
{
//向后移动节点
beforeNode = currentNode;
currentNode = currentNode.next;
}
//表示只有两个节点了,不在进行出环操作

if(beforeNode.data == currentNode.next.data) {

break;
}
}

System.out.println("最后留在环中的标号是:"+currentNode.data+ ","+ currentNode.next.data);
}

/*
* 构建单项循环链表
* @param  n 人数
*
* @return返回头节点
* */

private static Node buildData(int n) {
//循环链表的头节点
Node head = null;
//循环链表当前节点的前一个节点
Node prev  = null;

for(int i=1; i<=n ; i++) {
Node newNode = new Node(i);
//如果是第一个节点
if(i == 1) {
head = newNode;
prev = head;
//跳出当前循环,进行下一次循环
continue;
}
//如果不是第一个节点
prev.next = newNode;
prev = newNode;
//如果是最后的一个节点
if(i == n) {
prev.next = head;
}

}
return head;
}

}
class Node{
//当前存储的数据
int data;
Node next;
//当前节点的下一个节点

public Node(int data) {
this.data = data;
}
}

小剧场:几日不见,甚是想念啊

 

看-清 原创文章 27获赞 1访问量 821 关注 私信
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: