C++复健
前言
都是一些零散的知识,梦到哪里记到哪。。。
1.最大公约数算法原理
- 首先,老师上课讲过,但是好像并没有听懂,今天重刷洛谷时候感觉对这方面不是很熟。
这个方法来自欧几里得的辗转相除法。代码实现如下:
1 | gcd(a,b){ |
辗转相除法:
实际上,这是高等代数讲过的问题,就是最大公约数和最大公约数的区别。先回忆一下高代中的知识。
定理:
在多项式环 $P[x]$ 中,任意两个多项式 $f(x)$ 和 $g(x)$ 都存在最大公因式。
而且,$f(x)$ 和 $g(x)$ 的任意一个最大公因式 $d(x)$ 都可以表示为 $f(x)$ 和 $g(x)$ 的线性组合,即存在 $u(x), v(x) \in P[x]$,使得:
$$
d(x) = u(x)f(x) + v(x)g(x)
$$
- 证明如下图所示:

由上述定理,我们可以知道f(x),g(x)的最大公因式一定存在,接下来我们看用辗转相除法的原理证明(题外话,,这成高代笔记了。。):
小红书大佬的辗转相除法证明:
那我们回过头看,令 a%b=r,这段代码的含义就是如果 b 不等于0,函数就返回 gcd(b,r),直到b=0,此时的a就是图二中的 rs(x).
1 | gcd(a,b){ |
2.同余原理
定义:
- 如果两个整数 $a$ 和 $b$,以及一个正整数 $m$,满足 $a \equiv b \pmod{m}$,则称 $a$ 与 $b$ 在模 $m$ 意义下同余。
也就是说,$a$ 和 $b$ 除以 $m$ 后余数相同,或者 $m$ 能整除 $a-b$。
举例:
$17 \equiv 5 \pmod{12}$,因为 $17 - 5 = 12$ 能被 $12$ 整除。
相当于:$a-b=km$,或者$a=b+km$.
性质:
- 同余关系具有传递性、对称性和自反性。(离散数学)
- 如果 $a \equiv b \pmod{m}$,则 $a + c \equiv b + c \pmod{m}$,$a \cdot c \equiv b \cdot c \pmod{m}$。
应用:
- 常用于简化大数运算,比如快速判断某个数能否被整除。
- 在密码学、算法竞赛、程序设计等领域广泛应用。
例题:
2003年5月9日是星期五,问第 $2^{2003}$ 天是星期几?
解题思路:一周有 7 天,星期几每 7 天循环一次,所以只需计算 $2^{2003}$ 除以 7 的余数。
计算 $2^{2003} \bmod 7$:
注意到 $2^3 \equiv 1 \pmod{7}$,所以 $2^{2003} = 2^{3 \times 667 + 2} = (2^3)^{667} \times 2^2 \equiv 1^{667} \times 4 \equiv 4 \pmod{7}$。
推算星期几:
第 1 天是星期五,第 $2^{2003}$ 天是星期五后的第 4 天:
- 星期五 + 1 天 = 星期六
- 星期五 + 2 天 = 星期日
- 星期五 + 3 天 = 星期一
- 星期五 + 4 天 = 星期二
答:第 $2^{2003}$ 天是星期二。
编程题目:

1 |
|
- 上述代码为题解,其中,关键点是天数的确定
1 | int currentDay = (x + i - 1) % 7 + 1; |
- 关键就在于这行代码,这里通过对 7 取模(% 7),实现了星期的循环计算。因为一周有 7 天,星期几每 7 天循环一次,所以用模运算可以得到当前是星期几,这正是同余原理在实际编程中的应用。现在我们来仔细解读这段代码
- x+i-1:
x 是起始星期几,比如星期五就是 5。
i 是循环变量,表示第几天(第 0 天、第 1 天……)。
x + i - 1 这样写是为了让第 0 天就是起始星期几,第 1 天是起始星期几的下一天,以此类推。 - 如果没有 -1,比如 currentDay = (x + i) % 7 + 1,那么当 i = 0 时,结果是 x + 0,也就是第 1 天是星期 x+1,这样会错位一天。
- +1:因为 % 7 得到的是 0-6,而星期几通常用 1-7 表示,所以最后加 1,把结果变成 1-7。
- x+i-1:
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 秃头的君寻酱!





