约瑟夫问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个整数作为报数上限值m,从第一个人开始顺时针自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有的人全部出列为止。
试设计一个程序,求出出列值。
利用单向循环链表作为存储结构模拟此过程,按照出列顺序打印出各人的编号。
运行时间限制: 无限制
内存限制: 无限制
输入: 一串以空格间隔开的数字
第一个数字为环内人数 n < 10
第二个数字为初始密码 m < 10
后面的为每个人的密码值,密码值<10
输出: 出列顺序,以空格间隔开
样例输入: 6 3 6 5 4 3 2 1
样例输出: 3 1 4 2 5 6
大连理工 华为 2013
public void Josephus(){
List<String> list=new LinkedList<String>();//直接利用java中自带的LinkedList单链表
Scanner sc=new Scanner(System.in);
String[] inArr=sc.nextLine().split(" ");
int n=Integer.parseInt(inArr[0]);
int m=Integer.parseInt(inArr[1]);
String pwArr[]=new String[inArr.length-2];//密码卡
for(int i=0;i<pwArr.length;i++){
pwArr[i]=inArr[i+2];
}
for(int i=1;i<=n;i++){
String password=pwArr[i-1];
list.add(String.valueOf(i)+","+password);//密码卡绑定到人员身上
}
StringBuilder sb=new StringBuilder();
int i=0;
while(list.size()>1){
i=(i+m-1)%list.size();
String[] delete=list.get(i).split(",");
m=Integer.valueOf(delete[1]);
sb.append(delete[0]+" ");
list.remove(i);
}
sb.append(list.get(0).split(",")[0]);
System.out.println(sb);
}