• Josephus(约瑟夫环)


    第二次考虑这个问题,感觉理解深刻多了!

    问题描述:n个人(编号1~n)围成一个环,先淘汰m,再从m的下一位开始报数,报到k的人退出,剩下的人又从淘汰的人下一位开始,从1开始报数....。求胜利者的编号。

    例如:n=8,k=5,m=3

    则游戏过程为:        12345678 (开始)

           淘汰3     新环:4567812        开始从1报数,报到5(k = 5)者被淘汰

           淘汰8     新环:124567          报数

           淘汰6     新环:71245            报数

           淘汰5     新环:7124              报数

           淘汰7     新环:124                报数

           淘汰2     新环:41                  报数

           淘汰4     新环:1                    胜利者

    -----------------------------------------------------------------------------------

    解题思路:第一个人m出列后,剩下的人组成一个新环

    m+1 m+2 m+3 ... n-1, n,  1, 2 ,... m-1   (做编号转换为 1 2 3 ..... n-1

    我们知道接下来第二个人(编号一定是 k % n-1) 出列之后,剩下的n-2个人又组成了一个新的约瑟夫环(以编号为k+1的人开始):

    k+1 k+2 ... n-2,n-1,1,2,... k-1

    作编号转换:

        k+1 --> 1

          k+2 --> 2

      ..........

      k-3 --> n-4

      k-2 --> n-3

          k-1--->n-2

    变换后就成为了(n-2)个人报数的子问题,那么如果我们知道这个子问题的解:例如x 是最终的胜利者,根据编号转换的原则,就可以逆推出 x 在原序列中的位置。

    易推出 x'= (x+k) % n-1。  //第一轮m已被淘汰

    由此可得递推公式f[i]表示胜利者在 i 个人中的位置:

      f[1]=1;      //最后的胜利者位于1号位

      f[i]=(f[i-1]+k)%i; ( n > i >1)   //第一轮m已被淘汰

    以上例子的递推过程:

           新环:1                   胜者位置:f[1] = 1

           新环:41                        位置:f[2] = 2  =(1+5)% 2(倒数第二轮只有两人)

           新环:124                      位置:f[3] = 1  = (2+5)% 3

           新环:7124                    位置:f[4] = 2  = (1+5)% 4

           新环:71245                  位置:f[5] = 2  = (2+5)% 5

           新环:124567                位置:f[6] = 1  = (2+5)% 6

           新环:4567812              位置:f[7] = 6  = (1+5)% 7

    再做一个处理即可得胜利者原来的位置为:f[8] = (6+3)% 8 = 1

    代码:

    int Josephus_circle(int n,int k,int m)

    {

       int ans = 1;

       for(int i = 2; i < n; i++)

       {

           ans = ( ans + k )% i;

           if(ans == 0) ans = i;           //刚好整除,说明刚好处于i号位

       }

       ans = (ans + m)%n;

       ans = (ans == 0)? n:ans;

       return ans;

    }

  • 相关阅读:
    android gradle 打包命令
    android RRO
    android adb 常用命令
    mui执行滑动事件: Unable to preventDefault inside passive event listener
    获取 input[type=file] 文件上传尺寸
    MySQL:You can't specify target table for update in FROM clause
    input标签中autocomplete="off" 失效的解决办法
    @media属性针对苹果手机写法
    centos7 下mysql5.7修改默认编码格式为UTF-8
    使用Mui加载数据后a标签点击事件失效
  • 原文地址:https://www.cnblogs.com/chenbjin/p/Josephus.html
Copyright © 2020-2023  润新知