链接
题目描述
有一游戏,规则如下:围圆圈坐,座位编号从0到 n - 1,现有若干轮游戏
每一轮第 0 号位置上的同学顺时针走到第 m 号位置
第1号位置同学走到第 m+1 号位置…
现在,一共进行了 10^k 轮,请问 x 号同学最后走到了第几号位置。
样例输入
10 3 4 5
样例输出
5
思路
我比较菜,没想到公式,还是用的很朴素的想法:
枚举从x出发,经过r轮之后重新回到了x点,然后快速幂求出 1 0 k % r 10^k\ \%\ r 10k % r,最后的余数再手动跑掉就可以了
大佬公式: ( x % n + m % n ∗ 1 0 k % n ) (x\%n+m\%n*10^k\%n)%n (x%n+m%n∗10k%n)
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#define ll long long
int n, m, k, x;
ll kk, r, t, b[1000005][5];
using namespace std;
ll ksm(int a, int b)
{
int p = 1;
while(b)
{
if(b & 1) p = (p * a) % r;
a = (a * a) % r;
b /= 2;
}
return p;
}
int main()
{
// freopen("game.in", "r", stdin);
// freopen("game.out", "w", stdout);
scanf("%d%d%d%d", &n, &m, &k, &x);
int xx = x;
t = 0;
while(!b[x][0])
{
xx = (xx + m) % n;
if(xx == x) {
t++; break;}
if(!b[xx][0]) {
b[xx][0] = 1;
b[xx][1] = ++t;
}
}
r = t - b[x][1];
kk = ksm(10, k);
if(!kk) printf("%d", x);
else {
for(int i = 1; i <= kk; ++i)
x = (m + x) % n;
printf("%d", x);
}
return 0;
fclose(stdin);
fclose(stdout);
}