约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后 [1] 结果+1即为原问题的解。
现在把约瑟夫环理解成另一个问题
现有一个国王,将8个人围在一个圆桌上,现在从第一个人开始报数,每一次报数若是3的倍数则抽取出来执行死刑,直到最后一个人,最后一个人将获得赦免。现在需要计算最后一个人是第几号人。
第一轮:3号6号被拖出去执行死刑
第二轮:1号4号被拖出去执行死刑
第三轮:5号8号被拖出去执行死刑
第四轮:2号被拖出去执行死刑
最后一轮只剩下7号
现在就需要这个计算过程
@author:肖佳嘉
@Date: May 1 ,2019
package File_Statistics;
import java.util.ArrayList;
public class File06_joseph {
//经典算法————约瑟夫环
public static void main (String [] arg0) {
System.out.println(GetLuckNum(8));
}
public static int GetLuckNum(int num) {
//定义一个数组
ArrayList<Integer> arraylist = new ArrayList<>();
//定义一个i,i类似于指针不断的对环进行指向
int i ;
//将1-10 添加到集合中去
for( i=1 ; i <=num; i++) {
arraylist.add(i);
}
//定义一个计数count,计算指针i指向的次数
int count = 1;
//对count进行循环
for(i = 0; arraylist.size() != 1 ; i++) {
if(i == arraylist.size()) {
i = 0;
}
if(count %3 == 0){
//每删除一次,后面的数都要往前面挪,这时候指针i不能再往前挪而要保留在原地,所以用i--
arraylist.remove(i--);
}
count++;
}
return arraylist.get(0);
}
}
测试结果:
7