首页 > 代码库 > UVALive 3882 And Then There Was One

UVALive 3882 And Then There Was One

题解:

先来探讨约瑟夫问题

常规做法是链表模拟.不多说

递推做法

分析:

第一次:        0.1.2 ..... k-1.k.k+1........n-1

去掉k - 1     0.1.2 .....       k.k+1........n-1

从k开始       k.k+1...... n-1.0.1........ k-2

转换           0.1..........n-2  (转换公式: ( i - k + n ) % n )

第二次        0.1..........n-2

去掉k - 1     0.1.2 .....       k.k+1........n-2

从k开始       k.k+1...... n-2.0.1........ k-2

转换           0.1..........n-3  (转换公式: ( i - k + n - 1 ) % ( n - 1 ) )

........

第n次         0

反向递推

a = 0

第n次的0等价于第n-1次。最后一个删除的数  a = ( a + k  ) % 2

a 等价于第n - 2次。最后一个删除的数         a = ( a + k ) % 3

......

a = ( a + k ) % n

那么递推公式出来了

a = 0;
for( int i = 2; i <= n; i ++ ) a = ( a + k ) % i;

再根据m - 1 与 k - 1 的相对位置判断即可

最后需要 + 1

代码:

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define se second
#define fs first
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pii pair<int,int>
#define ll long long

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

 

UVALive 3882 And Then There Was One