Josephus 问题(2)

本文详细分析了一个环形报数游戏中最后留下的编号规律,并提供了C语言实现。通过观察发现,编号以2的幂次方为周期,结合数学公式计算出经历的轮数和在轮中的位置,最终得出结果。算法时间复杂度为O(1),空间复杂度也为O(1),展示了数学在编程中的应用。

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

一、题目

N人围成一个环,每个人一个编号1—n,然后1、2报数,报2出局,其余人继续,直至最后一人。求该人的编号。有时间限制

二、分析
找规律: 我直接写出了n从1—17的最终答案,分别为:1、1、3、1、3、5、7、1、3、5、7、9、11、13、15、1…发现其是以2的幂次方为一个轮回,然后奇数增长。
分开更容易看清:
第一轮:1
第二轮:1、3
第三轮:1、3、5、7
第四轮:1、3、5、7、9、11、13、15

个数刚好为1、2、4、8…
编写代码思路:首先我们要确定所给的数n是经历了几轮这样的循环,然后再确定是这一轮的哪个位置即可算出结果。
这里我们设为x轮,则有
在这里插入图片描述
这里c为一个变量。我们把所给数n放在第x+1轮,其前面总有x轮(x>=0)。
①求x:
因为有2^x-1+c=n,两边取对数:x=log2(n)-log2(c-1);
由于为整数,所以x=log2(n)向下取整即可(代码中已经自动实现向下取整,故不必考虑)。
c语言编程实现,可以使用log()函数。不过log()函数以10为底的,我们可以利用对数函数的换底公式。
于是则有:log2(n)=log10(n)除以log10(2)。
代码实现为: x = log(n)/log(2);

在求出经历x轮后,还得求出是第x+1轮的哪个位置。这里设为num,
②求num:
因为有2^x+num=n,故num=n-2 ^x。

③算出结果y
根据1,3,5,7……这样的规律
y=2*num+1。

三、算法实现

int main()
{
    long long n,x,y,num;
    while(scanf("%lld",&n)!=EOF)
    {
        x = log(n)/log(2);//计算出经历的轮数。
        num=n-pow(2,x);//所在的轮数的第num位上
        y=2*num+1;//求最终值。
        printf("%lld\n",y);
    }

    return 0;
}

四、算法分析
此算法为公式计算,故可以得出其时间复杂度为O(1).根据程序,易知空间复杂度为O(1)。 感受数学在编程过程中的无比魅力,数学思维很重要

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值