约瑟夫环问题(100围坐一圈报数,报3出圈)

100个人编号1-100,围坐一圈,从1号开始进行1,2,3报数,谁报数为3,就离开圈子,剩下的人继续报1,2,3,报数为3的出圈。。。

请写一段程序,计算最后一个留下来的人,他的编号

 1 package com.ycl.test;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 public class Test1 {
 7     public static void main(String[] args) {
 8         int count = 0;
 9         List<Integer> list = new ArrayList<Integer>();
10         for (int i = 1; i <= 100; i++) {
11             list.add(i);
12         }
13         while (list.size() > 0) {
14             for (int i = 0,j = list.size();i<j; i++) {
15                 ++count;
16                 if(count==3){
17                     count=0;
18                     list.remove(i);
19                     --i;
20                     --j;
21                     continue;
22                 }
23             }
24             if(list.size()==1){
25                 System.out.println("Last Number:"+list.get(0));
26                 break;
27             }
28         }
29     }
30 }

 

转载于:https://www.cnblogs.com/BeautyInWholeLife/p/7465857.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 限m,从第一个人开始按顺时针方向自1开始顺序报数到m的人圈,直到剩下最后一个人为止。这个人就是的胜利者。解决问题的方法有很多,其中比较常用的是递归和数学公式法。递归法是通过递归函数模拟报数圈的过程,直到只剩下一个人为止。数学公式法则是通过数学公式计算最后一个圈的人的编号。无论采用哪种方法,都需要理解问题的本质和规律,才能得正确的解答。 ### 回答2: 问题是经典的数学问题,它的背景故事大家都比较熟知,就是n个人成一圈,依次报数到m的人圈,问最后剩下的人在原来序列中的编号是多少。这个问题在我们的生活中可能不常见,但在计算机领域中却是经常被用到的。 本文将介绍三种常见的解决问题的方法。 第一种方法是使用循链表。我们可以用一个循链表来模拟这个过程,每次找到要圈的人,然后删除节点。直到只剩下一个节点为止。使用循链表的优点是简单易懂,但是需要手写链表结构,增加了代码量。 第二种方法是使用递归。我们可以使用一个递归函数来模拟这个过程,首先定义f(n,m)为n个人报数,每m个人圈最后胜利者的编号。那么在这个过程中,每次圈的人都是(m-1)%n,这样我们就可以使用递归,逐步缩小n的范,最后得到结果。使用递归的优点是代码量少,但是由于递归的特点,当数据量大的时候,可能会导致栈溢。 第三种方法是使用数学公式。问题有一个非常简单的数学规律,每次圈的人可以表示为:(f(n-1,m)+m-1)%n+1,其中f(n-1,m)表示n-1个人时的所求编号,这个方法的优点是速度快,但是需要较高的数学能力。 这三种方法各有优缺点,可以根据具体问题的需求进行选择。总之,问题虽然表面上只是一个简单的数学问题,但是其中蕴含的思维逻辑和算法原理非常深刻,是值得我们在日常练习中多多涉猎和思考的。 ### 回答3: 当报数为k时,第一次报数为k的人从顺时针方向开始依次列,之后从他的下一个人重新开始报数,仍然是从k开始报数,直到所有人被排圈子。该问题的实现方式有多种,其中较为常见的是使用单向循链表实现。 对于n个人排成的队列,可以使用循链表的形式存储,每个节点存储一个人的编号和密码。为了方便计算,可以给每个人编号从0到n-1。同时,为了实现报数为k的轮换,可以使用一个计数器j表示当前报数的人的编号,每报数一次则将j加1,当j等于k时,表示该人要被列。具体实现可以利用模运算,即(j+k)%n表示要列的人的编号,将该人从链表中移除,直到只剩下最后一个人为止。 另外,该问题也可以使用递推公式求解。令f(n,k)表示n个人报数为k时最后剩下的人的编号,则有以下递推关系式: f(1,k) = 0 f(n,k) = (f(n-1,k) + k) % n 其中f(1,k)表示只有一个人时,其编号为0;f(n,k)表示n个人中报数为k的轮换中最后剩下的人的编号;(f(n-1,k) + k) % n表示在n-1个人中报数为k时的轮换中最后剩下的人的编号,再加上k得到n个人中报数为k时的轮换最后剩下的人的编号。 通过递推公式,可以较为快速地求解较大规模问题的解,避免使用链表等数据结构引发的空间复杂度过高的问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值