zoukankan      html  css  js  c++  java
  • 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 ;
    }
  • 相关阅读:
    结对编程项目作业4
    团队编程项目进度
    团队编程项目作业2-团队编程项目代码设计规范
    现代软件工程 阅读笔记
    个人编程作业1-GIT应用
    结对编程项目作业2-开发环境搭建过程
    结对编程项目作业2-结对编项目设计文档
    课后作业-阅读任务-阅读提问
    《团队-科学计算器-模块测试过程》
    团队-科学计算器-模块开发过程
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10680195.html
Copyright © 2011-2022 走看看