假设现在是6个人(编号从0到5)报数,报到(2-1)的退出,即。那么第一次编号为1的人退出圈子,从他之后的人开始算起,序列变为2,3,4,5,0,即问题变成了这5个人报数的问题,将序号做一下转换:

2 —>0

3 —>1

4 —>2

5 —>3

0 —>4

现在假设x为0,1,2,3,4的解,x’设为那么原问题的解(这里注意,2,3,4,5,0的解就是0,1,2,3,4,5的解,因为1出去了,结果还是一个),根据观察发现,x与x’关系为x’=(x+m)%n,因此只要求出x,就可以求x’。

令f[i]表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n]
递推公式
f[1]=0;
f[i]=(f[i-1]+m)%i; (i>1)
有了这个公式,我们要做的就是从1-n顺序算出f[i]的数值,最后结果是f[n]。因为实际生活中编号总是从1开始,我们输出f[n]+1。
由于是逐级递推,不需要保存每个f[i]:

int main()
{
    int n,k,s=0,i;
    scanf("%d%d",&n,&k); 
    for(i=2;i<=n;i++)
        s=(s+k)%i;
    printf("%d\n",s+1);
    return 0;
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

51nod 1079 中国剩余定理 Previous
51nod 1384 全排列 Next