约瑟夫环

问题:输入一个数n,代表有n个人,现在从第一个开始报数,第M个将被杀掉,问M为何值会使最后留下第二个人

输入一组n,以0结束输入

Sample Input

3
4
5
6
7
8
9
10
11
12
0

Sample Output

2
5
2
4
3
11
2
3
8
16

这是一个约瑟夫环问题,约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3,1。

代码如下:

import java.util.*;
import java.io.*;
public class Main {
	public static void main(String[] args){
		Scanner scan=new Scanner(System.in);
		while(scan.hasNext()){
			int m=1;
			int n=scan.nextInt();
			if(n==0)break;
			while(ysf(m,n)!=1){
				m++;
			}
			System.out.println(m);
		}
	}
	
	public static int ysf(int m,int n){
		int f=0;
		for(int i=2;i

 解释:

假设有8人,M=3,每次杀掉一个人后重新排序,下划线表示每次将要被杀掉的人,则有

1  2  3  4  5  6  7  8

2  3  4  5  6  7  8

5  6  7  8  2  3

8  2  3  5  6

5  6  8  2

2  5  6 

2  5

由下向上,最后剩下的人在最后一行的的下标为 0,如果我们知道在 最后一个人在上一行的坐标,然后再重复以上 步骤不就可以 知道最后一人 在第一行的坐标了吗,知道坐标后,因为人的 排列是1到 n的 有序序列,所以 就可以知道最后剩下的那个人是谁了。 问题是,如何求最后一个人在上一行的坐标呢? 很简单,公式 就是f=(f+M)%i  。f是现在的 下标,i是上一行的长度。因为要求 2 号留到最后,所以如果最后留下的人在第二行是第一个人,也就是f==0,那么最后留下的就是 2 号,ysf函数就返回1。

大牛解法:https://blog.csdn.net/ZhengKarl/article/details/5596118

你可能感兴趣的:(约瑟夫环)