j a v a的简单 编 程 计 算 问题

假设有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);
        }
    }
}

这个是编程算法的经典题目,你可以直接搜索约瑟夫环。

经典的约瑟夫环问题,可以用一个数组来模拟环,通过对下标取模的方式构成环,然后按照题目的描述进行模拟即可