转圈游戏

GitHub跳转原题关系图返回列表

每轮相当于全体位置编号 +m (mod n),用快速幂求 m·10^k mod n,一步算出答案。

OJ: roj

题目 ID: 1617

难度:入门

标签:

创建: 2026-09-30 22:17

更新: 2026-10-06 01:04

题目描述

nn 个小伙伴(编号 0∼n−10\sim n-1)围坐一圈,ii 号小伙伴初始在第 ii 号位置。每轮位置 ii 上的人顺时针走到位置 (i+m) mod n(i+m) \bmod n,共进行 10k10^k 轮,求 xx 号小伙伴最后的位置。 输入一行四个整数 n,m,k,xn,m,k,x,输出一行一个整数表示答案,数据范围 1<n<1061<n<10^6,0<m<n0<m<n,0<k<1090<k<10^9。 样例输入 10 3 4 5,输出 5。

思路

每轮所有人做的事情相同:位置编号 +m(modn)+m \pmod n,所以 10k10^k 轮后的位置为 (x+m⋅10k) mod n(x+m\cdot 10^k)\bmod n。用快速幂求出 10k mod n10^k \bmod n(O(log⁡k)O(\log k)),再代入取模即可,注意用 long long。

参考代码

Python 版:

python
"""转圈游戏:每轮所有人位置顺时针平移 m,共 10^k 轮。"""
import sys

def main() -> None:
    n, m, k, x = map(int, sys.stdin.read().split())
    # 每轮位置编号 +m (mod n),10^k 轮即快速幂求 m * 10^k mod n
    print((x + m * pow(10, k, n)) % n)

main()

C++ 版(同一算法):

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-10-06 01:04
 * update_at: 2026-10-06 01:04
 */

#include <iostream>
using namespace std;

typedef long long ll;

ll n, m, k, x; // n 个位置、每轮平移 m、轮数为 10^k、询问 x 号小伙伴

// 快速幂:返回 base^exp mod mod,中间乘积用 ll 不会溢出。
ll qpow(ll base, ll exp, ll mod) {
    ll result = 1 % mod;
    base %= mod;
    while (exp > 0) {
        if (exp & 1) {
            result = result * base % mod;
        }
        base = base * base % mod;
        exp >>= 1;
    }
    return result;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> m >> k >> x;

    // 每轮全体位置 +m,10^k 轮后位置为 (x + m*10^k) mod n。
    ll ten_pow = qpow(10, k, n);       // 10^k mod n
    ll ans = (x + m * ten_pow) % n;    // 平移总量 m*10^k 对 n 取模
    cout << ans << '\n';

    return 0;
}