2025年有10人围成圈数数,每次数到3的人退出其他人继续,问最后剩下的一个人原来的位置是多少

有10人围成圈数数,每次数到3的人退出其他人继续,问最后剩下的一个人原来的位置是多少原文 http blog csdn net article details 这个问题是一个典型的约瑟夫环问题 对于这类题目我做了一些总结 下面我就分别用 数组 ArrayList LinkedList 以及通项公式去解决 首先用数组 把人都按顺序放到数组中

大家好,我是讯享网,很高兴认识大家。

原文:http://blog.csdn.net/_/article/details/

public class Test01 { public static void main(String[] args) { int n = 10;//参与游戏的人数 //将数字放入数组 int [] persons=new int[n]; for(int i=1;i<persons.length;i++){ persons[i-1]=i; } int saveCount=0;//目前数组中还存在的人数 int index=0;//我们要进行报的数 while(true){ //移除人出局 saveCount=0;//记录目前存活的人数每次循环都被初始化 for(int i= 0;i<persons.length;i++){ if(persons[i]!=-1){ index++; if(index==3){ index=0; //当计数器等于3的时候改变计数器的值并且把当前人的值改为-1 persons[i]=-1; } } //如果数组中的值不为-1存活人数+1 if(persons[i]!=-1){ saveCount++; } } //如果存活的人只剩下一个,退出循环 if(saveCount==1){ break; } } System.out.println(Arrays.toString(persons)); } }  
 
   
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

讯享网
讯享网public class Test02 { public static void main(String[] args) { //这里我用了字母初始化数组,为了更明显的表示 List<String> list = new ArrayList<String>(); for(char i = 'A'; i <= 'A' + 9; i++){ list.add(Character.toString(i)); } int n = 1;//计数器,因为每次都要移除一个人,所以n = 1 while(list.size() > 1){ for(int i = 0; i < list.size(); i++){ if(n == 3){ list.set(i, "");//找到叫到三的人把它的值变为空 n = 1; }else{ n++; } } for(int i = list.size() - 1; i >= 0; i--){ //每次循环完成之后,统一移除元素,不然会报错 if(list.get(i).length() == 0){ list.remove(i); } } } System.out.println(list.toString()); } } 
 
   
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
public class Test03 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); for(char i = 'A'; i < 'A' + 10; i++){ list.add(Character.toString(i)); } /* * 思路: * 1、得到每一次队列中,最后一个人应该报数的值:int n = list.size % 3 * 2、每次找到元素移除后,把计数器的值+1,等于跳过一个人,因为找到人是叫到3的人退出,所以刚移除过的人旁边的人肯定不会移除 */ int a = 0; System.out.println(list.toString()); while(list.size() > 1){ for(int i = 0; i < list.size(); i++){ a++;//2 if(a == 3){ if(i == list.size() - 1){ a = 0; }else{ a = 1; } list.remove(i); } } System.out.println(list.toString()); } } } 
 
   
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29


讯享网

讯享网public class Monkey { public static void main(String[] args) { int number = 0;//计数器 int count = 10;//玩家的总数 LinkedList<Integer> monkeys = new LinkedList<>(); for(int i = 1; i <= count; i++){ monkeys.add(i); } //这里用了迭代器,每次取出数组中的下个元素 Iterator<Integer> it = monkeys.iterator(); while(count > 1){ //每次进行迭代,如果有下个元素,计数器+1 if(it.hasNext()){ it.next(); ++number; }else{ //如果没有下个元素,迭代器从新赋值,即从头开始 it = monkeys.iterator(); } //如果找到元素,把计数器归零,移除元素,总数-1 if(number == 3){ number = 0; it.remove(); count--; } } System.out.println("编号为:" + monkeys.element()); } } 
 
   
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

LinkedList与ArrayList方法类似,都是找到元素并且移除,都是计数器进行计数每次记录循环结果,当做下次循环开始的计数。

最后介绍一种比较难理解的方法,一种通项公式,因为这是约瑟夫环问题,如果我门改变人数,多往下写,就会找到规律,用高中学到的求解通项公式的方法,可以找到这道题的通项公式 : f(n) = (f(n-1) + k) % n f(1) = 0; 
n代表人数,k代表叫到的数字(本题中:n = 10, k = 3); 
实现代码如下:

public class Test04 { public static void main(String[] args){ Scanner sc = new Scanner(System.in); System.out.println("请输入参与游戏的人数:"); int number = sc.nextInt(); System.out.println("请输入数到几的人退出游戏"); int k = sc.nextInt(); //通项公式 f(n) = (f(n-1) + k) % n int last = 0; // f(1) = 0 for(int i = k-1; i <= number; ++i){ last = (last + k) % i; } System.out.println(last + 1); } } 
 
   
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

使用通项公式很简洁的就解决了此类问题,看起来也简单,但是这一种方法却是最难理解的,因为我们需要自己去找通项公式。当然如果你的脑容量够大,你也可以记下来。

小讯
上一篇 2025-01-07 12:25
下一篇 2025-04-07 12:28

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/12600.html