Lesson 21 of 50 intermediate

GCD and LCM — Number Best Friends

Master the greatest common divisor and least common multiple — they show up EVERYWHERE in CP!

Open interactive version (quiz + challenge)

Real-world analogy

Imagine you have 24 cookies and 36 candies, and you want to put them into identical gift bags with no leftovers. The biggest number of bags you can make is the GCD (Greatest Common Divisor) of 24 and 36, which is 12. You would put 2 cookies and 3 candies in each bag. Now imagine two gears — one turns every 8 seconds, another every 12 seconds. When do they first line up again? That is the LCM (Least Common Multiple) of 8 and 12, which is 24 seconds. GCD and LCM are like best friends — they always help each other!

What is it?

GCD (Greatest Common Divisor) is the largest positive integer that divides two numbers without a remainder. LCM (Least Common Multiple) is the smallest positive integer that is divisible by both numbers. They are connected by the formula LCM(a,b) = a*b/GCD(a,b). Euclid's Algorithm computes GCD efficiently in O(log(min(a,b))) time.

Real-world relevance

GCD is used to simplify fractions (12/18 simplifies to 2/3 by dividing both by GCD=6), schedule events that repeat at different intervals, tile floors with the largest possible square tiles, and even in cryptography (RSA encryption uses GCD). LCM tells you when traffic lights will all be green at the same time, or when multiple bus routes will arrive simultaneously.

Key points

Code example

#include <bits/stdc++.h>
using namespace std;

// GCD using Euclid's algorithm (recursive)
int gcd(int a, int b) {
    if (b == 0) return a;
    return gcd(b, a % b);
}

// LCM using GCD (divide first to avoid overflow)
long long lcm(int a, int b) {
    return (long long)a / gcd(a, b) * b;
}

int main() {
    int a, b;
    cin >> a >> b;
    
    cout << "GCD of " << a << " and " << b << ": " << gcd(a, b) << endl;
    cout << "LCM of " << a << " and " << b << ": " << lcm(a, b) << endl;
    
    // Simplify a fraction
    int num = a, den = b;
    int g = gcd(num, den);
    cout << "Fraction " << num << "/" << den << " simplifies to ";
    cout << num / g << "/" << den / g << endl;
    
    // GCD of an array
    int n;
    cin >> n;
    int arr[n];
    for (int i = 0; i < n; i++) cin >> arr[i];
    
    int arrayGCD = arr[0];
    long long arrayLCM = arr[0];
    for (int i = 1; i < n; i++) {
        arrayGCD = gcd(arrayGCD, arr[i]);
        arrayLCM = arrayLCM / gcd((int)arrayLCM, arr[i]) * arr[i];
    }
    
    cout << "GCD of array: " << arrayGCD << endl;
    cout << "LCM of array: " << arrayLCM << endl;
    
    return 0;
}

Line-by-line walkthrough

  1. 1. int gcd(int a, int b) { if (b == 0) return a; return gcd(b, a % b); } — This is Euclid's algorithm. If b is 0, the GCD is a. Otherwise, the GCD of a and b equals the GCD of b and the remainder of a/b. For GCD(48,18): GCD(18,12) → GCD(12,6) → GCD(6,0) → 6.
  2. 2. long long lcm(int a, int b) { return (long long)a / gcd(a, b) * b; } — We divide a by gcd first (which always divides evenly) before multiplying by b. This prevents overflow. The cast to long long ensures we have enough room.
  3. 3. int g = gcd(num, den); ... num/g ... den/g — To simplify a fraction, divide both numerator and denominator by their GCD. For 12/18: GCD=6, so 12/6=2 and 18/6=3. Result: 2/3.
  4. 4. arrayGCD = gcd(arrayGCD, arr[i]); — To find the GCD of many numbers, use chaining: GCD(a,b,c) = GCD(GCD(a,b), c). Start with the first element, then fold in each subsequent element.
  5. 5. arrayLCM = arrayLCM / gcd((int)arrayLCM, arr[i]) * arr[i]; — Same chaining for LCM, using the formula LCM(a,b) = a/gcd(a,b)*b at each step.

Spot the bug

#include <bits/stdc++.h>
using namespace std;

int gcd(int a, int b) {
    if (b == 0) return a;
    return gcd(b, a % b);
}

int main() {
    int a, b;
    cin >> a >> b;
    int result = a * b / gcd(a, b);
    cout << "LCM: " << result << endl;
    return 0;
}
Need a hint?
What if a and b are both around 100,000? What happens when you compute a * b before dividing? Also, what is the type of result?
Show answer
Two bugs! First, a * b can overflow int when a and b are large (e.g., 100000 * 100000 = 10 billion, way beyond int's 2 billion limit). Second, even if it does not overflow, we should divide first: a / gcd(a,b) * b. Fix: long long result = (long long)a / gcd(a, b) * b; This divides first (which is safe because gcd always divides a evenly) and uses long long to hold the result.

Explain like I'm 5

GCD is like this: imagine you have 12 apples and 8 oranges, and you want to put them in bags so every bag has the same number of apples AND the same number of oranges, with nothing left over. The most bags you can make is 4 (the GCD). Each bag gets 3 apples and 2 oranges! LCM is different: if one friend visits every 3 days and another visits every 4 days, they will both visit on the same day every 12 days (the LCM).

Fun fact

Euclid's Algorithm was described by the Greek mathematician Euclid around 300 BC in his book 'Elements'. It is one of the oldest algorithms still in use today — over 2,300 years old! And it is incredibly efficient: for two numbers up to 1 billion, it takes at most about 45 steps. The algorithm is a perfect example of how a simple idea can be incredibly powerful.

Hands-on challenge

Read two numbers a and b. Print their GCD and LCM. Then read a fraction (numerator and denominator) and print it in its simplest form. For example, if the fraction is 8/12, print 2/3. Bonus: read n numbers and find the GCD and LCM of all of them.

More resources

Open interactive version (quiz + challenge) ← Back to course: CP Zero to Hero