hdu 5643 King's Game 约瑟夫变形

首先约瑟夫问题的数学推理过程:我们知道第一个人(编号一定是(m-1) mod n) 出列之后,剩下的n-1个人组成了一个新的约瑟夫环(以编号为k=m mod n的人开始):
k k+1 k+2 ... n-2,n-1,0,1,2,... k-2
并且从k开始报0。
我们把他们的编号做一下转换:
k --> 0
k+1 --> 1
k+2 --> 2
...
...
k-2 --> n-2
问题变为(N-1)个人,报到为(M-1)的人自杀,问题规模减小了。这样一直进行下去,最后剩下编号为0的人。用函数表示:

F(1)=0

当有2个人的时候(N=2),报道(M-1)的人自杀,最后自杀的人是谁?应该是在只有一个人时,报数时得到的最后自杀的序号加上M,因为报到M-1的人已经自杀,只剩下2个人,另一个自杀者就是最后自杀者,用函数表示:

F(2)=F(1)+M

可以得到递推公式:

F(i)=F(i-1)+M

因为可能会超出总人数范围,所以要求模

F(i)=(F(i-1)+M)%i

知道了约瑟夫问题的原理之后;

题意:给你n个人,每个人报1,2,,,,,n,报道数的人被处死,求最后活着的人的编号
根据约瑟夫问题,可以知道每次都是倒推回去;
所以将m改变成n-1,n-2,n-3,....1;

# include <stdio.h>
int main()
{
    int m, n, i, s;
    int x;
    scanf("%d",&x);
    while(x--)
    {
        scanf("%d", &n);
        s=0;
        m=n-1;
        for (i = 2; i <= n; ++i)
        {
            s=(s + m)%i;
            m--;
        }
        printf("%d\n", s+1);   
    }
    return 0;
}

  

posted @ 2016-03-23 19:41  jhz033  阅读(237)  评论(0编辑  收藏  举报