Sari la conținut
EduCamp

Probleme rezolvate pe categorii

Divizibilitate

10 probleme Date la Definitivat și Titularizare în 2024. Bacalaureat: 1Exerciții: 8

Înainte de probleme Tiparul problemelor de divizibilitate

Problemele de divizibilitate s-au dat la examenul de Definitivat în 2024 și la bacalaureat în 2023. În problemele din tabelul de mai jos se cere un subprogram care lucrează pe un singur număr sau pe o pereche de numere, iar programul principal aplică subprogramul tuturor numerelor citite.

ProblemaCe face subprogramulCe face programul
k-perechi de numere consecutive (Definitivat 2024)numără divizorii unui numărnumără perechile de numere consecutive cu câte k divizori
Număr abundent (bacalaureat 2023)calculează suma divizorilorcompară raportul S(n)/n cu rapoartele numerelor mai mici
Un număr par scris ca sumă de două numere primeverifică dacă un număr este primscrie un număr par ca sumă de două numere prime
Numerele prime găsite cu suma divizorilor propriicalculează suma divizorilor propriiafișează în ordine crescătoare numerele prime
Perechi de numere prime între elecalculează cel mai mare divizor comunafișează perechile de numere prime între ele
Numerele prime în ordine inversă citiriiverifică dacă un număr este primafișează numerele prime în ordine inversă citirii
Fracții ireductibile și numitorul comuncalculează cel mai mare divizor comunsimplifică fracții și calculează numitorul comun
Numerele perfecte dintr-un fișierverifică dacă un număr este perfectafișează descrescător numerele perfecte

Prelucrările de bază de mai jos se scriu de fiecare dată la fel.

Divizorii unui număr

Un număr natural d este divizor al lui n dacă restul împărțirii lui n la d este 0, adică n % d == 0. Divizorii lui n se grupează în perechi: dacă d este divizor, atunci și n/d este divizor. Pentru n = 36:

d12346
n/d36181296

Din fiecare pereche, divizorul mai mic este cel mult egal cu rădăcina pătrată a lui n. De aceea divizorii se caută numai pentru d de la 1 până când d·d depășește n, iar pentru fiecare divizor găsit se numără și perechea lui, n/d. Când n este pătrat perfect, d și n/d sunt egali pentru d = 6, iar divizorul se numără o singură dată. Lui 36 îi corespund astfel 9 divizori.

Pentru n = 10⁶, căutarea până la rădăcina pătrată face 1000 de împărțiri, în loc de 500 000 cât ar face căutarea până la n/2.

Divizorii proprii ai lui n sunt divizorii diferiți de 1 și de n. Divizorii 1 și n se numesc improprii.

Numărul prim

Un număr natural este prim dacă este mai mare decât 1 și are exact doi divizori: 1 și el însuși. Pentru verificare se caută un divizor d cu 2 ≤ d și d·d ≤ n:

  • dacă se găsește un astfel de divizor, numărul nu este prim;
  • dacă nu se găsește niciunul, numărul este prim.

Numerele 0 și 1 nu sunt prime și se tratează separat, la începutul subprogramului.

Cel mai mare divizor comun

Cel mai mare divizor comun al numerelor a și b, notat (a, b) sau cmmdc(a, b), este cel mai mare număr natural care îl divide atât pe a, cât și pe b. Dacă cmmdc(a, b) = 1, numerele a și b sunt prime între ele.

Algoritmul lui Euclid cu împărțiri se bazează pe faptul că orice divizor comun al lui a și b divide și restul împărțirii lui a la b. Pașii algoritmului sunt:

  • se calculează r, restul împărțirii lui a la b;
  • a primește valoarea lui b, iar b primește valoarea lui r;
  • cât timp b este diferit de 0, se reia de la primul pas;
  • la oprire, cmmdc este valoarea lui a.

Pentru a = 504 și b = 60:

abr = a % b
5046024
602412
24120
120—

Cel mai mare divizor comun este 12.

