约瑟夫环问题

问题:有N个人围成一圈,顺序排号。从第一个人开始报数(从1~~3报数),凡报到3的退出圈子,问最后留下的人原来是排在第几号?

请编程实现之。

思路:
(1)用一个循环队列array(用数组或者链表模拟循环队列都可)去存放这个n个人组成的圈子.
(2)然后依次开始报数,用变量currentCallNum表示当前报数(根据题意,从1开始),用index表示数组里面每个元素的下标(下标从0开始)
(3)当有人需要出圈的时候,就把array[index%n]置为-1,然后整个队列的长度len减1
(4)最后当队列长度为1时,遍历这个队列,返回值不为1的位置即可.

代码(Java)实现如下:

public class Joseph1 {

    public static void main(String[] args) {
         System.out.println("最后留下的人原来排在:" + pickup(11, 3) + "号!");
    }

    public static int pickup(int n, int m) {
        // 用数组去模拟这个循环队列
        int[] array = new int[n];
        for (int i = 0; i < n; i++) {
            array[i] = i + 1;
        }

        int len = n;
        // currentCallNum表示当前报数(根据题意,从1开始)
        int currentCallNum = 1;

        // 用index表示数组里面每个元素的下标(下标从0开始)
        int index = 0;

        while (len != 1) {
            // 判断该位置是否有人
            if (array[index % n] != -1) {

                // 判断该位置上的人是否应该出圈
                if (currentCallNum % m == 0) {
                  // 把array[index%n]置为-1,然后整个队列的长度len减1
                    array[index % n] = -1;
                  len--;

                }
                // 位置上有人,才报数,没有人则不需要报
                currentCallNum++;
            }

            index++;

        }
        int lastPersonPos = 0;
        
        // 最后当队列长度为1时,遍历这个队列,返回值不为1的位置即可.
        for (int i = 0; i < array.length; i++) {
            if (array[i] != -1) {
                lastPersonPos = array[i];
            }
        }
        return lastPersonPos;

    }

}

posted @ 2009-12-07 13:56  Chris Wang  阅读(289)  评论(0)    收藏  举报