题目:有10个人围成一圈,从1到3循环报数,数到3的人退出,最后剩下的人是谁?
这道题,可以抽象成这样:有N个人围成一圈,从1到M报数,数到M的人退出,最后剩下的人是谁?
以前在写程序解这道题的时候都是用数组+for循环的方式实现。今天偶然见到一种牛逼方法:一个公式F(N) = (F(N-1)+M)%N;
此公式的推导过程如下:
1:假设有N个人 1 2 3 ..... N 数到M的出列
2:第一次第(M)个人 出列 也就是 1 2 M-1 ? M+1 ...N
3:这里有个问题 如果M大于N的话怎么办?
3.1:如果M小于N 那么出列的就是M
3.2:如果 M > N 那么就是M除以N的余数:例如 2 个人数到 3 第一个出列的就是 3%2 = 1;
3.3:针对第一种情况 M<N. M%N=M 所以 第一个出列的人就是M%N. 则 F(1) = M % 1 = 0。
4:第二次出列的人就是第一个出列的人再往后数M个人,也就是第2M个人出列 也就是 F(N-1) + M
5:这时就有个问题第一次出列的问题
6:所以第二次出列的就是 2M % N. 也就是 F(N) = (F(N-1)+M)%N
所以程序代码如下:
public static int jie(int n, int m) {
if (n == 1) return 0;
else return ((jie(n - 1, m) + m) % n) ;
}
擦。两行代码就实现了。
数学太强大!!!!!!!!!!!!!!