当前位置: 首页 > news >正文

【数论】最大公因数 (gcd) 与最小公倍数 (lcm)

文章目录

  • 一、最大公因数 (gcd)
    • 1. 最大公因数的性质
    • 2. 欧几里得算法
  • 二、最小公倍数 (lcm)
  • 三、练习
    • 1. 最大公因数和最小公倍数 ⭐
    • 2. 三个数的最大公因数 ⭐
    • 3. 有大整数的最大公因数 ⭐⭐
      • (1) 补充:秦九韶算法
      • (2) 解题思路

一、最大公因数 (gcd)

1. 最大公因数的性质

我们在小学的时候就学过最大公因数 (Greatest Common Divisor, 简称 GCD),就是两个或多个数所有公因数中最大的那一个。比如 12 12 12 18 18 18 的最大公因数是 6 6 6。我们通常把两个数 x x x y y y 的最大公因数记为 g c d ( x , y ) gcd(x, y) gcd(x,y) 或者 ( x , y ) (x, y) (x,y)。你也许学过短除法、辗转相除法来求最大公因数,但是如果落实到代码上,该如何写呢?首先我们需要了解最大公因数的几个性质:

对于任意整数 a a a b b b c c c,有

  1. ( a , b ) = ( b , a ) = ( − a , b ) = ( a , − b ) (a, b)=(b, a)=(-a, b)=(a, -b) (a,b)=(b,a)=(a,b)=(a,b)

  2. a ∣ b a \mid b ab(" ∣ \mid " 为整除符号,意为 b b b 能够被 a a a 整除),则 ( a , b ) = a (a, b)=a (a,b)=a

  3. 对于任意两个整数 x x x y y y,必有 ( a , b ) ∣ a x + b y (a, b)\mid ax + by (a,b)ax+by

  4. x x x a a a b b b 的任意公因数,则有 x ∣ ( a , b ) x \mid (a, b) x(a,b)

  5. a = b q + c a = bq + c a=bq+c q q q 是一个整数,则有 ( a , b ) = ( b , c ) (a, b) = (b, c) (a,b)=(b,c)

其中第 5 个性质是我们用代码求解 gcd 的核心,下面对它进行证明:

证明: ( a , b ) (a, b) (a,b) a a a b b b 的最大公因数,那么一定有
( a , b ) ∣ a (a, b) \mid a (a,b)a
以及
( a , b ) ∣ b (a, b) \mid b (a,b)b
因为 a = b q + c a = bq + c a=bq+c,所以 c = a − b q c = a - bq c=abq,又由性质 3 可知,两个数的最大公因数可以整除这两个数的线性组合,所以有
( a , b ) ∣ a − b q (a, b) \mid a - bq (a,b)abq

( a , b ) ∣ c (a, b) \mid c (a,b)c
由于 ( a , b ) (a, b) (a,b) 既是 b b b 的公因数,又是 c c c 的公因数,所以 ( a , b ) (a, b) (a,b) b b b c c c 的一个公因数,由性质 4 可得
( a , b ) ∣ ( b , c ) (a, b) \mid (b, c) (a,b)(b,c)
同理可以用 a = b q + c a = bq + c a=bq+c 求得
( b , c ) ∣ ( a , b ) (b, c) \mid (a, b) (b,c)(a,b)
由于 ( a , b ) (a, b) (a,b) ( b , c ) (b, c) (b,c) 相互整除,所以有
( a , b ) = ( b , c ) (a, b) = (b, c) (a,b)=(b,c)
证毕。


2. 欧几里得算法

欧几里得算法,其实就是我们中学学过的辗转相除法,我们先来看一个例子:求 ( 4864 , 3458 ) (4864, 3458) (4864,3458)

我们先用 4864 4864 4864 除以 3458 3458 3458,得到一个商和余数:
4864 = 3458 × 1 + 1406 4864 = 3458\times 1 + 1406 4864=3458×1+1406
由上面我们所证明的性质 5, ( 4864 , 3458 ) (4864, 3458) (4864,3458) 就转换成了求 ( 3458 , 1406 ) (3458, 1406) (3458,1406)

接着我们用 3458 3458 3458 去除 1406 1406 1406,得到新的商和余数:
3458 = 1406 × 2 + 646 3458 = 1406 \times 2 + 646 3458=1406×2+646
现在就转换成了求 ( 1406 , 646 ) (1406, 646) (1406,646)

像这样反复运算,我们的余数最终会变成 0,而我们所算出的最后一个非零余数就是最大公因数。这里的最后一个非零余数是 38 38 38,所以最大公因数是 38 38 38

