zoukankan      html  css  js  c++  java
  • 约瑟夫环问题

    转:https://blog.csdn.net/tingyun_say/article/details/52343897

    讲一个比较有意思的故事:约瑟夫是犹太军队的一个将军,在反抗罗马的起义中,他所率领的军队被击溃,只剩下残余的部队40余人,他们都是宁死不屈的人,所以不愿投降做叛徒。一群人表决说要死,所以用一种策略来先后杀死所有人。 
    于是约瑟夫建议:每次由其他两人一起杀死一个人,而被杀的人的先后顺序是由抽签决定的,约瑟夫有预谋地抽到了最后一签,在杀了除了他和剩余那个人之外的最后一人,他劝服了另外一个没死的人投降了罗马。

    规则是这样的:

    在一间房间总共有n个人(下标0~n-1),只能有最后一个人活命。

    按照如下规则去杀人:

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

    特例:q为2

    1. 共有2k个人

    我们仔细分析也就是每次除去一半的元素,然后剩余的一半继续重复之前的策略,再除去一半。

      得到:j(2^k) = 1

    2.共有2k+t个人

    例如n = 9时,当除掉一个人之后,就又构成了上一个问题(共有2k个人),这时的第一个是除掉人的后一个。

     

    此时,我们可以把3号看成新的约瑟夫问题中的1号位置:
    也就是说这里的1代表的就是上一个问题中的3号

    由此递推得出几轮

    得到:J(2^k + t) = 2t+1

    说完了特例,

    现在说说q 不等于2的情况下:

     

     能不能由Jq(n+1)的问题缩小成为J(n)的问题:

    现在大概知道我们的新的约瑟夫环的下标都是这样来的:

    在旧的下标基础上,减去一个q,再用计算出的结果对长度取余
      new = (old-q) % n

      反推一下:
      old = (new+q) % n

    解释的通俗一点就是:人数每次减少一个,最后剩下一个的时候他一定是被杀死的且一定为0,我们要求得是这个0是上一个约瑟夫环中的几号,这样一层一层向上求,求出在当前环中的号数。

    代码:

    #include<iostream>
    #include<stdio.h>
    using namespace std;
    int yuesefu(int n,int m){
            if(n == 1){
                    return 0; //这里返回下标,从0开始,只有一个元素就是剩余的元素0
            }
            else{
                    return (yuesefu(n-1,m) + m) % n; //我们传入的n是总共多少个数
            }
    }
    int main(void){
            int a,b;
            cin>>a>>b;
            cout<<yuesefu(a,b)<<endl;
            //或者,直接循环迭代,求出来的result如上
            int result = 0;
            for(int i = 2;i <= a;i++){
                    result = (result+b) %i;
            }
            cout<<"result = "<<result<<endl;
            return 0;
    }

     

  • 相关阅读:
    Less学习笔记
    如何在网页启动Windows服务
    让VS2010记住TFS的登陆用户名和密码
    调式WP程序报0x80131500错误的解决办法
    FizzBuzzWhizz是算法题吗?我从设计的角度去解决的。
    基于Roslyn的远程任务平台
    优雅就一个字——设计模式之数据上传接口
    关于反射优化的疑问,单次调用时直接反射要快于委托调用反射?
    用VC++11中编译libthrift项目
    grunt初体验
  • 原文地址:https://www.cnblogs.com/Lune-Qiu/p/9183081.html
Copyright © 2011-2022 走看看