Algoritmul lui Euclid cu scăderi se bazează pe faptul că divizorii comuni ai lui a și b divid și diferența lor. Cât timp a ≠ b, din numărul mai mare se scade numărul mai mic; la oprire, a = b este cmmdc. Varianta cu scăderi face mai mulți pași: pentru 1000 și 1 face 999 de scăderi, iar varianta cu împărțiri face un singur pas.

Cel mai mic multiplu comun

Cel mai mic multiplu comun al numerelor nenule a și b, notat [a, b] sau cmmmc(a, b), este cel mai mic număr natural nenul care se divide atât cu a, cât și cu b. Între cele două valori există relația:

cmmdc(a, b) · cmmmc(a, b) = a · b

deci cmmmc(a, b) = a · b / cmmdc(a, b). Pentru 504 și 60, cmmmc = 504 · 60 / 12 = 2520.

Descompunerea în factori primi

Orice număr natural n ≥ 2 se scrie ca produs de numere prime, fiecare la o anumită putere, iar scrierea este unică. Pentru n = 880:

Problema 1 · Definitivat 2024 · Subiectul I.3 · 15 puncte k-perechi de numere consecutive

Cerința este rezolvată și pe pagina subiectului: k-perechi de numere consecutive.

Ce cere problema

Două numere consecutive, i și i + 1, formează o k-pereche dacă amândouă au exact k divizori. În intervalul [22, 80], pentru k = 4:

PerecheaDivizorii primului numărDivizorii celui de-al doilea număr
26 și 271, 2, 13, 261, 3, 9, 27
33 și 341, 3, 11, 331, 2, 17, 34
34 și 351, 2, 17, 341, 5, 7, 35
38 și 391, 2, 19, 381, 3, 13, 39
57 și 581, 3, 19, 571, 2, 29, 58

Intervalul este delimitat de x și y, care pot fi date în orice ordine: în primul exemplu x = 80 și y = 22. Ambele numere ale perechii trebuie să fie în interval, deci primul număr al perechii merge de la capătul mic până la capătul mare minus 1.

Programul și descrierea metodei

În stânga sunt subprogramul și programul principal, așa cum se scriu pe foaia de examen. În dreapta este metoda de rezolvare, descrisă în limbaj natural, cu pașii așezați pe niveluri după structura programului.

#include <iostream>
#include <fstream>
using namespace std;

/* Numarul divizorilor lui n: divizorii se cauta
   pana la radacina patrata, cu perechea lor n/d. */
int nrDiv(int n) {
    int nr = 0;
    for (int d = 1; d * d <= n; d++)
        if (n % d == 0) {
            nr++;              // divizorul d
            if (d != n / d)
                nr++;          // divizorul n/d
        }
    return nr;
}

Subprogramul nrDiv(n)

  • nr pornește de la 0
  • pentru d de la 1, cât timp d·d ≤ n
    • dacă d îl divide pe n
      • se numără divizorul d
      • dacă n/d este diferit de d, se numără și divizorul n/d
  • se returnează nr

Pentru n = 27 se găsesc 1 cu perechea 27 și 3 cu perechea 9, deci se returnează 4. Căutarea face cel mult 1000 de pași, deoarece 1000 · 1000 = 10⁶.

int main() {
    ifstream f("def2024.in");
    int k, x, y;
    f >> k >> x >> y;
    f.close();

    if (x > y) {               // capetele, in ordine
        int aux = x;
        x = y;
        y = aux;
    }

    int nr = 0;
    int dCurent = nrDiv(x);    // divizorii lui i
    for (int i = x; i < y; i++) {
        int dUrm = nrDiv(i + 1);   // divizorii lui i+1
        if (dCurent == k && dUrm == k)
            nr++;
        dCurent = dUrm;
    }

    cout << nr;
    return 0;
}

Programul principal

  • se citesc din fișier k, x și y
  • dacă x > y, valorile lui x și y se interschimbă, astfel încât intervalul să fie [x, y]
  • dCurent primește numărul divizorilor lui x
  • pentru i de la x la y − 1
    • dUrm primește numărul divizorilor lui i + 1
    • dacă dCurent și dUrm sunt egale cu k, i și i + 1 formează o k-pereche și se numără
    • dCurent primește dUrm: numărul i + 1 devine primul număr al perechii următoare
  • se afișează numărul perechilor

Fiecare număr din interval trece o singură dată prin nrDiv.

Problema 2 · Bacalaureat 2023 · Subiectul III.1 · 10 puncte Număr abundent

Ce cere problema

S(i) este suma tuturor divizorilor lui i, inclusiv 1 și i. Pentru numerele de la 1 la 8:

iDivizoriiS(i)S(i)/i
1111
21, 231.5
31, 341.33
41, 2, 471.75
51, 561.2
61, 2, 3, 6122
71, 781.14
81, 2, 4, 8151.87

Numărul n este abundent dacă raportul lui este strict mai mare decât raportul fiecărui număr mai mic. Pentru 6, raportul 2 este mai mare decât toate rapoartele din rândurile de deasupra. Pentru 8, raportul 1.87 este mai mic decât raportul lui 6.

Rapoartele nu se calculează cu împărțiri, deoarece valorile reale pot fi rotunjite. Ambele numere sunt pozitive, deci inegalitatea S(n)/n ≤ S(k)/k se scrie echivalent S(n) · k ≤ S(k) · n.

Programul și descrierea metodei

În stânga sunt subprogramul și programul principal, scrise în C++. În dreapta este metoda de rezolvare, descrisă în limbaj natural, cu pașii așezați pe niveluri după structura programului.

Problema 3 · Exercițiu Un număr par scris ca sumă de două numere prime

Ce cere problema

Pentru fiecare număr par mai mare decât 2 se caută două numere prime cu suma egală cu el. Se încearcă a = 2, 3, 4, … până când atât a, cât și n − a sunt prime:

na încercatn − aAmbele prime?
18216nu, 16 nu este prim
18315nu, 15 nu este prim
18414nu, 4 nu este prim
18513da: 18 = 5 + 13
422da: 4 = 2 + 2

Numerele impare din fișier nu se prelucrează. Pentru toate numerele pare cu cel mult 4 cifre există o astfel de scriere, deci căutarea se oprește întotdeauna.

Programul și descrierea metodei

În stânga sunt subprogramul de la punctul a) și programul principal de la punctul b). În dreapta este metoda de rezolvare, descrisă în limbaj natural, cu pașii așezați pe niveluri după structura programului.

Problema 4 · Exercițiu Numerele prime găsite cu suma divizorilor proprii

Ce cere problema

Divizorii proprii ai lui n sunt divizorii lui diferiți de 1 și de n. Un număr prim nu are divizori proprii, deci suma lor este 0:

nDivizorii propriiSumaEste prim?
422nu
103—0da
59—0da
23—0da
79—0da
3—0da
100317, 5976nu

Suma este 0 și pentru 0 și 1, care nu sunt prime. De aceea un număr n este prim dacă n > 1 și suma divizorilor lui proprii este 0. Numerele prime se afișează în ordine crescătoare: 3 23 59 79 103.

Programul și descrierea metodei

În stânga sunt subprogramul de la punctul a) și programul principal de la punctul b). În dreapta este metoda de rezolvare, descrisă în limbaj natural, cu pașii așezați pe niveluri după structura programului.

Problema 5 · Exercițiu Perechi de numere prime între ele

Ce cere problema

Două numere sunt prime între ele dacă cel mai mare divizor comun al lor este 1. Se verifică fiecare pereche de numere de pe al doilea rând. Câteva perechi din exemplu:

PerecheaDivizorii primuluiDivizorii celui de-al doileacmmdcPrime între ele?
4 și 91, 2, 41, 3, 91da
4 și 101, 2, 41, 2, 5, 102nu
9 și 101, 3, 91, 2, 5, 101da
10 și 151, 2, 5, 101, 3, 5, 155nu

În pereche, numărul mai mic se scrie primul, deoarece enunțul cere a < b. Două numere egale nu formează o pereche cu a < b, deci nu se afișează.

Programul și descrierea metodei

În stânga sunt subprogramul de la punctul a) și programul principal de la punctul b). În dreapta este metoda de rezolvare, descrisă în limbaj natural, cu pașii așezați pe niveluri după structura programului.

Problema 6 · Exercițiu Numerele prime în ordine inversă citirii

