题目描述
n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏。按照顺时针方向给 n 个位置编号,从0 到 n-1。最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置,……,依此类推。游戏规则如下:每一轮第 0 号位置上的小伙伴顺时针走到第 m 号位置,第 1 号位置小伙伴走到第 m+1 号位置,……,依此类推,第n − m号位置上的小伙伴走到第 0 号位置,第n-m+1 号位置上的小伙伴走到第 1 号位置,……,第 n-1 号位置上的小伙伴顺时针走到第m-1 号位置。
现在,一共进行了 10^k轮,请问 x 号小伙伴最后走到了第几号位置。
输入输出格式
输入格式:输入文件名为 circle.in。
输入共 1 行,包含 4 个整数 n、m、k、x,每两个整数之间用一个空格隔开。
输出格式:输出文件名为 circle.out。
输出共 1 行,包含 1 个整数,表示 10
k 轮后 x 号小伙伴所在的位置编号。
输入输出样例
输入样例#1:
10 3 4 5
输出样例#1:
5
说明
对于 30%的数据,0 < k < 7;
对于 80%的数据,0 < k < 10^7;
对于 100%的数据,1 <n < 1,000,000,0 < m < n,1 ≤ x ≤ n,0 < k < 10^9
。
分析
转到一轮时,他可能会回到x起始点,后面的都一样了,所以如果我们预处理出step数组,表示第几轮时在哪个位置,之后将步数模一下,输出就好。需要快速幂。不过看到别人的代码时发现自己写的好笨,只需要快速幂求出轮数,用这个乘以m(往前走的步数)+x,在模n,即可,中途别忘了取模。
code
1 #include<iostream> 2 using namespace std; 3 4 int step[500100]; 5 6 int Pow(int a,int p,int mod) 7 { 8 if (p==0) return 1%mod; 9 int tmp = Pow(a,p/2,mod); 10 if (p&1) 11 return (long long)tmp * tmp * a % mod; 12 else 13 return (long long)tmp * tmp % mod; 14 } 15 int main() 16 { 17 int c = 0,p,n,m,k,x; 18 cin>>n>>m>>k>>x; 19 p = x; 20 step[0] = x; 21 for (int i=1; ; i++) 22 { 23 p = (p+m)%n; 24 step[++c] = p; 25 if (p==x) break ; 26 } 27 cout<<step[Pow(10,k,n)%c]; 28 return 0; 29 }