Algorithm 约瑟夫环问题

import edu.whu.cs.typedef.MyQueue;
public class 约瑟夫环 {
    /** 报数问题
     * @number需要报数的数目 
     * @kids需要报数的人数
     * **/
    public static int countNumber0(int number,int  kids){
        MyQueue queue = new MyQueue();
        int count = 0;
        for(int i=1;i<=kids;i++) queue.push(i);
        while(queue.size() != 1){
            int e = queue.pop(); count ++;
            if(count == number) count = 0;
            else queue.push(e);
        }
        return queue.pop();
    }
    
    
    /**递推关系
     *           f[1]=0;     令f[i]表示i个人玩游戏报m退出最后胜利者的编号
     *                     第一轮报号k的人出局之后将k+1号从0号开始编号
              f[i] = (f[i-1]+m)%i;
     * @param m是总数量 ;n是数到出队的数
     */
    public static int countNumber1(int m,int n){
        if(n == 1) return n;
        int s = 0;
        for(int i = 2; i <= n; i++) {
            s = (s + m) % i;
        }
        return  (s+1);
    }
    
    public static int countNumber2(int m,int n){
        int i = 0,p = 0;
        while(++i <= n){
            p = i*m;
            while(p>n)
                p = p - n + (p-n-1)/(m-1);
        }
        return p;
    }
    
    public static void main(String[] args) {
        int number = 11, kids = 101;
        int k0 = 约瑟夫环.countNumber0(number, kids);
        int k1 = 约瑟夫环.countNumber1(number, kids);
        int k2 = 约瑟夫环.countNumber2(number, kids);
        System.out.println(k0 + ":" + k1 + ":" + k2);
    }
}

 

posted @ 2015-10-07 10:40  √珞珈搬砖工√  阅读(89)  评论(0)    收藏  举报