1 条题解
-
0
题目分析
本题是一个循环移位问题。 个小伙伴围成一圈,每轮所有小伙伴顺时针移动 个位置,经过 轮后,求编号为 的小伙伴所在的位置。
数学建模
设初始时位置 上的小伙伴编号为 。
经过 轮后,位置 上的小伙伴编号为:
经过 轮后,位置 上的小伙伴编号为:
我们要求的是经过 轮后,编号为 的小伙伴在哪个位置 ,即解方程:
解得:
核心算法
因此问题转化为计算:
由于 最大可达 ,直接计算 会溢出,需要使用快速幂算法计算 。
代码解析
#include <bits/stdc++.h> using namespace std; long long n, k, x, m; int main() { cin >> n >> m >> k >> x; int anss = 10, ans = 1; // anss 是底数,ans 是结果 // 快速幂计算 10^k mod n while (k != 0) { if (k & 1) // 如果当前位为1 ans = (ans * anss) % n; anss = (anss * anss) % n; // 底数平方 k >>= 1; // 指数右移 } // 计算最终位置 cout << (x + m * ans) % n << endl; return 0; }
算法步骤
- 输入:读取 , , ,
- 快速幂计算 :
- 初始化
anss = 10(底数),ans = 1(结果) - 遍历 的二进制位:
- 如果当前位为 :
ans = (ans * anss) % n - 平方底数:
anss = (anss * anss) % n - 右移指数:
k >>= 1
- 如果当前位为 :
- 初始化
- 计算最终位置:
- 输出:位置
复杂度分析
- 时间复杂度:
- 快速幂的循环次数为 的二进制位数
- 对于 ,最多循环约 次
- 空间复杂度:
- 只使用了常数个变量
示例验证
对于样例输入:
n=10, m=3, k=4, x=5计算过程:
- 计算
- 的二进制:
- 循环过程:
- :
anss=10→anss=(10*10)%10=0 - :
anss=(0*0)%10=0 - :
ans=(1*0)%10=0,anss=(0*0)%10=0
- :
- 计算位置:
输出:
5,与样例一致。
关键点说明
- 模运算性质:$(a \cdot b) \bmod n = [(a \bmod n) \cdot (b \bmod n)] \bmod n$
- 快速幂原理:将指数 用二进制表示,通过平方和乘法分解计算
- 循环移位等价性:顺时针移动 格等价于逆时针移动 格,但本题采用数学推导直接得出公式
该算法能够高效处理 高达 的大数据范围,是本题的最优解法。
- 1
信息
- ID
- 4259
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者