Ce înseamnă "Sume și produse complexe"?
După această lecție, vei ști să rezolvi probleme care cer mai multe calcule simultan într-un singur algoritm.
Recapitulare rapidă: Sume și produse simple
Ce știm deja din lecțiile anterioare:
Atenție la inițializări!
Regulă de aur: Dacă uitați să inițializați corect variabilele, programul va da rezultate greșite!
int suma = 0; pentru că 0 este elementul neutru la adunare
int produs = 1; pentru că 1 este elementul neutru la înmulțire
int produs = 0; pentru că orice înmulțit cu 0 dă 0!
Analogie: Bucătarul care prepară mai multe feluri de mâncare
Gândește-te la un algoritm complex ca la un bucătar care prepară simultan mai multe feluri de mâncare:
Pregătește doar o singură mâncare
→ algoritm cu un singur calculPregătește supă, fel principal și desert
→ algoritm cu multiple calculeFiecare fel are ingrediente proprii
→ fiecare calcul are variabile propriiToate se gătesc în același timp
→ toate calculele în aceeași buclăAlgoritmul pentru calcule combinate
Declară toate variabilele necesare
Pentru fiecare rezultat de care ai nevoie, creează o variabilă separată.
produsImpare = 1
Parcurge numerele (de obicei cu for/while)
Folosește o singură buclă pentru a parcurge toate numerele.
Pentru fiecare număr, decide ce calcule faci
Folosește condiții (if) pentru a alege în ce variabilă adaugi numărul.
else produsImpare*=i
Afișează toate rezultatele
După buclă, afișează toate variabilele cu rezultatele finale.
Observație importantă: Folosim o singură buclă PENTRU pentru a parcurge numerele, dar în interior facem calcule diferite în funcție de paritatea lui i. Asta face algoritmul eficient!
produsImpare = 1
❌ NU → produsImpare = 1×1 = 1
✅ DA → sumaPare = 0+2 = 2
❌ NU → produsImpare = 1×3 = 3
✅ DA → sumaPare = 2+4 = 6
❌ NU → produsImpare = 3×5 = 15
sumaPare = 6
produsImpare = 15
Exercițiu de completare - Calcul combinat:
Completează codul C++ pentru suma pătratelor și produsul cuburilor:
Bancă de cuvinte:
Test de înțelegere: Care variabilă pentru care calcul?
Pentru problema: "Pentru numerele de la 1 la n, calculează suma numerelor divizibile cu 3 și produsul numerelor divizibile cu 5"
Cum ar trebui să inițializezi variabilele?
Știai că...
Capcane comune și soluții pentru calcule complexe
Greșeli frecvente la sume și produse multiple:
Soluție: Memorizează: suma = 0, produs = 1
Exemplu: rezultat = rezultat + i pentru sumă, apoi rezultat = rezultat * i pentru produs
Soluție: Folosește variabile separate: sumaPare, produsImpare
Un număr poate să îndeplinească mai multe condiții (ex: divizibil cu 3 și cu 5)
Best Practices pentru calcule complexe:
sumaPare, produsImpare, numarDivizori
Comparație operații în aceeași buclă vs. bucle separate:
for(i=1; i<=n; i++) if(cond2) calc2;
Sfat pentru profesor: Încurajați elevii să scrie pe hârtie toate variabilele de care au nevoie înainte să scrie codul. Această etapă de planificare evită multe greșeli!
PbInfo #7 - Suma și produsul
Enunț:
Cerință: Se citește un număr natural n. Să se calculeze suma numerelor pare și produsul numerelor impare de la 1 la n.
Date de intrare:
Programul citește de la tastatură numărul n.
Date de ieșire:
Programul va afișa pe ecran, separate printr-un spațiu, suma numerelor pare și produsul numerelor impare.
Exemplu:
Intrare:
5
Ieșire:
6 15
Explicație: Pare: 2+4=6, Impare: 1×3×5=15
Cum gândim soluția:
- Citim numărul n
- Declarăm și inițializăm două variabile:
sumaPare = 0(pentru suma numerelor pare)produsImpare = 1(pentru produsul numerelor impare)
- Parcurgem numerele de la 1 la n cu o buclă for
- Pentru fiecare număr i:
- Dacă i este par (
i % 2 == 0): adăugăm lasumaPare - Altfel (i este impar): înmulțim la
produsImpare
- Dacă i este par (
- Afișăm cele două rezultate separate prin spațiu
Execuție pentru n=5:
Ce trebuie să verifici mereu?
- n=1: sumaPare=0 (niciun număr par), produsImpare=1
- n=2: sumaPare=2, produsImpare=1
- n=0: Atenție! Intervalul este de la 1 la n, deci pentru n=0, bucla nu se execută
- Inițializări: suma începe cu 0, produsul cu 1
Scrie soluția în C++:
Soluție corectă:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int sumaPare = 0; // Inițializare corectă pentru sumă
int produsImpare = 1; // Inițializare corectă pentru produs
for (int i = 1; i <= n; i++) {
if (i % 2 == 0) {
// Număr par - adăugăm la sumă
sumaPare += i;
} else {
// Număr impar - înmulțim la produs
produsImpare *= i;
}
}
// Afișăm rezultatele separate prin spațiu
cout << sumaPare << " " << produsImpare;
return 0;
}
Ce învățăm din această problemă:
- Variabile multiple: Fiecare calcul are variabila sa
- Inițializări diferite: sume cu 0, produse cu 1
- O singură buclă: Eficient - parcurgem numerele o singură dată
- Condiții exclusive: Un număr fie este par, fie este impar
- Format output: Rezultate separate prin spațiu, în ordinea cerută
Varianta cu verificare suplimentară:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int sumaPare = 0;
int produsImpare = 1;
// Verificăm dacă n este mai mare decât 0
if (n <= 0) {
cout << "0 1"; // pentru n=0 sau negativ
return 0;
}
for (int i = 1; i <= n; i++) {
if (i % 2 == 0) {
sumaPare += i;
} else {
produsImpare *= i;
}
}
cout << sumaPare << " " << produsImpare;
return 0;
}
PbInfo #8 - Trei calcule simultan
Problemă cu trei rezultate diferite într-un singur algoritm
Enunț:
Cerință: Se citește un număr natural n. Să se calculeze:
- Suma numerelor divizibile cu 3 de la 1 la n
- Produsul numerelor divizibile cu 5 de la 1 la n
- Numărul de valori care nu sunt divizibile nici cu 3, nici cu 5
Date de intrare:
Programul citește de la tastatură numărul n.
Date de ieșire:
Programul va afișa pe ecran, separate prin spațiu, cele trei rezultate în ordinea de mai sus.
Exemplu:
Intrare:
10
Ieșire:
18 5 4
Explicație: Divizibile cu 3: 3+6+9=18, Divizibile cu 5: 5, Nici cu 3 nici cu 5: 1,2,4,7=4 numere
Cum gândim soluția:
- Citim numărul n
- Declarăm și inițializăm trei variabile:
sumaDiv3 = 0produsDiv5 = 1contor = 0(pentru numărarea celor nedivizibile)
- Parcurgem numerele de la 1 la n cu o buclă for
- Pentru fiecare număr i:
- Dacă
i % 3 == 0: adăugăm lasumaDiv3 - Dacă
i % 5 == 0: înmulțim laprodusDiv5 - Dacă
i % 3 != 0 && i % 5 != 0: incrementămcontor
Important: Un număr poate să fie divizibil atât cu 3, cât și cu 5 (ex: 15). În acest caz, intră în ambele calcule!
- Dacă
- Afișăm cele trei rezultate în ordinea cerută
Cum funcționează pentru n=10:
Atenție la exemplul din problemă: Există o discrepanță între exemplul dat (18 5 4) și rezultatul logic (18 50 4). Verifică întotdeauna algoritmul tău cu propriile calcule!
De ce această problemă este importantă?
Problema exersează gândirea algoritmică complexă:
- Mai multe condiții independente: Un număr poate să îndeplinească 0, 1 sau 2 condiții
- Tipuri diferite de calcule: sumă, produs, numărare
- Condiții compuse:
!(i%3==0 || i%5==0)este echivalent cui%3!=0 && i%5!=0 - Ordinea afișării: Trebuie respectată ordinea din enunț
Formula cheie pentru condiție compusă: if (i % 3 != 0 && i % 5 != 0)
Scrie soluția în C++:
Soluție corectă:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int sumaDiv3 = 0; // Suma numerelor divizibile cu 3
int produsDiv5 = 1; // Produsul numerelor divizibile cu 5
int contor = 0; // Numărul de valori nedivizibile cu 3 sau 5
for (int i = 1; i <= n; i++) {
// Verificăm dacă i este divizibil cu 3
if (i % 3 == 0) {
sumaDiv3 += i;
}
// Verificăm dacă i este divizibil cu 5
if (i % 5 == 0) {
produsDiv5 *= i;
}
// Verificăm dacă i NU este divizibil nici cu 3, nici cu 5
if (i % 3 != 0 && i % 5 != 0) {
contor++;
}
}
// Afișăm rezultatele în ordinea cerută
cout << sumaDiv3 << " " << produsDiv5 << " " << contor;
return 0;
}
Varianta alternativă (cu if-uri separate):
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int sumaDiv3 = 0;
int produsDiv5 = 1;
int contor = 0;
for (int i = 1; i <= n; i++) {
bool esteDivizibilCu3 = (i % 3 == 0);
bool esteDivizibilCu5 = (i % 5 == 0);
if (esteDivizibilCu3) {
sumaDiv3 += i;
}
if (esteDivizibilCu5) {
produsDiv5 *= i;
}
if (!esteDivizibilCu3 && !esteDivizibilCu5) {
contor++;
}
}
cout << sumaDiv3 << " " << produsDiv5 << " " << contor;
return 0;
}
Ce învățăm din această problemă:
- Condiții independente: Un număr poate să fie atât divizibil cu 3, cât și cu 5
- Condiții compuse: Folosirea operatorilor
&&(și) și||(sau) - Inițializări diferite: contorul începe cu 0 (ca toate numărările)
- Gândire exhaustivă: Trebuie să acoperim toate cazurile posibile
- Aplicații practice: Statistici multiple pe aceleași date
- Verificarea calculelor: Testați întotdeauna algoritmul cu valori mici!
Pentru profesori: Această problemă este excelentă pentru a discuta despre "cazuri speciale". Întrebați elevii: "Ce se întâmplă dacă n=0? Dar dacă n=1? Cum gestionăm aceste cazuri?"
Exercițiul Practic: Calcule multiple combinate
Sarcini de lucru
Completează următoarele sarcini pentru a-ți consolida cunoștințele despre sume și produse complexe
Sarcina 1: Analiză algoritm cu 3 rezultate
Analizează algoritmul pentru problema cu 3 calcule:
Pentru n=15, care numere intră în fiecare categorie și de ce? Câte numere sunt divizibile atât cu 3, cât și cu 5?
Soluție pentru Sarcina 1:
Analiza pentru n=15:
- Divizibile cu 3: 3, 6, 9, 12, 15 → suma = 3+6+9+12+15 = 45
- Divizibile cu 5: 5, 10, 15 → produs = 5×10×15 = 750
- Nedivizibile cu 3 sau 5: 1, 2, 4, 7, 8, 11, 13, 14 → contor = 8
- Numere divizibile și cu 3 și cu 5: 15 (un singur număr)
Observație importantă: Numărul 15 apare atât în suma divizibilelor cu 3, cât și în produsul divizibilelor cu 5. Acest lucru este corect, deoarece condițiile sunt independente. În problemele de acest tip, un număr poate să contribuie la mai multe calcule dacă îndeplinește mai multe condiții.
Verificare: 15 % 3 == 0 (adevărat) și 15 % 5 == 0 (adevărat), deci se execută atât sumaDiv3 += 15 cât și produsDiv5 *= 15.
Sarcina 2: Implementare în C++ pentru statistici complexe
Cerință: Implementează în C++ un program care citește un număr n și afișează: suma numerelor perfecte, produsul numerelor abundente, și numărul numerelor deficiente de la 1 la n.
Soluție pentru Sarcina 2:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int sumaPerfecte = 0;
int produsAbundente = 1;
int numarDeficiente = 0;
// Parcurgem toate numerele de la 1 la n
for (int i = 1; i <= n; i++) {
int sumaDivizori = 0;
// Calculăm suma divizorilor lui i (fără i însuși)
for (int d = 1; d <= i/2; d++) {
if (i % d == 0) {
sumaDivizori += d;
}
}
// Clasificăm numărul i
if (sumaDivizori == i) {
// Număr perfect
sumaPerfecte += i;
} else if (sumaDivizori > i) {
// Număr abundant
produsAbundente *= i;
} else {
// Număr deficient (inclusiv numerele prime)
numarDeficiente++;
}
}
cout << sumaPerfecte << " " << produsAbundente << " " << numarDeficiente << endl;
return 0;
}
Explicații importante:
- Buclă dublă: Pentru fiecare număr i, avem o buclă pentru divizori
- Suma divizorilor: Calculăm suma divizorilor proprii (fără numărul însuși)
- Clasificare exclusivă: Un număr poate fi doar perfect, abundant sau deficient
- Numere prime: Sunt deficiente (suma divizorilor = 1 < numărul)
- Teste recomandate:
- n=10 → perfecte: 6 (suma=6), abundente: niciuna (produs=1), deficiente: 9
- n=28 → perfecte: 6+28=34, abundente: 12,18,20,24 (produs=103680), deficiente: restul
- n=1 → perfecte: 0, abundente: niciuna (produs=1), deficiente: 1