Grade 10 · Divide and conquerCitește în română

GCD of an array's elements with divide and conquer

Original: Cmmdc-ul elementelor unui vector prin divide et impera

O(n log n)C++1756 lines2 examples

The idea

The GCD of a portion is the GCD of the left half's GCD and the right half's GCD, because gcd(a, b, c, d) = gcd(gcd(a, b), gcd(c, d)). The base case: a single element. The combine step uses Euclid's algorithm.

Original description (Romanian)

Cmmdc-ul unei porțiuni este cmmdc-ul dintre cmmdc-ul jumătății stângi și cmmdc-ul jumătății drepte, pentru că cmmdc(a, b, c, d) = cmmdc(cmmdc(a, b), cmmdc(c, d)). Cazul elementar: un singur element. Pasul de combinare folosește algoritmul lui Euclid.

Complexity
O(n log M), where M is the largest value
Grade
Grade 10 (Clasa a X-a)

Examples

Example 1

Input

4
12 18 24 30

Expected output

6
Example 2

Input

3
7 14 9

Expected output

1

The code

Comments are in Romanian, as in the original collection. Edit freely: you can reset at any time.

cmmdc-elementelor-unui-vector.cpp
/*
 * Titlu: Cmmdc-ul elementelor unui vector prin divide et impera
 * Clasa: 10
 * Capitol: Divide et impera
 * Descriere: Cmmdc-ul unei porțiuni este cmmdc-ul dintre cmmdc-ul jumătății stângi
 *            și cmmdc-ul jumătății drepte, pentru că cmmdc(a, b, c, d) =
 *            cmmdc(cmmdc(a, b), cmmdc(c, d)). Cazul elementar: un singur element.
 *            Pasul de combinare folosește algoritmul lui Euclid.
 * Complexitate: O(n log M), unde M este cea mai mare valoare
 *
 * Exemplu
 * Intrare:
 * 4
 * 12 18 24 30
 * Ieșire: 6
 *
 * Exemplu
 * Intrare:
 * 3
 * 7 14 9
 * Ieșire: 1
 */
#include <iostream>
using namespace std;

int v[1000];

int cmmdc(int a, int b)
{
    while (b != 0)
    {
        int r = a % b;
        a = b;
        b = r;
    }
    return a;
}

int cmmdcVector(int st, int dr)
{
    if (st == dr)
        return v[st];
    int m = (st + dr) / 2;
    return cmmdc(cmmdcVector(st, m), cmmdcVector(m + 1, dr));
}

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> v[i];
    cout << cmmdcVector(0, n - 1) << '\n';
    return 0;
}

Runs on a real g++ (C++17, -O2) through Compiler Explorer. Keep runs short; there's a time limit.