野外生存问题处理系统

二战后的某一天,N个日本人来到了一个山洞休息,为了派出一
个日本人去外面充满危险的丛林中采摘食物,他们设置如下游戏产生
外出采摘的人:
1、首先,所有参加游戏的日本人按顺序编号为1、2、3…N;
2、接下来每个日本人心里产生一个数字,这个数字称为序号为 N
的人的密码P;
3、所有参加游戏的人按照编号站成一个圈,长老为游戏设置初
始密码K,从编号为1的人开始报数,报到K的人退出队伍,然后将自
己心中的密码P说出来,由下一个人继续从1开始报数,报到P的人退
出队伍,以此类推;
4、当队伍中剩下一个人的时候,这个人就是今天要出去采摘的
日本人,他可能回不来了!
请各位同学设计程序并使用Java语言实现该程序,在用户输入了
人数N、每个人的密码P和初始密码K的情况下,自动完成上面的选择
过程,输出先后离开队伍的人的序号序列,最后输出要去采摘的日本
人,输出他的编号。如采用图形化形式表示整个游戏过程,本次试验
额外加分。
源码:

import java.util.*;
import javax.swing.*;

public class live {
	public static void main(String[] args) {
		int N = 0,k = 0;
		
		Scanner in = new Scanner(System.in);
		
		N = Integer.parseInt(JOptionPane.showInputDialog(null, "please input the number of people N:"));
		k = Integer.parseInt(JOptionPane.showInputDialog(null, "please input the original password k:"));
		
		//这里定义了三个链表,一个存放所有的密码,一个存放出列的顺序,一个存放人的下标值
		LinkedList<Integer> allKeys = new LinkedList<>();
		LinkedList<Integer> order = new LinkedList<>();
		LinkedList<Integer> indexList = new LinkedList<>();


		for(int i = 1;i <= N;i++){
			allKeys.add(Integer.parseInt(JOptionPane.showInputDialog(null, "please input the " + i + " key")));
			indexList.add(i);
		}
//		LinkedList<Integer> allKeysCopy = new LinkedList<>(allKeys);//这里没用clone的原因是LinkedList的clone()方法是浅克隆,在之后的remove会存在问题

//		System.out.println(allKeysCopy.toString());
//		System.out.println(indexList.toString());
		int outN;//考虑出队后从出队的人的下一个人开始数,放大outN的作用域
		while(N>1){
			outN=0;
			outN=(k+outN-1)%N;//计算出队的人在链表中的下标
			if(outN==0){
				outN=N;
			}

			k = allKeys.get(outN-1);//得到出队人的密码
			order.add(indexList.get(outN-1));
			indexList.remove(outN-1);
			allKeys.remove(outN-1);
			N--;
		}
//		System.out.println(allKeys.toString());
//		System.out.println(order.toString());
//		System.out.println(indexList.toString());
//		System.out.println((indexList.indexOf(allKeys.get(0))+1));
//		JOptionPane.showMessageDialog(null,"The last people is num "+(allKeysCopy.indexOf(allKeys.get(0))+1));//LinkedList的下标从0开始
		JOptionPane.showMessageDialog(null,"The last people is num "+(indexList.getFirst()));
		JOptionPane.showMessageDialog(null,"The dequeue order is "+order.toString());

		in.close();
		}
}

部分解释:
//这里定义了三个链表,一个存放所有的密码,一个存放出列的顺序,一个存放人的下标值

		LinkedList<Integer> order = new LinkedList<>();
		LinkedList<Integer> indexList = new LinkedList<>();

//通过求模运算计算出出队人的下标,将下标存储在order表中,得到出对人的密码来进行下一轮的出队。

int outN;//考虑出队后从出队的人的下一个人开始数,放大outN的作用域
while(N>1){
		outN=0;
		outN=(k+outN-1)%N;//计算出队的人在链表中的下标
		if(outN==0){
			outN=N;
		}

		k = allKeys.get(outN-1);//得到出队人的密码
		order.add(indexList.get(outN-1));
		indexList.remove(outN-1);//在indexList和allKeys中同时删除出队的人,要不然结果会出现重复
		allKeys.remove(outN-1);
		N--;
	}
	```
	该实验是一个约瑟夫环问题
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liu'1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值