【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;
}

 

posted @ 2018-08-27 15:20  rld  阅读(138)  评论(0)    收藏  举报