• 2018-2019 ACM-ICPC 沈阳赛区 K. Let the Flames Begin


    K. Let the Flames Begin

    题目链接:https://codeforces.com/gym/101955/problem/K

    题意:

    n个人围成一个圈,然后依次从1开始报数,报到k的人出局,现在有个人,他想要成为第m个出局的男人,现在要求他初始位置应该在哪。

    题解:

    类似于约瑟夫环问题,所以我们可以考虑一下递推。我们可以考虑一下n和n - 1规模的关系,借助于约瑟夫环的思路,我们可以知道,如果一个人在n - 1规模时位置为p,那么n的规模时位置应为(p + k) % n (下标从0 ~ n - 1)。我们设第m轮出局的位置为f(n,m),那么就有f(n,m) = (f(n - 1 , m - 1) + k ) % n。

    但是这里n,m,k可能到10^18,数据范围过大,直接递推行不通。但是题目中有个条件为min(m,k) <= 2e6, 那么我们就需要利用上这个信息。

    当m <= k 时,我们直接从f(n - m + 1 , 1)开始递推即可,题中数据保证这样不会超时;

    当m > k时,这个k可能远小于n,也就是取模操作困难隔很久才一次,所以我们可以根据这个加速递推。设c轮过后会取模,那么有f(a,b) + c * k >= a   =>   c >= (a - f(a,b)) / k,我们直接通过计算得出这个c就好了~

    这个题主要就是在于对递推式的理解吧~

    代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    ll n,m,k;
    int T;
    int main() {
        ios::sync_with_stdio(false);cin.tie(0) ;
        int cnt = 0;
        cin >> T;
        while(T--) {
            cnt++;
            cin >> n >> m >> k ;
            cout << "Case #" << cnt << ": " ;
            ll p = n - m + 1;
            ll ans = (k - 1) % p ;
            if(m < k) {
                for(int i = 2; i <= m ; i++)
                    ans = (ans + k) % (++p);
            }else {
                ll a = n - m + 1;
                if(k == 1) {
                    cout << m << '
    ' ;
                    continue ;
                }
                while(a < n) {
                    ll x = (ll)ceil(1.0 * (a - ans) / (k - 1));
                    if(a + x > n) x = n - a;
                    ans = (ans + x * k ) % (p = a + x) ;
                    a = a + x ;
                }
            }
            cout << ans + 1<< '
    ' ;
        }
        return 0 ;
    }
  • 相关阅读:
    LAMP LNMP 和 LNMPA
    nginx版本如何选择?
    如何看apache的版本号
    CLR Via CSharp读书笔记(12):泛型
    要先怀疑外部代码的错误,再检测是不是自己代码的问题
    redis的那些事
    An Illustrated Guide to SSH Agent Forwarding
    Using sshagent with ssh
    dtach
    [原创]bind DNS IP列表的精确获取
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10680195.html
Copyright © 2020-2023  润新知