Câți clienți DISTINCȚI are o companie de telefonie, dacă un client poate avea mai multe abonamente? Mulțimea rezolvă elegant tot ce înseamnă „unic": fiecare element apare o singură dată, iar ordinea nu contează.
O mulțime e o colecție în care fiecare element apare O SINGURĂ DATĂ, iar ordinea nu are nicio importanță. O știi de la matematică — acum devine structură de date.
{3, 7, 3, 5} este de fapt {3, 5, 7} — dublurile dispar AUTOMAT. De-asta mulțimea răspunde instant la „câți distincți?".
{1, 2, 3} și {3, 1, 2} sunt ACEEAȘI mulțime. Nu există „primul element" — deci nici indexare cu m[0]!
Întrebarea „x e în mulțime?" primește răspuns aproape instant — fără parcurgerea întregii colecții, ca la liste.
Cele două rucsacuri din programă: scrie obiectele (numerele) din fiecare, apoi apasă operațiile și privește zonele aprinzându-se.
Teoria mulțimilor, gata implementată. Aceleași operații, sintaxă de o linie.
Acolade cu elemente — sau set(listă), care curăță automat dublurile.
Adăugare și ștergere; remove pe element inexistent dă EROARE, discard nu.
Reuniune, intersecție, diferență — sau metodele union / intersection / difference.
in verifică elementul; <= verifică submulțimea; == egalitatea (ordinea nu contează!).
Trei probleme în care mulțimea face în 2 rânduri ce lista făcea în 10.
O listă de abonamente cu numele clienților (un client poate apărea de mai multe ori). Câți clienți distincți?
Obiectele comune și cele aflate doar în primul rucsac — exact enunțul din programă.
O listă are elemente repetate? Compari lungimile — trucul de aur.
Aceeași problemă, două stiluri: C++ ca în clasa a IX-a (vectori de frecvență, fără STL) și Python cu set (operatorii | & -). Apasă „vezi rezolvarea" și compară cât cod îți economisește setul.
Se dă un șir de n numere naturale, ordonate crescător. Afișează elementele distincte, tot crescător.
Șirul e sortat → un element e „nou" doar dacă diferă de precedentul (nu ai nevoie de nicio structură).
#include <iostream>
using namespace std;
int main() {
int n; cin >> n;
long long x, prec = -1;
for (int k = 0; k < n; k++) {
cin >> x;
if (x != prec) cout << x << ' '; // sortat → distinct = diferit de precedent
prec = x;
}
return 0;
}
Se dau două mulțimi de numere naturale. Afișează reuniunea crescător pe o linie, apoi intersecția crescător pe linia următoare.
Vector de frecvență: marchezi ce apare în A și în B, apoi parcurgi valorile crescător.
#include <iostream> using namespace std; int fa[1001], fb[1001]; // pune 1000 = valoarea maximă din enunț int main() { int n, m, x; cin >> n; for (int k = 0; k < n; k++) { cin >> x; fa[x] = 1; } cin >> m; for (int k = 0; k < m; k++) { cin >> x; fb[x] = 1; } for (int v = 0; v <= 1000; v++) if (fa[v] || fb[v]) cout << v << ' '; // reuniunea cout << '\n'; for (int v = 0; v <= 1000; v++) if (fa[v] && fb[v]) cout << v << ' '; // intersecția return 0; }
Variație pe subpuncte: reuniunea și intersecția a două mulțimi. Aici arătăm și a treia operație — diferența A − B (ce e doar în A).
Aceleași frecvențe — schimbă doar condiția: || reuniune, && intersecție, && ! diferență.
#include <iostream>
using namespace std;
int fa[1001], fb[1001];
int main() {
int n, m, x;
cin >> n; while (n--) { cin >> x; fa[x] = 1; }
cin >> m; while (m--) { cin >> x; fb[x] = 1; }
for (int v = 0; v <= 1000; v++) if (fa[v] || fb[v]) cout << v << ' '; // A U B
cout << '\n';
for (int v = 0; v <= 1000; v++) if (fa[v] && fb[v]) cout << v << ' '; // A ∩ B
cout << '\n';
for (int v = 0; v <= 1000; v++) if (fa[v] && !fb[v]) cout << v << ' '; // A − B
return 0;
}
Se dă un șir de numere naturale. Câte dintre ele au toate cifrele distincte? (Un mini-set, dar de cifre 0–9.)
Vector de frecvență pe cifre (0–9): dacă o cifră reapare, numărul NU are cifre distincte.
#include <iostream>
using namespace std;
bool cifreDistincte(long long x) {
int f[10] = {0};
if (x == 0) return true;
while (x > 0) {
int c = x % 10;
if (f[c]) return false; // cifra c a mai apărut
f[c] = 1;
x /= 10;
}
return true;
}
int main() {
int n; cin >> n; long long x; int cate = 0;
for (int k = 0; k < n; k++) { cin >> x; if (cifreDistincte(x)) cate++; }
cout << cate;
return 0;
}
Se dă n (pe prima linie) și un șir de n numere naturale (pe a doua). Câte valori distincte conține șirul? Citire clasică, cu n dat de la început.
Vector de frecvență: numeri o valoare doar prima dată când o întâlnești.
#include <iostream> using namespace std; int f[1001]; // pune 1000 = valoarea maximă din enunț int main() { int n, x, cate = 0; cin >> n; for (int k = 0; k < n; k++) { cin >> x; if (f[x] == 0) { cate++; f[x] = 1; } // prima apariție = valoare nouă } cout << cate; return 0; }
Cinci întrebări — mulțimile pe scurt.
Modelul neliniar, condensat.