zoukankan      html  css  js  c++  java
  • POJ3517And Then There Was One

    约瑟夫环问题变形

    问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。

    编号0-(n-1)是有意义的,因为要模n,所以用0-(n-1)更好操作

    我们知道第一个人(编号一定是(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)个人报数的子问题,假如我们知道这个子问题的解:例如x是最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗?!!变回去的公式很简单,相信大家都可以推出来:x'=(x+k) mod n

    f[n]=(f[n-1]+k)%n,f[1]=0;  f[i]表示有i个人时,最后胜利者编号

    ---------------

    现在这个问题是从m开始,即是首先(m-1)编号的人出去。。然后就和普通约瑟夫环一样了。

    故只要我们f[n]=(f[n-1]+m)%n单独算就行了。其他f[i]=(f[i-1]+k)%i;(1<i<n);

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    #define MAXN 10000+50
    int f[MAXN];
    
    int main()
    {
        int n,k,m;
        while(~scanf("%d%d%d",&n,&k,&m))
        {
            if(n==0)
                break;
            f[1]=0;
            for(int i=2;i<n;i++)
            {
                f[i]=(f[i-1]+k)%i;
            }
            f[n]=(f[n-1]+m)%n;
            cout<<f[n]+1<<endl;
        }
        return 0;
    }
  • 相关阅读:
    mvn常用命令
    maven pom.xml解释 (转)
    hibernate的主键生成策略
    软件绿色版和安装版的区别
    spring事务
    JdbcTemplate操作数据库
    控制反转和spring在项目中可以带来的好处
    三种实例化bean的方式
    UVA 1262 Password 暴力枚举
    CSDN2015博客之星评选之拉票环节
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2868183.html
Copyright © 2011-2022 走看看