🧩

最大公约数与最小公倍数

GCD = 两个数"共同的最大玩具";LCM = 两人约好"第一次同时到达"的时刻

💡 打个比方

12 和 18 一起玩积木。它们都能整除的数叫"公约数":1、2、3、6。其中最大的是 6,这就是最大公约数(GCD)——两个数共同的最大玩具。

再看公交:12 路车每隔 12 分钟一班,18 路车每隔 18 分钟一班,它们"同时发车"的时刻是 36、72、108……最早一次就是 36,这就是最小公倍数(LCM)。

两个数共有的因数叫公约数,最大的那个叫最大公约数 GCD;两个数共有的倍数叫公倍数,最小的那个叫最小公倍数 LCM。

🖼️ 大图看明白

12 的因数(能整除 12 的朋友) 1 2 3 4 6 12 18 的因数(能整除 18 的朋友) 1 2 3 6 9 18 两边都绿色(公约数):1、2、3、6 GCD(12, 18) = 6 ⭐ 12 的倍数(从 12 开始跳着数) 12 24 36 48 18 的倍数(从 18 开始跳着数) 18 36 54 72 两边都绿色(公倍数):36、72…… LCM(12, 18) = 36 ⭐ 万能公式:LCM = a ÷ GCD × b 12 ÷ 6 × 18 = 36 —— 先除后乘,防止数字大时"装不下"(溢出)!

📏 求 GCD 和 LCM,只要 3 步

  1. 第 1 步:从 min(a, b) 开始往下试,找第一个能同时整除 a 和 b 的数。
  2. 第 2 步:第一个找到的就是最大公约数(因为从大到小试)。
  3. 第 3 步:LCM = a ÷ GCD × b(先除后乘)。
为什么"先除后乘"?a × b 可能大得超过 int 的范围(溢出),而 a ÷ GCD 一定 ≤ a,先除一步就把数字缩小了,再乘就安全了。

💻 C++ 怎么写

// 从大到小找第一个能同时整除 a 和 b 的数
int gcd(int a, int b) {
    for (int i = min(a, b); i >= 1; i--) {
        if (a % i == 0 && b % i == 0)
            return i;   // 从大到小试,第一个就是最大的
    }
    return 1;
}

int main() {
    int a, b;
    cin >> a >> b;
    int g = gcd(a, b);
    cout << "GCD = " << g << "\n";
    cout << "LCM = " << a / g * b << "\n";  // 先除后乘,防溢出
    return 0;
}

✋ 你来试试

题目 1:gcd(24, 36) 和 lcm(24, 36) 各是多少?
24 的因数:1,2,3,4,6,8,12,24;36 的因数:1,2,3,4,6,9,12,18,36。最大公约数是 12。LCM = 24 ÷ 12 × 36 = 72。(验证:72 = 24×3 = 36×2 ✓)
题目 2:如果 gcd(a, b) = 1,我们怎么说?举例说明。
a 和 b 除了 1 以外没有别的公约数,叫互质(互素)。例如 gcd(8, 9) = 1,所以 8 和 9 互质。注意互质不要求各自是素数:6 和 35 也互质(6=2×3,35=5×7,没有公共因数)。
🎯 一句话记住:GCD 是"共同因数里最大的";LCM = a ÷ GCD × b,先除后乘不溢出;gcd = 1 叫互质。