约瑟夫(Josephus)问题

本文介绍了约瑟夫问题的历史背景及算法实现,该问题源于古罗马时期,通过一个特定的报数规则确定最后的幸存者。文中提供了一个具体的算法示例,用于计算指定人数和报数间隔条件下每个人的出圈顺序。

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

约瑟夫(Josephus)问题是由古罗马的史学家约瑟夫提出的,他参加并记录了公元66-70年犹太人反抗罗马的起义。约瑟夫作为一个将军,设法守住了裘达伯特城达47天之久,在城市沦陷之后,他和40名将士在附近的一个洞穴中避难。在哪里,将士们群情激奋并表示:要投降毋宁死。于是,约瑟夫建议每个人轮流杀死他旁边的人,而这个顺序是由抽签决定的。约瑟夫有预谋地抓到了最后一签并且做为洞穴中两个幸存者之一生存下来。约瑟夫环问题的具体描述是:设有编号为12......nn(n>0)个人围成一个圈,从第一个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,报m的出圈,......,如此下去,知道只剩下一人为止。当任意给定 n m后,设计算法求 n个人出圈的次序。

    

        int minIndex = 0;//计数器

        int quet = 0;//记录剩下的人数

        int m = 0, n = 0;

        printf("输入人数和循环数:");

        scanf("%d%d", &m, &n);

        int array[m];

        int index = m;//循环次数

        for ( int i = 0; i <= m ; i++) {

            array[i - 1] = i;

        }

    

        while (index > 0) {

            //外层循环次数大于他的人数就行,保证能循环到找到那个人

            for (int i = 0; i < m; i++) {

                if (array[i] != 0) {

                    //如果对应的值不等于0,也就是对应位置还有人参与的话,累加midIndex,也就是继续数数

                    minIndex ++;

                }

                if (minIndex == n) {

                    //如果数到3,则让其下标对应的人退出,(对应值归零)

                    array[i] = 0;

                    //如果累加等于3,也就是数到3的时候,累加器归零,重新数数

                    minIndex = 0;

                }

            }

            //以上循环循环一次之后,会得出一组踢人之后的数组.

            for (int i = 0; i < m ; i++) {

                if (array[i] != 0) {//这个条件判断对应的位置是否有人,如果有人 则累加器+1

                    quet++;

                }

            }

            //循环过后得到,第一次循环之后,还剩多少人

    

            if (quet == 1) {//如果剩下一个人,则让外层循环停止  也就是 index 初始化,

                index = 0;

                for (int i = 0; i < m ; i++) {

                    if (array[i] != 0) {

                        printf("剩下的人是:%d",array[i]);//输出剩下的一个人

                    }

                }

            }

            else if (quet != 1)//如果剩下的人不是一个,则重置quet,要不然下次循环还会累加

                quet = 0;

    

            index --;

        }

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值