`

约瑟夫环问题

阅读更多
约瑟夫环问题起源于一个犹太故事。约瑟夫环问题的大意如下:
   
    罗马人攻占了桥塔波特,41人藏在一个山洞中躲过了这场浩劫。这41个人中,包括历史学家Josephus(约瑟夫)和他的一个朋友。剩余的39个人为了表示不向罗马人屈服,决定集体自杀。大家决定了一个自杀方案,所有者41个人围成一个圆圈,由第1个人开始顺时针报数,每报数为3的人就立刻自杀,然后再由下一个人重新开始报数,仍然是每报数为3的人就立刻自杀,。。。。。。,直到所有人都自杀身亡为止。
    约瑟夫和他的朋友并不想自杀,于是约瑟夫想到了一个计划,他们两个同样参与到自杀方案中,但是最后却躲过了自杀。请问,他们是怎么做到的?

简单约瑟夫环算法

    我们先来分析一个约瑟夫环问题。其实,约瑟夫和他的朋友只要在一直报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;
		}
	}

}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics