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
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)
- Chapter
- Divide and conquer
Examples
Input
4 12 18 24 30
Expected output
6
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.
/*
* 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.