/**
问题描述:已知n个人(编号1,2...n)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;
他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,求最后出列的人的编号。
(以下代码是默认k = 1)
(1) 循环链表的方法时间复杂度为O(n*m).
(2) 一个时间复杂度为O(n)的数学方法,思路如下:
假设当前剩下i个人(i<=n),显然这一轮m要挂(因为总是从1开始数).经过这一轮,
剩下的人是:1 2 3...m-1 m+1...i, 我们将从m+1开始的数映射成1,则m+2对应2, n对应i-m,
1对应成i-m+1, m-1对应i-1,那么现在的问题变成了已知 i-1个人进行循环报数m,求出去的人的序号。
假设已经求出了i-1个人循环报数下最后一个出去的人的序号x0,那么它在n个人中的序号 x1 = (x0+m-1)%n + 1,
最初的 x0=1 ,反复迭代 x0和x1可以求出.
**/
#include <stdio.h>
int main()
{
int n, m, s, i;
scanf("%d %d", &n, &m);
s = 1; //初值为1
for (i=2; i<=n; i++)
{
s = (s+m)%i;
if (s == 0) s = i;
//这两个语句也可以用s = (s+m-1)%i + 1;来代替
}
printf("answer = %d/n", s);
}