约瑟夫环问题:一群人围成一个圈,开始报数,第三个死,下一个从1开始,问第几位最后不死

本文深入探讨了约瑟夫环问题,这是一个经典的数学应用问题。通过详细的算法分析和Java代码实现,展示了如何解决n个人围成一圈,按特定规则报数并逐个淘汰,直至最后确定剩下人员的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

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

分析

有n个人,围成一圈,顺序排号,从某人开始数到第三个的人出列,再接着从下一个人又从1开始报数,最终输出最终出列的人

java代码

package d0225;

/**
 * @description: ${description}
 * @create: 2019-02-25
 * 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。
 * 从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,
 * 数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
 * 通常解决这类问题时我们把编号从0~n-1,最后 [1]  结果+1即为原问题的解
 * 有n个人围成一圈,顺序排号,从第一个人开始报数(从1~3报数),凡报到3的人退出圈子,问最后留下的人原来排在第几号
 **/
public class F {
    public static int f(int n){
        //初始化一个长度为n的boolean数组,并且全部赋值true
        boolean[] array=new boolean[n];
        for(int i=0;i<n;i++){
            array[i]=true;
        }

        int result=0;//最终留在队伍里面的人:即数组的下标+1
        int index=0;//数组下标
        int numberOfArray=n;//循环后,数组的长度
        int counter=0;//报数的数组(1,2,3)
        
        while (numberOfArray>1){
            if(array[index]){//当index这个位置为默认true的时候,counter才加1,如果被改变为falsle则不计数
                counter++;//反方向思考,如果这个位置是false的话,代表这个人走了,那么就是下个人来喊,下个人要是还走了,就让下下个人来喊
            }
            if(counter==3){//计数到3且满足楼上的情况下
                array[index]=false;//人离开
                numberOfArray--;//人数减一
                counter=0;//从零计算
            }
            index++;//下标递增
            if(index==n){//下标循环
                index=0;
            }
        }
        for(int i=0;i<n;i++){//找出唯一剩下的人
            if(array[i]==true){
                result=i;
                break;
            }
        }
        return result+1;//默认数组是1-n(原先是0~n-1),需要加一
    }

    public static void main(String[] args) {
        System.out.println(f(3));
        System.out.println(f(4));
        System.out.println(f(5));
        System.out.println(f(6));
        System.out.println(f(7));
    }
}

结果

在这里插入图片描述

心得

让index下标递增,先处理好counter的增加(必须是true)
然后再处理报数是3的(删,计数归零,数组长度减一)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值