n个人 从1至N开始顺序循环数数,每数到M时,将该数字退出,继续从下个人开始数,最后一个退出的为胜利者
把问题变成0-n-1(编号变了而已),
第一个人出列之后,(第一个人编号一定是m%n-1)
剩下的是n-1个人,编号从0-(n-2)
组成一个新的约瑟环夫问题
接下去就是从编号m%n开始计数
k k+1 k+2 ... n-2, n-1, 0, 1, 2, ... k-2并且从k开始报0
把他们的编号换一下
即:
k->0
k+1->1
....
.....
.....
k-2->n-2
k-1->n-1
这样子就是另一个新的约瑟环夫问题了
求出胜利者之后
只要把他的编号变回原来的编号就行了
设最后的是为x胜利者
x'=(x+m)%n;(n为当前约瑟环夫问题的总人数 )
x''=(x'+m)%(n+1);
.....
.....
知道最后n为最初的约瑟环夫问题的人数为止
所得的x+1就是最后的胜利者编号(因为本来从0开始)】
晕死了
这么短的代码
这么长的理论
数学知识博大精深...
巨汗!
#include <stdio.h>
int main()
{
int n, m, i, s = 0;
scanf("%d%d", &n, &m);
for (i = 2; i <= n; i++)
s = (s + m) % i;
printf ("%d\n", s+1);
}