package com.bupt.syc; import java.util.Iterator; import java.util.LinkedList; import org.junit.Test; public class Josephus { // 模拟解法 public static int JosephusWinner(int M, int N) throws Exception { if (N < M) { throw new Exception("M should smaller than N"); } int arr[] = new int[N]; for (int i = 0; i < N; i++) { arr[i] = 1; } int cnt = 0, k = 0, j = 0; int num=-1; while(cnt<=N-1){ if(arr[k]==1){ j+=arr[k]; } if(j==M){ arr[k]=0; cnt++; } } return num; } //公式法 //f(1)=0 //f=(f+m)mod i (i>1) public static int JosephusWinner2(int M ,int N){ int winner=0; for(int i=2;i<=N;i++){ winner=(winner+M)%i; } return winner; } public static void JosephusWinner3(int M ,int N){ LinkedList <Integer> linkedList=new LinkedList<Integer>(); for(int i=0;i<N;i++){ linkedList.add(i); } int num=0; while(linkedList.size()>1){ Iterator iterator=linkedList.iterator(); while(iterator.hasNext()){ num++; iterator.next(); if(num==M){ iterator.remove(); num=0; } } } if(linkedList.size()==1){ System.out.println("winner is :"+linkedList.get(0)); } } //题目:有N个人围成一圈,每人有一个编号,从编号为1的人开始,每隔M个出圈,按出圈次序排成一列,其编号刚好按顺序从1到M。 //要求:从键盘输入M,N,编程计算并输出这N个人原来在圈中的位置。 public static void reverseJosephusWinner(int M,int N){ LinkedList <Integer> linkedList=new LinkedList<Integer>(); for(int i=0;i<N;i++){ linkedList.add(0); } int num=1; int cnt=0; int index=0; while(num<=N){ if(linkedList.get(index)==0){ cnt++; } if(cnt==M&&linkedList.get(index)==0){ linkedList.set(index, num); num++; cnt=0; for(int i=0;i<N;i++){ System.out.print(linkedList.get(i)+" "); } System.out.println(); } if(index+1>N-1) index=0; else index++; } } public static void main(String args[]) { JosephusWinner3(5,9); reverseJosephusWinner(5,9); } }