约瑟夫问题

来源:互联网 发布:sql语句的关键字 编辑:程序博客网 时间:2024/04/29 14:46

约瑟夫问题是个著名的题目,它来自于一个历史故事:

古罗马的史学家约瑟夫(Josephus),他参加并记录了公元66—70年犹太人反抗罗马的起义。约瑟夫和犹太叛军战士们,设法守住了裘达伯特城达47天之久。在城市沦陷之后,他和40名犹太叛军的将士们在附近的一个洞穴中避难。在那里,这些叛乱者表决说“要投降毋宁死”,决定在罗马人俘虏他们之前自杀。方法是他们站成一个圈,从一开始,依次杀掉编号是三的倍数的人,直到一个人也不剩。

据传说,Josephus具有非凡的数学天赋,他快速的计算出他和他的朋友应该站的位置,这两个位置也就是最后剩下的两个人。他设法说服了他的朋友,两人幸存了下来,当然这也正是Josephus能够记录下来这段历史的前提。下图演示了一个简化的情况。

initial state ==>  serval

本题要求你简单模拟这个过程:N个人排成一圈,从第一个人报数,凡是数到M的人就走出队列(出局),然后继续报数,请按照顺序输出出局的人的编号。

输入:

N M

输出:

对应的出局顺序(输出占一行,两个编号间用一个空格隔开。最后的编号后面没有空格,但要有换行,否则可能无法验证通过。)

 

样例输入:

73

样例输出:

3627514

___________________________________________________________________________________________________________

解答:

import java.util.Scanner;


public class Main41 {
            public static void main(String args[]) throws Exception {               
                Scanner cin=new Scanner(System.in);
                int N=cin.nextInt(), M=cin.nextInt();
                int[] array_N = new int[N];
                for(int i = 0; i < N; i++){
                array_N[i] = i + 1;
                }
                boolean[] found = new boolean[N];
                int count_all = N;
                int count_num = 1;
                while(count_all != 0){
                    for(int j = 0; j < N; j++){
                    if(found[j] == true)
                    continue;
                    if (count_num == M){
                    if(count_all == 1)
                            System.out.print(array_N[j] + "\n");
                    else
                    System.out.print(array_N[j] + " ");
                   
                    count_num = 0;
                    found[j] = true;
                    count_all--;
                    }
                    count_num++;
                    }
                }
            }
}

原创粉丝点击