用数组解决约瑟夫环问题

一、问题描述。

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

 二、代码实现

import java.util.Scanner;

public class Main {
	public static void main(String args[]) {
		Scanner in = new Scanner(System.in);
		System.out.print("请输入人数:");
		int N = in.nextInt();				//定义输入的人数
		int a[] = new int[N];				//数组a代表存人的编号
		int b[] = new int[N-2];				//数组b用来存取自杀人的编号,比数组a少两位
		for(int i = 1; i <= N;i++) {		//格式化数组
			a[i-1] = i;
		}
		
		int k = 0;							//记录b数组编号,把a数组自杀的人的编号存到b数组中
		int r = 0;							//用来数数,数到3的人则自杀
		while(b[N-3]==0) {					//b数组本来为0,判断最后一个不为零时,,也就是自杀剩余2人时,跳出循环
			for(int i = 0;i < N;i++) {
				if(a[i]!=0) {				//a[i]不为0,则代表该编号的人还存活,数数加1
					r++;
				}
				if(r == 3) {				
					b[k] = a[i];			//当数到3,该人自杀,把编号存到b数组中
					a[i] = 0;				//并把a数组该人的编号设为0,代表该人已经自杀
					r = 0;
					k++;
				}
			}
		}
		
		for(int i = 0; i < N-2;i++) {
			System.out.println("自杀的人编号:"+b[i]);
		}
		
		for(int i = 0; i < N;i++) {
			if(a[i]!=0) {
				System.out.println("最后存活的人的编号:"+a[i]);
			}
		}
		
	}

}

三、运行结果

请输入人数:41
自杀的人编号:3
自杀的人编号:6
自杀的人编号:9
自杀的人编号:12
自杀的人编号:15
自杀的人编号:18
自杀的人编号:21
自杀的人编号:24
自杀的人编号:27
自杀的人编号:30
自杀的人编号:33
自杀的人编号:36
自杀的人编号:39
自杀的人编号:1
自杀的人编号:5
自杀的人编号:10
自杀的人编号:14
自杀的人编号:19
自杀的人编号:23
自杀的人编号:28
自杀的人编号:32
自杀的人编号:37
自杀的人编号:41
自杀的人编号:7
自杀的人编号:13
自杀的人编号:20
自杀的人编号:26
自杀的人编号:34
自杀的人编号:40
自杀的人编号:8
自杀的人编号:17
自杀的人编号:29
自杀的人编号:38
自杀的人编号:11
自杀的人编号:25
自杀的人编号:2
自杀的人编号:22
自杀的人编号:4
自杀的人编号:35
最后存活的人的编号:16
最后存活的人的编号:31

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值