zoukankan      html  css  js  c++  java
  • 【UVa1394】And Then There Was One

    题目描述

    n个人围成环,首先第m个人出列,然后从下一个开始,数到第k个就出列。问最后剩下的是谁?


    输入

    多组数据。每组数据包含3个整数n,k,m ( 2≤n≤10000 ,1≤k≤10000,1≤m≤n )。输入结束标志为n=k=m=0。


    输出

    对于每组数据,输出最后一个被删除的数。


    样例输入

    8 5 3

    100 9999 98

    10000 10000 10000

    0 0 0

    样例输出

    1

    93

    2019



    题解

    假设将编号变为0~n-1。第一次拿数就应该是 k-1 ( 假设 k < n ) ,然后,我们从k开始重新编号,即 k -> 0 ,k+1 -> 1 ........ 。新的编号与原编号有什么关系?原编号 = (新编号+ k )% n。

    可以想象,当还有最后一个人的时候,他的新编号一定是 0,即 f [ 1 ] = 0 , 他在上一轮的编号 f [ 2 ] = ( f [ 1 ] + k ) % 2,然后由 f [ 2 ] 推出 f [ 3 ] 继而 f [ n ] 就是答案。最后再考虑从m开始取编号从一开始。

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=10000+50;
    
    int n,k,m;
    int f[maxn];
    
    template<typename T>void read(T& aa){
        char cc; ll ff;aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main(){
        while(scanf("%d%d%d",&n,&k,&m)&&(n||m||k)){
            f[1]=0;
            for(int i=2;i<=n;i++) f[i]=(f[i-1]+k)%i;
            int ans=(m-k+1+f[n])%n;
            if(ans<0) ans+=n;
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    orm 锁 和 事务
    多表查询
    django 单表查询
    djgango装饰器
    几个SQL命令的使用
    怎么成为优秀的软件模型设计者?
    jbpm 工作流(二)
    Jbpm工作流(一)
    EJB 介绍
    JNDI 使用
  • 原文地址:https://www.cnblogs.com/rlddd/p/9542418.html
Copyright © 2011-2022 走看看