观察上面的计算过程我们不难发现,这中间的计算方法都是一样的,因此我们可以用递归来实现:

// 求两个数 x 和 y 的最大公因数
int gcd(int x, int y)
{if(y == 0) return x;return gcd(y, x % y);
}

二、最小公倍数 (lcm)

最小公倍数 (Least Common Multiple, 简称 LCM),就是两个或多个数所有公倍数中最小的那个。比如 8 8 8 12 12 12 的最小公倍数是 24 24 24。我们通常把两个数 x x x y y y 的最小公倍数记为 l c m [ x , y ] lcm[x, y] lcm[x,y] 或者 [ x , y ] [x, y] [x,y]

两个数的最小公倍数的求法十分简单,只需要计算出两个数的最大公因数 ( a , b ) (a, b) (a,b),那么就有
[ a , b ] = a × b ( a , b ) [a, b] = \frac{a \times b}{(a, b)} [a,b]=(a,b)a×b


三、练习

1. 最大公因数和最小公倍数 ⭐

【题目链接】

B3634 最大公约数和最小公倍数 - 洛谷

【题目描述】

给定两个正整数 a , b a,b a,b,求他们的最大公约数(gcd)和最小公倍数(lcm)。这两个整数 a , b a,b a,b 均在 int 范围内。

【输入格式】

两个整数 a a a b b b,用空格分隔。

【输出格式】

两个整数表示答案,用空格隔开。

【示例一】

输入

6 15

输出

3 30
#include<iostream>using namespace std;typedef long long LL;// 将 a 和 b 的类型设置为 long long 防止溢出
LL gcd(LL a, LL b)
{return b == 0 ? a : gcd(b, a % b);
}int main()
{LL a, b;cin >> a >> b;LL g = gcd(a, b);cout << g << ' ' <<  a * b / g << endl;return 0;
}

2. 三个数的最大公因数 ⭐

【题目链接】

[B3736 信息与未来 2018] 最大公约数 - 洛谷

【题目描述】

输入三个正整数 x , y , z x,y,z x,y,z,求它们的最大公约数(Greatest Common Divisor) g g g:最大的正整数 g ≥ 1 g ≥1 g1,满足 x , y , z x,y,z x,y,z 都是 g g g 的倍数,即 ( x m o d g ) = ( y m o d g ) = ( z m o d g ) = 0 (x \bmod g) = (y \bmod g) = (z \bmod g) = 0 (xmodg)=(ymodg)=(zmodg)=0

【输入格式】

输入一行三个正整数 x , y , z x,y,z x,y,z

【输出格式】

输出一行一个整数 g g g,表示 x , y , z x,y,z x,y,z 的最大公约数。

【示例一】

输入

12 34 56

输出

2

【示例二】

输入

28 70 28

输出

14

说明/提示

样例 1 1 1

12 = 2 × 6 , 34 = 2 × 17 , 56 = 2 × 28 , g = 2 12 = 2 × 6, 34 = 2 × 17, 56 = 2 × 28, g = 2 12=2×6,34=2×17,56=2×28,g=2

样例 2 2 2

28 = 14 × 2 , 70 = 14 × 5 , 28 = 14 × 2 , g = 14 28 = 14 × 2, 70 = 14 × 5, 28 = 14 × 2,g = 14 28=14×2,70=14×5,28=14×2,g=14

数据规模

所有数据满足 1 ≤ x , y , z ≤ 1 0 6 1 ≤ x,y,z ≤ 10^6 1x,y,z106

本题原始满分为 15 pts 15\text{pts} 15pts


只需算出其中任意两个数的最大公因数,再用这个最大公因数去和另一个数求最大公因数即可。

#include<iostream>using namespace std;int gcd(int x, int y)
{if(y == 0) return x;return gcd(y, x % y);
}int main()
{int x, y, z;cin >> x >> y >> z;cout << gcd(gcd(x, y), z) << endl;return 0;
}

3. 有大整数的最大公因数 ⭐⭐

【题目链接】

小红的 gcd

image-20250906150550547


(1) 补充:秦九韶算法

