在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 }