约瑟夫环 详解

简介

所有人围成一圈,顺时针报数,每次报到q的人将被杀掉,被杀掉的人将从房间内被移走
然后从被杀掉的下一个人重新报数,继续报q,再清除,直到剩余一人

q = 2

对于q为2的情况,有个简单的方法。
假设2n2^n2n个人,从1开始数,那么最后活下来的那个一定是1,这个就不证明了。那么可以借用这个规律,假设有9个人,从1开始数,数到2,杀死,接下来到3的时候,相当于8个人从3开始数,那么根据上面的规律,活下来的就是3了(8==232^323

规律为:当q==2时,2n+t2^n+t2n+t个人活下来的是第2t+12t+12t+1个人

记得有道q==2,n<=1e100的题,就是可以用这个思路做。需要用大数,找到第一个小于等于2x2^x2x的数,直接得ans==2∗(n−2x)+1ans==2*(n-2^x)+1ans==2(n2x)+1


q != 2

设:n+1n+1n+1个数杀每次第q个的最终结果为A(n+1)A(n+1)A(n+1),n个每次杀第q个为A(n)A(n)A(n)
显然A(n+1)=(A(n)+q)%(n+1),A(1)==0A(n+1)=(A(n)+q)\%(n+1),A(1)==0A(n+1)=(A(n)+q)%(n+1),A(1)==0

证明:

n+1n+1n+1个人的游戏中,第一个杀掉的是k−1k-1k1,那么第二个人是k−1+kk-1+kk1+k。但是我们可以把杀掉一个人后的情况,看成nnn个人的游戏的开始,也就是说k−1+kk-1+kk1+k看成nnn个人的游戏中的k−1k-1k1。所以有A(n+1)=(A(n)+q)%(n+1)A(n+1)=(A(n)+q)\%(n+1)A(n+1)=(A(n)+q)%(n+1)
在这里插入图片描述
代码:

int f(int n,int q){
    if(n==1){
        return 0;
    }
    return (f(n-1,q)+q)%n;
}//若第一个编号为1,ans++即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值