Ce cere problema

Numerele din fișier se împart în prime și neprime:

Numărul citit1267542911
Este prim?nunudadanudanuda

Numerele prime formează, în ordinea citirii, șirul 7 5 2 11. În ordine inversă se afișează 11 2 5 7. În fișier sunt 4 numere neprime, deci pe rândul al doilea se afișează 4.

Programul și descrierea metodei

În stânga sunt subprogramul și programul principal. În dreapta este metoda de rezolvare, descrisă în limbaj natural, cu pașii așezați pe niveluri după structura programului.

Problema 7 · Exercițiu Fracții ireductibile și numitorul comun

Ce cere problema

O fracție se aduce la forma ireductibilă împărțind numărătorul și numitorul la cel mai mare divizor comun al lor:

Fracția citităcmmdcForma ireductibilă
12/36121/3
49/7077/10
35/4057/8
25/7055/14
1/311/3

Numitorul comun al fracțiilor ireductibile este cel mai mic multiplu comun al numitorilor din ultima coloană a tabelului, adică 840. Cel mai mic multiplu comun se calculează din cel mai mare divizor comun: cmmmc(a, b) = a / cmmdc(a, b) · b.

Programul și descrierea metodei

În stânga sunt subprogramul de la punctul a) și programul principal de la punctul b). În dreapta este metoda de rezolvare, descrisă în limbaj natural, cu pașii așezați pe niveluri după structura programului.

Problema 8 · Exercițiu Numerele perfecte dintr-un fișier

Ce cere problema

Un număr natural este perfect dacă este egal cu suma divizorilor săi diferiți de el însuși:

nDivizorii mai mici decât nSumaEste perfect?
61, 2, 36da
711nu
281, 2, 4, 7, 1428da
141, 2, 710nu

Tot perfecte sunt 496 și 8128. Primul număr din fișier, 6, arată câte numere urmează.

Programul și descrierea metodei

În stânga sunt subprogramul și programul principal. În dreapta este metoda de rezolvare, descrisă în limbaj natural, cu pașii așezați pe niveluri după structura programului.

#include <iostream>
#include <fstream>
using namespace std;

/* Returneaza n daca n este perfect, 0 altfel. */
int perfect(int n) {
    if (n < 2)
        return 0;
    int s = 1;                 // divizorul propriu 1
    for (int d = 2; d * d <= n; d++)
        if (n % d == 0) {
            s = s + d;
            if (d != n / d)
                s = s + n / d;
        }
    if (s == n)
        return n;
    return 0;
}

Subprogramul perfect(n)

  • 0 și 1 nu sunt perfecte: se returnează 0
  • s pornește de la 1, deoarece 1 este divizor al oricărui n ≥ 2
  • pentru d de la 2, cât timp d·d ≤ n
    • dacă d îl divide pe n
      • d se adună la s
      • dacă n/d este diferit de d, se adună și n/d
  • dacă s este egal cu n, se returnează n; altfel se returnează 0

Căutarea începe de la 2, deci divizorul n, pereche a lui 1, nu se adună.

int v[301];

int main() {
    ifstream f("nr17.txt");
    int n, x, k = 0;
    f >> n;
    for (int i = 1; i <= n; i++) {
        f >> x;
        if (perfect(x) != 0) {
            k++;
            v[k] = x;
        }
    }
    f.close();

    if (k == 0) {
        cout << "NU EXISTA";
        return 0;
    }

    /* ordonare descrescatoare */
    for (int i = 1; i < k; i++)
        for (int j = i + 1; j <= k; j++)
            if (v[i] < v[j]) {
                int aux = v[i];
                v[i] = v[j];
                v[j] = aux;
            }

    for (int i = 1; i <= k; i++)
        cout << v[i] << " ";
    return 0;
}

Programul principal

  • se citește n, numărul de valori din fișier
  • pentru fiecare dintre cele n valori x
    • dacă perfect(x) este diferit de 0, k crește cu 1 și x se memorează în v[k]
  • dacă k este 0, se afișează NU EXISTA și programul se încheie
  • vectorul se ordonează descrescător
    • pentru fiecare poziție i, se compară v[i] cu fiecare element de după el
    • dacă un element de după el este mai mare, cele două se interschimbă
  • se afișează elementele vectorului

