题目描述
�n 个小伙伴(编号从 00 到 �−1n−1)围坐一圈玩游戏。按照顺时针方向给 �n 个位置编号,从 00 到 �−1n−1。最初,第 00 号小伙伴在第 00 号位置,第 11 号小伙伴在第 1 号位置,……,依此类推。
游戏规则如下:每一轮第 00 号位置上的小伙伴顺时针走到第 �m 号位置,第 11 号位置小伙伴走到第 �+1m+1 号位置,……,依此类推,第 �−�n−m 号位置上的小伙伴走到第 00 号位置,第 �−�+1n−m+1 号位置上的小伙伴走到第 11 号位置,……,第 �−1n−1 号位置上的小伙伴顺时针走到第 �−1m−1 号位置。
现在,一共进行了 10�10k 轮,请问 �x 号小伙伴最后走到了第几号位置。
输入格式
输入共 11 行,包含 44 个整数 �n、�m、�k、�x,每两个整数之间用一个空格隔开。
输出格式
输出共 11 行,包含 11 个整数,表示 10�10k 轮后 �x 号小伙伴所在的位置编号。
样例
输入数据 1
10 3 4 5
Copy
输出数据 1
5
Copy
数据范围与提示
对于 30% 的数据,0<�<70<k<7;
对于 80% 的数据,0<�<1070<k<107;
对于 100% 的数据,1<�<1061<n<106,0<�<�0<m<n,1≤�≤�1≤x≤n,0<�<1090<k<109。
题解
这道题我给大家三种解法
解法①:分配率
#include <iostream>
using namespace std;
int cnt(int n, int m, int k, int x)
{
int ans = 1, a = 10;
while(k)
{
if((k) & (1))
{
ans = ans * a % n;
}
a = a * a % n;
k >>= 1;
}
return (x % n + m % n * ans % n) % n;
}
int main()
{
int n, m, k, x;
cin >> n >> m >> k >> x;
cout << cnt(n, m, k, x) << endl;
return 0;
}
Copy
解法②:递增取余
#include <iostream>
using namespace std;
int main()
{
long long n, m, k, x,y;
cin >> n >> m >> k >> x;
long long x1 = x, x2 = x;
for (long long i = 0; i < 1e9; i++)
{
x += m;
x %= n;
if (x == x1)
{
x1 = i + 1;
break;
}
}//x1圈后回到x位置
int j = 1;
for (int i = 0; i < k / 4; i++)
{
j *= 10000;
j %= x1;
}
for (int i = 0; i < k % 4; i++)
{
j *= 10;
j %= x1;
}
//剩余j圈
for (int i = 0; i < j; i++)
{
x2 += m;
x2 %= n;
}
cout << x2 << endl;
return 0;
}
Copy
解法③:快速幂
#include <iostream>
using namespace std;
long long n, m, k, x;
int ksm(long long a, long long b, long long c)
{
long long d = 1;
a %= c;
while (b > 0)
{
if (b % 2 == 1)
d = (d * a) % c;
b /= 2;
a = (a * a) % c;
}
return d;
}
int main()
{
cin >> n >> m >> k >> x;
k = ksm(10, k, n * m);
k *= m, x += k;
cout << x % n;
return 0;
}