假设有m个小孩围成一圈,从1开始依次报数,每报到n时,这个小孩就出列,
下个小孩重新从1开始报数,直到n时出列,以此类推,请输出小孩出列的顺序。
这个问题叫做约瑟夫环问题
参考
http://www.cnblogs.com/timeng/p/3335162.html
http://www.cnblogs.com/lan0725/archive/2009/02/28/1873876.html
约瑟夫环问题,可以考虑用循环链队实现
我直接贴我自己写的代码吧,用递归实现的,我写了注释,这里就不多说了:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
new Main().doIt();
}
private class Child {
int index;
}
private int n;
private List<Child> childList;
private void doIt() {
System.out.println("请输入小孩的总数:");
Scanner scanner = new Scanner(System.in);
int m = Integer.valueOf(scanner.nextLine());
System.out.println("请输入出列序号:");
n = Integer.valueOf(scanner.nextLine());
scanner.close();
childList = new ArrayList<>();
//按编号1~N生成小孩
for (int i = 0; i < m; i++) {
Child child = new Child();
child.index = (i + 1);
childList.add(child);
}
joseph(0);
}
private void joseph(int index) {
if (childList.size() > 0) {
//执行一轮完整的报数,以任意一个小孩报数到指定数字为结束
//得到出列的小孩对象的数组下标
int outIndex = announce(1, index);
//计算一个小孩出列之后,下一轮报数开始的小孩的数组下标
int nextStartIndex = (outIndex == childList.size() - 1) ? 0 : outIndex;
//从圆圈(组)中剔除出列的小孩,并报出此小孩原本的顺序号
Child child = childList.get(outIndex);
System.out.print(child.index + "\t");
childList.remove(child);
//执行下一轮报数
joseph(nextStartIndex);
}
}
private int announce(int announce, int index) {
if (announce == n) {
return index;
} else {
return announce(announce + 1, (index < childList.size() - 1) ? index + 1 : 0);
}
}
}
这个是编程算法的经典题目,你可以直接搜索约瑟夫环。
经典的约瑟夫环问题,可以用一个数组来模拟环,通过对下标取模的方式构成环,然后按照题目的描述进行模拟即可