约瑟夫问题是个著名的题目,它来自于一个历史故事:
古罗马的史学家约瑟夫(Josephus),他参加并记录了公元66—70年犹太人反抗罗马的起义。约瑟夫和犹太叛军战士们,设法守住了裘达伯特城达47天之久。在城市沦陷之后,他和40名犹太叛军的将士们在附近的一个洞穴中避难。在那里,这些叛乱者表决说“要投降毋宁死”,决定在罗马人俘虏他们之前自杀。方法是他们站成一个圈,从一开始,依次杀掉编号是三的倍数的人,直到一个人也不剩。
据传说,Josephus具有非凡的数学天赋,他快速的计算出他和他的朋友应该站的位置,这两个位置也就是最后剩下的两个人。他设法说服了他的朋友,两人幸存了下来,当然这也正是Josephus能够记录下来这段历史的前提。下图演示了一个简化的情况。
==>
本题要求你简单模拟这个过程:N个人排成一圈,从第一个人报数,凡是数到M的人就走出队列(出局),然后继续报数,请按照顺序输出出局的人的编号。
输入:
N M
输出:
对应的出局顺序(输出占一行,两个编号间用一个空格隔开。最后的编号后面没有空格,但要有换行,否则可能无法验证通过。)
样例输入:
7□3↵
样例输出:
3□6□2□7□5□1□4↵
___________________________________________________________________________________________________________
解答:
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++;
}
}
}
}