【题目链接】
ybt 1617:转圈游戏
ybt 1875:【13NOIP提高组】转圈游戏
洛谷 P1965 [NOIP2013 提高组] 转圈游戏
【题目考点】
1. 取模运算
【解题思路】
第x号小伙伴第一轮后走到
x
+
m
x+m
x+m位置,第二轮后走到
x
+
2
m
x+2m
x+2m位置,如果该位置的值超过了n,位置编号要减n,使得位置编号只能在0~n-1范围内。因此
1
0
k
10^k
10k轮后,第x号小伙伴所在的位置为
(
x
+
1
0
k
⋅
m
)
%
n
(x+10^k\cdot m)\%n
(x+10k⋅m)%n。
已知x、m都小于n。根据同余定理的乘法应用:
a
⋅
b
%
m
=
(
a
%
m
⋅
b
%
m
)
%
m
a\cdot b \% m = (a\%m \cdot b\%m)\%m
a⋅b%m=(a%m⋅b%m)%m
有:
(
x
+
1
0
k
⋅
m
)
%
n
(x+10^k\cdot m)\%n
(x+10k⋅m)%n
=
(
x
%
n
+
(
1
0
k
%
n
⋅
m
%
n
)
%
n
)
%
n
=(x\%n+(10^k\%n\cdot m\%n)\%n)\%n
=(x%n+(10k%n⋅m%n)%n)%n
=
(
x
+
(
1
0
k
%
n
⋅
m
)
%
n
)
%
n
=(x+(10^k\%n\cdot m)\%n)\%n
=(x+(10k%n⋅m)%n)%n
主要问题是求
1
0
k
%
n
10^k\%n
10k%n
k达到
1
0
9
10^9
109,这里必须使用快速幂算法(快速幂算法求幂的复杂度为
O
(
l
o
g
n
)
O(logn)
O(logn),n是指数的大小)。
根据同余定理,有:
a
b
%
m
=
(
a
%
m
)
b
a^b\%m = (a\%m)^b
ab%m=(a%m)b。在使用快速幂的过程中,对于底数a和结果r,每次运算后都对m取模即可。
【题解代码】
解法1:快速幂
#include<bits/stdc++.h>
using namespace std;
int fastPowMod(int a, int b, int m)//快速幂求a^b%m
{
int r = 1;//结果
while(b > 0)
{
if(b % 2 == 1)
r = (r * a) % m;
a = (a * a) % m;
b /= 2;
}
return r;
}
int main()
{
int n, m, k, x;
cin >> n >> m >> k >> x;
cout << (x + fastPowMod(10, k, n) * m % n) % n;
return 0;
}