Josephus问题求解:
设有n个人围坐一个圆桌周围,,现从第S人开始报数,数到第m的人出列,
然后从出列的下一个重新开始报数,数列的第m个人又出列……如此重复,直
到所有的人全部出列为止。对任意给定的n、s、m,求按出列次序得到的n个
人员的顺序表。
分析:对于n个人,每一次出列一个人,余下的n-1个人仍然是一个Josephus问题,因此可以使用递归的方式,每次出列一个人,直到余下最后一个人。
public class Josephus {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
boolean[] nodes=new boolean[10];
for(int i=0; i<nodes.length; i++){
nodes[i]=false;
}
System.out.println("the left is "+ josephus(nodes,7,0,nodes.length));
}
public static int josephus(boolean[] nodes,int k, int start, int left){
if(left==1){ //剩下最后一个人,找到这个人的坐标返回
start=ignore(nodes,start);
return ++start;
}
int i=1; //从start开始计数,过滤掉出列的人,直到数到k-1
while(i<k){
if(nodes[start]==false){
i++;
}
start++;
if(start==nodes.length) start=0;
}
start=ignore(nodes, start);
nodes[start]=true; //找到数到k的人,出列
left--; //总人数减少
System.out.println("nodes is deleted,pos:"+(start+1));
return josephus(nodes,k,(++start)%nodes.length,left); //重新开始下一轮
}
private static int ignore(boolean[] nodes,int start){
while(nodes[start]) {
start++;
if(start==nodes.length) start=0;
}
return start;
}
}
运行结果:
nodes is deleted,pos:7
nodes is deleted,pos:4
nodes is deleted,pos:2
nodes is deleted,pos:1
nodes is deleted,pos:3
nodes is deleted,pos:6
nodes is deleted,pos:10
nodes is deleted,pos:5
nodes is deleted,pos:8
the left is 9