约瑟夫环问题起源于一个犹太故事。约瑟夫环问题的大意如下:
罗马人攻占了桥塔波特,41人藏在一个山洞中躲过了这场浩劫。这41个人中,包括历史学家Josephus(约瑟夫)和他的一个朋友。剩余的39个人为了表示不向罗马人屈服,决定集体自杀。大家决定了一个自杀方案,所有者41个人围成一个圆圈,由第1个人开始顺时针报数,每报数为3的人就立刻自杀,然后再由下一个人重新开始报数,仍然是每报数为3的人就立刻自杀,。。。。。。,直到所有人都自杀身亡为止。
约瑟夫和他的朋友并不想自杀,于是约瑟夫想到了一个计划,他们两个同样参与到自杀方案中,但是最后却躲过了自杀。请问,他们是怎么做到的?
[size=medium][i][color=red][b]简单约瑟夫环算法[/b][/color][/i][/size]
我们先来分析一个约瑟夫环问题。其实,约瑟夫和他的朋友只要在一直报1或者2的位置即可,最后剩下3个人时,另一个人报3自杀后,剩下约瑟夫和他的朋友,即可不遵循自杀方案躲过自杀。
我们可以用数组来模拟环,数组的值为每个人的位置,用一个数作为标记,来模拟数1,2,3的过程,当标记为3时,对应位置的数组值赋值为0,表示这个人已经自杀。此时将标记赋值为0,没经过一个人,标记值加1,重复这个过程,当到达数组末尾后,从数组头继续。直到自杀了39个人位置,最后剩下的两个位置即为约瑟夫和其朋友的位置。
下面这部分是我的代码:
罗马人攻占了桥塔波特,41人藏在一个山洞中躲过了这场浩劫。这41个人中,包括历史学家Josephus(约瑟夫)和他的一个朋友。剩余的39个人为了表示不向罗马人屈服,决定集体自杀。大家决定了一个自杀方案,所有者41个人围成一个圆圈,由第1个人开始顺时针报数,每报数为3的人就立刻自杀,然后再由下一个人重新开始报数,仍然是每报数为3的人就立刻自杀,。。。。。。,直到所有人都自杀身亡为止。
约瑟夫和他的朋友并不想自杀,于是约瑟夫想到了一个计划,他们两个同样参与到自杀方案中,但是最后却躲过了自杀。请问,他们是怎么做到的?
[size=medium][i][color=red][b]简单约瑟夫环算法[/b][/color][/i][/size]
我们先来分析一个约瑟夫环问题。其实,约瑟夫和他的朋友只要在一直报1或者2的位置即可,最后剩下3个人时,另一个人报3自杀后,剩下约瑟夫和他的朋友,即可不遵循自杀方案躲过自杀。
我们可以用数组来模拟环,数组的值为每个人的位置,用一个数作为标记,来模拟数1,2,3的过程,当标记为3时,对应位置的数组值赋值为0,表示这个人已经自杀。此时将标记赋值为0,没经过一个人,标记值加1,重复这个过程,当到达数组末尾后,从数组头继续。直到自杀了39个人位置,最后剩下的两个位置即为约瑟夫和其朋友的位置。
下面这部分是我的代码:
import java.util.Scanner;
public class JosephusProblem {
public static void main(String[] args) {
int sum=0;//自杀人的个数
int n,killMan;
boolean num=true;
//int flags = 0;
int flag = 0;
System.out.print("请输入约瑟夫环问题中的人数:");
Scanner input = new Scanner(System.in);
n = input.nextInt();//总人数
System.out.print("请输入自杀者的报数:");
killMan = input.nextInt();
int[] a = new int[n];
for(int i = 0; i < n;i++)
{
a[i]=i+1;
}
while(num)
{
int j;
for(j = 0;j<n;j++)
{
if(a[j]>0)
{
flag+=1;
if((flag%3)==0)//数到3的人
{
sum+=1;//统计自杀的人数
a[j]=0;//将自杀位置的人的值赋值为0,表明该人已不存在
System.out.println("第"+(j+1)+"位置的人会自杀!");
flag=0;//清零,方便下一个人从新计数
}
if((n-sum)<killMan)//输出没有自杀的人的位置
{
for(int k=0;k<n;k++)
{
if(a[k]>0)
{
System.out.println("第"+(k+1)+"位置的人不会自杀!");
}
}
num=false;//用于判断是否退出循环
break;
}
}
}
j=0;
}
}
}