约瑟夫环(队列解法)
队列操作:
每个人都报数一次:可以创建一个计数器,每当报数时计数器+1,(报到9的人就扔进大海),代表:计数器 % 9 ==
0,
/**
* 约瑟夫环:15个基督教徒和15个非教徒在海上遇险,必须将其中一半的人投入海中,其余的人才能幸免于难,
* 于是30个人围成一圈,从某一个人开始从1报数,报到9的人就扔进大海,他后面的人继续从1开始报数,重复上面的规则,直到剩下15个人为止。
* 结果由于上帝的保佑,15个基督教徒最后都幸免于难,问原来这些人是怎么排列的,哪些位置是基督教徒,哪些位置是非教徒。
* @author zengxin
*
*/
public class Pahe11约瑟夫环 {
@Test
public void ListTest() {
Queue<Integer> queue = new LinkedList<>();
int personNum = 30; //总人数
int liveNum = 15;//基督人数
int key = 9;//数的关键字
//初始化人参数
for(int i = 1;i<=personNum;i++){
queue.add(i);
}
List<Integer> flaseList = getFlase(queue, personNum, key, liveNum);
System.out.println();
Queue<Integer> trueQueue = getTrue(queue, flaseList);
//遍历出 基督成员
for(Integer i : trueQueue){
System.out.print("基:"+i+" ");
}
}
//获取非基督人员
private static List<Integer> getFlase(Queue<Integer> queue,int personNum,int key,int liveNum){
List<Integer> flaseList = new ArrayList<>();//非基督徒人员
int count =0;
while(queue.size()>liveNum){
//出队操作
int k = queue.poll();
//计数器
count++;
if(count % key == 0){
System.out.print("非:"+k+" ");
flaseList.add(k);
}else{
//当不满足时,继续入栈
queue.add(k);
}
}
return flaseList;
}
//移除非基督成员
private Queue<Integer> getTrue(Queue<Integer> queue,List<Integer> flaseList){
for(Integer i : flaseList){
queue.remove(i);
}
return queue;
}