约瑟夫环问题

来源:互联网 发布:西门子1200编程软件 编辑:程序博客网 时间:2024/05/14 03:21

问题

n个人, 编号为1到n, 排成一个圈, 顺时针从1开始报数. 数到m的退出游戏, 剩下的人继续游戏. 活到最后的一个人是胜利者. 求最后胜利者的编号.

思路

剩下i个人, 讲剩下i个人的序号映射到1..i, 从而得到递推公式. 

假设当前剩下i个人(i<=n), 这一轮m要退出游戏. 经过这一轮, 剩下的人是1 2 3 ... m- 1 m + 1 ... i. 

我们将从m+1开始的数映射成1, 则m+2对应2, i对应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,i, s=0;    printf( "N  M  =  ");    scanf("%d%d ",&n,&m);    for(i=2;i<=n;i++)s=(s+m)%i;    printf("The winner is %d/n ", s+1);    return 0;}

总结

这道题实际上是从后向前想,有一个递推式

x(n)为指针的位置x(n) = (x(n - 1) + m)% i 

原创粉丝点击