Problema 9 · Exercițiu Divizorii unui număr în ordine crescătoare

Ce cere problema

Divizorii lui 12 se grupează în perechi d și 12/d:

d123
12/d1264

Divizorii din primul rând sunt mai mici decât rădăcina pătrată a lui 12 și cresc. Perechile lor, din al doilea rând, scad. Ordinea crescătoare se obține astfel:

  • se afișează divizorii d din primul rând, de la stânga la dreapta;
  • se afișează perechile n/d, de la dreapta la stânga.

Când n este pătrat perfect, rădăcina lui este divizor fără pereche și se afișează între cele două grupe. Pentru 36 se afișează 1 2 3 4, apoi 6, apoi 9 12 18 36.

Programul și descrierea metodei

În stânga este programul. În dreapta este metoda de rezolvare, descrisă în limbaj natural, cu pașii așezați pe niveluri după structura programului.

Problema 10 · Exercițiu Descompunerea în factori primi

Ce cere problema

Orice număr natural n ≥ 2 se scrie ca produs de numere prime la anumite puteri. Pentru câteva valori:

nDescompunereaCe se afișează
202² · 5¹2^2, 5^1
902¹ · 3² · 5¹2^1, 3^2, 5^1
8802⁴ · 5¹ · 11¹2^4, 5^1, 11^1
77¹7^1

Divizorii primi se afișează în ordine crescătoare, separați prin virgulă și spațiu.

Programul și descrierea metodei

În stânga sunt subprogramul și programul principal. În dreapta este metoda de rezolvare, descrisă în limbaj natural, cu pașii așezați pe niveluri după structura programului.

#include <iostream>
using namespace std;

/* Afiseaza factorii primi ai lui n, cu puterile lor. */
void descompunere(int n) {
    int primul = 1;    // 1 cat timp nu s-a afisat nimic
    for (int d = 2; d * d <= n; d++) {
        int p = 0;
        while (n % d == 0) {
            n = n / d;
            p++;
        }
        if (p > 0) {
            if (primul == 0)
                cout << ", ";
            cout << d << "^" << p;
            primul = 0;
        }
    }
    if (n > 1) {       // a ramas un factor prim
        if (primul == 0)
            cout << ", ";
        cout << n << "^1";
    }
}

Subprogramul descompunere(n)

  • primul are valoarea 1 cât timp nu s-a afișat niciun factor
  • pentru d de la 2, cât timp d·d ≤ n
    • p, puterea lui d, pornește de la 0
    • cât timp d îl divide pe n, n se împarte la d și p crește cu 1
    • dacă p > 0
      • dacă s-a afișat deja un factor, se afișează virgula și spațiul
      • se afișează d, semnul ^ și p
      • primul devine 0
  • dacă n > 1, valoarea rămasă este un factor prim, la puterea 1
    • se afișează, precedată de virgulă dacă nu este primul factor

Un divizor d găsit astfel este prim: factorii primi mai mici decât el au fost deja eliminați din n.

int main() {
    int n;
    cin >> n;
    descompunere(n);
    return 0;
}

Programul principal

  • se citește n
  • se apelează subprogramul descompunere(n)

Materialul acesta se citește pe educamp.ro și nu se tipărește.

Vezi problemele rezolvate ca și cursant

Lista categoriilor, cu problemele date la examen în fiecare, se citește gratuit și integral. Pentru a citi rezolvările, te înscrii la cursul de pregătire.

Te înscrii, alegi în cont când începe cursul și plătești prima lună prin transfer bancar. Pentru a vedea mai întâi ce probleme s-au dat, poți reveni la lista categoriilor.

Acces la suportul de curs

25 RON / lună, fără ședințe

Ce cuprinde:

  • Acces la toate lecțiile disponibile
  • Suport de curs pentru tematica științifică și metodică
  • Exemple, explicații și exerciții
  • Acces la materialele noi adăugate pe platformă
  • Posibilitatea de a adresa întrebări

Înscrie-te Cum plătești Login