约瑟夫环问题

来源:互联网 发布:电商与淘宝有什么区别 编辑:程序博客网 时间:2024/06/07 00:00

        在1-n个人中,从1开始报数,数到m的那个人退出,后面的人继续从1开始报数,求最后剩余的那个人在原来的序列1-n中序号是多少?

        在这个问题中,第一次退出的那个人编号为(m-1)%n+1(这里为什么不直接写m%n,因为序列是从1开始的,如果是m=3,n=3,退出的人是m%n=0么,不是,应该是2%3+1才对,如果我们先将编号先置为0-n-1,那么就是m%n,然后可以再结果后面加上1即可),那么编号为m%n+1的这个人又开始从1数,直至数到m退出,问题变为规模为n-1个人的约瑟夫环问题,如下,设k = m%n+1

        k        ->    1

        k+1    ->    2

        k+2   ->    3

              .......

        k-2   ->    n-1

        我们假设在这n-1个人中,最后的胜出者编号为x,那么,由上表可知在n个人中,该胜出者的编号为(x+k-2)mod n+1,从而得知规模为n的问题,可以化解为规模为n-1的问题,也可以得出第推公式为

        f[n] = (f[n-1]+k-2)mod n +1  = (f[n-1]+m-1)mod n + 1

        且f[1] = 1

        由上公式,我们可以用C语言实现出这个问题的求解,代码如下所示

       1 #include <stdio.h>
       2 #include <stdlib.h>
       3 int JosephCircle(int n,int m){
      4     if(n == 1)
      5         return 1;
      6     else if(n > 1){
      7     int val;
      8     val = (JosephCircle(n-1,m)+m-1)%n+1;
      9     return val;
     10     }
     11     else
     12         printf("input failed\n");
     13     return 0;
     14 }   
     15 int main(){
     16     int n;
     17     int m;
     18     int value;
     19     scanf("%d %d",&n,&m);
     20     value = JosephCircle(n,m);
     21     printf("The number is %d\n",value);
     22     return 0;
     23 }


0 0
原创粉丝点击