美文网首页java学习之路Java 杂谈Java
:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数)

:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数)

作者: 唯有努力不欺人丶 | 来源:发表于2019-09-25 18:08 被阅读0次

首先,我最大的学习来源不是百度而是我群友~~在这里表白一波我热爱学习的群友们!
然后今天群里突然有人提出了题目的这个问题:

有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

冥思苦想半天(好吧我审完题就百度的),,然后查到了几种算法吧,但是我不知道是因为我只会java还是真的有的人的思路比较广泛,跳跃,所以看起来略复杂啊。
然后有仔细看了半天,稍微好一点勉强看懂了,但是我觉得还是不简单,而且是思维上的绕圈。
但是我还把我看过的感觉上挺全的(主要是内容很多)的链接在此粘一下,有兴趣的同学可以去看看:https://blog.csdn.net/weixin_38214171/article/details/80352921

然后继续说我又在网上找了找,果然找到一种我觉得很简单易懂而且很方便的解决方法,然后我又在其基础上做了解释说明,下面是解法:

package test;

import java.util.ArrayList;
import java.util.List;

/**
 *     约瑟夫环问题的解决
 * @author sijia
 *
 */
public class Demo1 {

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(0);
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
        list.add(7);
        list.add(8);
        list.add(9);
        list.add(10);
        list.add(11);
        list.add(12);
        list.add(13);
        list.add(14);
        list.add(15);
        list.add(16);
        
        
        //思路是遍历数组,隔两个删除一个元素,直到只剩下一个元素。如果到了数组末尾则跳转开头
        int i=0;
        while(list.size()!=1) {              
                //遍历到了最后一个元素,i+2是跳转到正数第二个元素
                if(i>=list.size()-1) {
                    i=-1;
                }
                //遍历到了倒数第二个元素,i+2是跳转到第一个元素
                if(i>=list.size()-2) {
                    i=-2;
                }
                //以上完成了数组据末尾跳转到数组开头
                
                i=i+2;
                /**
                   *    删除元素
                   *    这里不理解的可以做个带入。第一次删除0+2,也就是把下标为2的元素删除了。第二次继续,走到这里
                   * i=2+2变成了4.为什么这次删除下标为4的?因为之前把下标为2的删除后,后面的元素依次前移了。
                   *    原下标3的现在下标为2.同理,原下标为5的现在下标为4.
                   *    如此:3,4,后面原下标5现下标4的元素删除。符合了题目的逻辑。
                   * i每次都加2,是因为上一轮删除了一个元素,整个下标都前移了。所以才会+2代表隔了两个删除一个
                   *    同样大家可以考虑一下这道题的变换:比如题目变成隔5个删除一个,也就是报数1-6,数到6的出局要怎么写?
                 * 
                 */
                list.remove(i);
            
        }
        /**
         *   最后打印出来的就是剩下的那个元素,因为我这里取巧,将下标和元素的值对应了,所以我们不仅可以看出元素的值
         *   还可以看元素原来的下标。如果不这么做可以在一开始就复制一份list,然后用最后剩下来的值去反推,再不济还能不移除而是用别的方法标记出局。这样要改动的比较大
         *   这个 数值与数组list的总元素数,也就是题目中的N息息相关,我反正试了多次。
         */
        System.out.print(list.get(0));

    }

}

至此,问题解决,然后文中我留了两个问题:

1.这个人数n和排除的数m之间是有一定关联关系的,但是我这个数学渣有点没耐心一遍遍测试或者思考了,所以作为一个遗留问题吧。

2.我文中说的,这个方法是实现N个人数到3退出的代码。但是如果题目是N个人数到5退出呢?又该怎么写?反正我目前是有思路了,有意的可以私信我探讨哦

全文手打不易,如果稍微帮到你了,请点个喜欢点个关注支持一下~~~~~也祝大家工作顺顺利利!

相关文章

  • 算法笔记_06:蓝桥杯练习 筛选号码

    1. 问题描述 问题描述有n个人围成一圈,顺序排号(编号为1到n)。从第1个人开始报数(从1到3报数),凡报到3的...

  • 数 3 游戏 2

    题目 有 n 个人围成一圈,顺序排号。从第一个人开始报数(从 1 到 3 报数),凡报到 3 的人退出圈子,问最后...

  • 数 3 游戏 1

    题目 有 n 个人围成一圈,顺序排号。从第一个人开始报数(从 1 到 3 报数),凡报到 3 的人退出圈子,问最后...

  • 蓝桥杯算法训练-筛选号码问题(Java语言)

    描述 有n个人围成一圈,顺序排号(编号为1到n)。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子。从下一...

  • Rust语言编程实例100题-069

    Rust语言编程实例100题-069 题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到...

  • 【习题37】

    【程序37】题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下...

  • 3个月熟练使用python--Day2打卡

    1、约瑟夫环问题 问题:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最...

  • 7.29打卡

    题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几...

  • 题解:报数问题(C++描述)

    题目相关 题目描述 有n人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下...

  • 【Java编程基本功】(十一)求最大红玫瑰数,求最后剩下的人,根

    第三十四题 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原...

网友评论

    本文标题::有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数)

    本文链接:https://www.haomeiwen.com/subject/lmghyctx.html