对于一个 n n n 次多项式:
P ( x ) = a n x n + a n − 1 x n − 1 + ⋯ + a 1 x + a 0 P(x)=a_nx^n+a_{n−1}x^{n−1}+⋯+a_1x+a_0 P(x)=anxn+an1xn1++a1x+a0
可以改写为:
P ( x ) = ( ⋯ ( ( a n x + a n − 1 ) x + a n − 2 ) x + ⋯ + a 1 ) x + a 0 P(x)=(⋯((a_nx+a_{n−1})x+a_{n−2})x+⋯+a_1)x+a_0 P(x)=(((anx+an1)x+an2)x++a1)x+a0
比如
3 × 2 4 + 5 × 2 3 + 6 × 2 2 + 4 × 2 + 1 3 \times2^4 + 5\times 2^3 + 6\times 2^2 + 4 \times 2 + 1 3×24+5×23+6×22+4×2+1
根据秦九韶算法,可以写成
( ( ( 3 × 2 + 5 ) × 2 + 6 ) × 2 + 4 ) × 2 + 1 (((3\times2 + 5)\times2 + 6)\times2 + 4)\times2 + 1 (((3×2+5)×2+6)×2+4)×2+1
时间复杂度为 O ( n ) O(n) O(n)


(2) 解题思路

那么对于这道题来说,由于 a a a 可能非常大,我们只能用 string 字符串来存储它。而我们要计算 ( a , b ) (a, b) (a,b),只需计算 ( b , a m o d b ) (b, a \bmod b) (b,amodb) 即可,问题就转换成了计算 a m o d b a \bmod b amodb。对于一个数字 a a a,比如它是 1234 1234 1234,那么我们可以把它写成
1 × 1 0 3 + 2 × 1 0 2 + 3 × 10 + 4 1\times10^3 + 2\times10^2 + 3\times10 + 4 1×103+2×102+3×10+4
利用秦九韶算法,可以写成
( ( 1 × 10 + 2 ) × 10 + 3 ) × 10 + 4 ((1\times10 + 2)\times10 + 3)\times 10 + 4 ((1×10+2)×10+3)×10+4
这样我们就可以只对数字的每一位进行操作,这符合字符串的操作模式。我们只需从前往后取出每一位的数字,将它乘 10 10 10 再加上后一位,这样一边计算一边取模,最终得到的结果就是 a m o d b a \bmod b amodb 的结果。

#include<iostream>using namespace std;int gcd(int x, int y)
{if(y == 0) return x;return gcd(y, x % y);
}int main()
{string sa;int b;cin >> sa >> b;// 防止 a * 10 溢出long long a = sa[0] - '0';for(int i = 1; i < sa.size(); i++){a = (a * 10 + sa[i] - '0') % b;}cout << gcd(b, a) << endl;return 0;
}
http://www.dtcms.com/a/499269.html

相关文章:

  • rocky linux MariaDB安装过程
  • git的 Rebase
  • 第8篇 QT联合halcon12在vs2019搭建环境开发图像处理
  • 【小白笔记】最大交换 (Maximum Swap)问题
  • CentOS安装Node.js
  • 深入解析MCP:从基础配置到高级应用指南
  • 佛山网站建设服务wordpress 不能更换主题
  • Process Monitor 学习笔记(5.13):从 0 到 1 的排障剧本清单(可复用模板)
  • Fluent 重叠网格+UDF NACA0012翼型摆动气动仿真
  • 深圳网站建设 设计卓越迈wordpress一键采集文章
  • 理想汽车Java后台开发面试题及参考答案(下)
  • python|if判断语法对比
  • 全链路智能运维中的实时流处理架构与状态管理技术
  • 排序算法:详解快速排序
  • 安阳哪里做360网站科技感十足的网站
  • UV 紫外相机在半导体制造领域的应用
  • 突破亚微米光电子器件制造瓶颈!配体交换辅助打印技术实现全打印红外探测器
  • 可见光工业相机半导体制造领域中的应用
  • require和 import是两种不同的模块引入方式的区别
  • 半导体制造工艺基本认识 五 薄膜沉积
  • 矩阵及其应用
  • **发散创新:探索零信任网络下的安全编程实践**随着信息技术的飞速发展,网络安全问题日益凸显。传统的网络安全防护方式已难以
  • 网络营销方案毕业设计安卓手机性能优化软件
  • 建设企业网站价格建设银行北京市财满街分行网站
  • (Kotlin高级特性一)kotlin的扩展函数和属性在字节码层面是如何实现的
  • Spring Boot 3零基础教程,WEB 开发 静态资源默认配置 笔记27
  • 【论文精度-2】求解车辆路径问题的神经组合优化算法:综合展望(Yubin Xiao,2025)
  • 赣州哪里做网站域名注册备案
  • windows双系统下 ubutnu 20.04 启动项出问题无法进入ubuntu 20.04的解决方法
  • MQTT 协议全面学习笔记