Josephus问题
来源:互联网 发布:淘宝怎样发布二手宝贝? 编辑:程序博客网 时间:2024/06/05 07:36
Josephus问题: N个人编号从1到N ,围坐成一个圆圈。从一号开始传递一个土豆,经过M次传递后拿着土豆的人被清除离座,围坐的圆缩紧,由坐在被清除的人的后面的人拿起土豆继续进行游戏,最后剩下的人获胜。如:M=1 N=5 被清除的人的顺序为2,4,1,5。
方法一:按照题目提示,问题处理关键为循环数组,关键在处理下标。
源代码如下:
public class PT36 {
public static void main(String args[]){
/*
* 初始化各类参量
*/
int n = 5, m =1, from = 0;
List<Integer> list = new ArrayList<Integer>();
for(int i= 0 ; i < n ; i++){
list.add(i+1);
}
System.out.print(list);
/*
* 游戏开始
*/
while(list.size() != 1){
if((from+m) <list.size()) /* 判断标识和移动之后的标识是否越界*/
from = from+m;
else{
int temp = list.size() - from;
from =m-temp;
if(from >= list.size()){
do{
from = from-list.size();
}while(from >= list.size());
} /* 下标越界操作,在数组越来越小时要使用循环才可以保证下标移入到数组内部 */
}
System.out.print(list.get(from));
list.remove(from);
if(from == list.size())
from = 0; /*打印被弹出的数组,同时做判断是有在删除数字之后,下标越界*/
}
System.out.print(list);
}
}
上述方法的while可以用递归来表示,但会额外增加存储空间,不建议使用。
方法二:将一个循环数组改变为不断加长的数组,例如[1,2,3,4,5] -> [1,3,4,5]->[1,3,5]->[1,3,5,1,3,5]->[3,5,3,5]->[3,3]->3
源代码如下:
public class PT36_2 {
public static void main(String args[]){
/*
* 完成初始化。
*/
int m = 3 , n =5 , index = 0 , pianyi = 0;
List<Integer> list = new ArrayList<Integer>();
for(int i=0;i<n;i++){
list.add(i+1);
}
System.out.print(list);
/*
* 定义空数组,用于数组增加
*/
List<Integer> templist = new ArrayList<Integer>();
templist.addAll(list);
/*
* 游戏开始
*/
while(!issimple(list)){
if(index + m < list.size()){
/*
* 确定标识位置,同时在删除之后根据拼接的次数完成标志偏移量的修改。
*/
index = index+m;
list=myremove(list, list.get(index));
if(index >= list.size()/(pianyi+1))
index= index - pianyi;
templist.clear();
templist.addAll(list);
System.out.print(list);
}else{
do{
/*
* 拼接数组,同时记录拼接次数
*/
list.addAll(templist);
pianyi ++;
}while(index + m >= list.size());
}
}
/*
* 显示最终获胜者
*/
System.out.println(list.get(0));
}
/*
* 由于数组拼接,可能导致同意元素多个,所以List提供的remove方法无法满足条件,自己写方法用于删除所有同类元素
*/
private static List<Integer> myremove(List<Integer> list , int x) {
List<Integer> templist1 = list;
for(int i=0; i<list.size();i++){
if(list.get(i) == x){
list.remove(i);
}
}
templist1 = list;
return templist1;
}
/*
* 判断目前的ArrayList是否只包含最后胜出的元素
*/
private static boolean issimple(List<Integer> list){
boolean issimple = true;
int example = list.get(0);
for(int i = 0 ; i<list.size();i++){
if(example != list.get(i)){
issimple = false;
break;
}
}
return issimple;
}
}
游戏分析与实现完成!
- Josephus问题
- Josephus问题
- Josephus问题
- Josephus问题
- josephus 问题
- Josephus问题
- Josephus问题
- josephus问题
- Josephus问题
- Josephus问题
- Josephus问题
- Josephus问题
- Josephus问题
- Josephus问题
- Josephus问题
- Josephus问题
- Josephus问题
- Josephus问题
- 构建qt4.8.6嵌入式qt环境
- jQuery和CSS3商品图片预览轮播图插件
- P51 第4题 编写一个程序,判断用户输入的字符是否是数字,若是数字,则输出“a numerical character”,否则输出“other character”.
- CentOS 6.6下安装SQLite
- sea.js+grunt学习笔记
- Josephus问题
- Android开发架构设计之健壮且可读的安卓架构(下篇)
- 【CF】529B Group Photo 2 (online mirror version)
- 11种超酷CSS3复选框样式美化效果
- test命令
- Asterisk 13.2.0 current.tar.gz安装步骤详解
- Java堆栈介绍
- MySQL drop table操作风险
- 《python核心编程》序列类型小结2