Nu obții 100 de puncte sau ai nelămuriri în privința problemelor? Scrie-mi pe Instagram.
Ai găsit o greșeală, vrei să raportezi un utilizator sau vrei să comunici altceva? Folosește formularul de contact.
Vrei să ne transmiți o părere despre platformă? Folosește formularul de feedback.
Folosește următoarele shortcuturi pentru a naviga mai ușor pe platformă.
Meniu shortcuturi | ? |
Căutare probleme sau utilizatori | / |
Navigare printre rezultatele căutării | ↑, ↓ |
Meniu de contact și feedback | CTRL + Shift + F |
Ieșire din meniuri | Esc |
Setări editor | CTRL + Shift + S |
Schimbare stil editor | CTRL + Shift + E |
Șabloane de cod | CTRL + Shift + 1/2/3 |
Golire editor | CTRL + Shift + 4 |
Se dau doi vectori cu numere naturale ordonate crescător. Se dorește formarea unui alt vector care să conțină valorile din ambii vectori, tot în ordine crescătoare.
Exemplu. Dacă avem vectorii a = (1, 2, 5, 9)
și b = (3, 4, 5, 7)
, atunci vectorul rezultat este c = (1, 2, 3, 4, 5, 5, 7, 9)
.
O metodă ar fi să lipim al doilea vector de primul, după care să sortăm elementele. Deși această soluție funcționează, rezolvarea problemei devine mai complicată. În plus, nu se folosește deloc de faptul că vectorii sunt inițial sortați crescător.
În această lecție învățăm metoda eficientă de rezolvare a acestei probleme, cu ajutorul interclasării.
Interclasarea a doi vectori constă în parcurgerea concomitentă a vectorilor, selectând pe rând elementul mai mic dintre elementul curent din primul vector și din al doilea. Iată o animație care demonstrează această idee:
Vector | Valoare |
---|---|
a | (11, 22, 55, 99) |
b | (33, 44, 55, 77) |
c | (1, 2, 3, 4, 5, 5, 7, 9) |
Să zicem că avem cei doi vectori ordonați crescător:
a
, de lungime n
;b
, de lungime m
;Vom crea un al treilea vector, c
, de lungime k
, care să rețină la final interclasarea.
c
este gol (k = 0
);a
și b
concomitent, cu un i
și un j
; cu alte cuvinte, cât timp i <= n && j <= m
(cât timp suntem în ambii vectori):a[i]
cu b[j]
(elementele curente din cei doi vectori);c
; dacă a[i] < b[j]
:c
elementul a[i]
(k++, c[k] = a[i]
);i
cu 1
(i++
);b[j] ≤ a[i]
:c
elementul b[j]
(k++, c[k] = b[j])
;j
cu 1
(j++
);i <= n
atunci mai avem elemente în vectorul a
, pe care le adăugăm în c
, pe rând;j <= m
atunci mai avem elemente în vectorul b
, pe care le adăugăm în c
, pe rând;c
este format.#include <iostream>
using namespace std;
//Declarăm cei trei vectori
int a[101], b[101], c[201], n, m, k; //Vectorul c trebuie să aibă lungimea dublă, ca să încapă elementele din ambele mulțimi
int main()
{
//Citim vectorii a și b
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
cin >> m;
for(int i = 1; i <= m; i++)
cin >> b[i];
//Începem interclasarea
int i = 1, j = 1;
while(i <= n && j <= m) { //Comparăm elementele a[i] și b[j] din vector
//Luăm mereu elementul mai mic
if(a[i] < b[j]) {
k++;
c[k] = a[i];
i++;
} else {
k++;
c[k] = b[j];
j++;
}
}
while(i <= n) { //Dacă intrăm în acest while, atunci vectorul b s-a epuizat, dar au rămas elemente în vectorul a, pe care le adăugăm pe rând ca mai sus
k++;
c[k] = a[i];
i++;
}
while(j <= m) { //Dacă intrăm în acest while, atunci vectorul a s-a epuizat, dar au rămas elemente în vectorul b, pe care le adăugăm pe rând ca mai sus
k++;
c[k] = b[j];
j++;
}
//Afișăm vectorul final
for(int i = 1; i <= k; i++)
cout << c[i] << " ";
return 0;
}
Dându-se doi vectori ordonați crescător reprezentând două mulțimi, să se afișeze mulțimea ce reprezință reuniunea lor. Testează-ți rezolvarea pe această pagină.
Exemplu: Pentru mulțimile a = (1, 2, 3, 4)
și b = (3, 5, 6)
, avem reuniunea lor c = (1, 2, 3, 4, 5, 6)
.
Rezolvare: Să notăm cei doi vectori a
și b
, iar cel răspuns c
. Observăm că dacă făceam interclasarea vectorilor folosind algoritmul clasic, obțineam un vector cu toate elementele din ambii, în ordine crescătoare (în exemplul de mai sus, interclasarea clasică ar fi fost c = (1, 2, 3, 3, 4, 5, 6)
). Fiind vorba de mulțimi, toate elementele vectorului răspuns trebuie să fie distincte — mai precis, singura diferență pe care trebuie să o facem față de algoritmul clasic este să ne asigurăm că nu băgăm niciodată două elemente egale unul după altul.
Implementare în C++
//Reuniunea a două mulțimi
#include <iostream>
using namespace std;
//Declarăm cei trei vectori
int a[101], b[101], c[201], n, m, k;
int main()
{
//Citim vectorii a și b
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
cin >> m;
for(int i = 1; i <= n; i++)
cin >> b[i];
//Interclasarea
int i = 1, j = 1;
while(i <= n && j <= m) {
if(a[i] == b[j]) { //Nu băgăm ambele elemente, ci doar pe unul dintre ele
k++;
c[k] = a[i]; //sau b[j]
i++;
j++;
} else if(a[i] < b[j]) {
k++;
c[k] = a[i];
i++;
} else {
k++;
c[k] = b[j];
j++;
}
}
while(i <= n) {
k++;
c[k] = a[i];
i++;
}
while(j <= m) {
k++;
c[k] = b[j];
j++;
}
for(int i = 1; i <= k; i++)
cout << c[i] << " ";
return 0;
}
Dându-se doi vectori ordonați crescător reprezentând două mulțimi, să se afișeze mulțimea ce reprezință intersecția lor. Testează-ți rezolvarea pe această pagină.
Exemplu: Pentru mulțimile a = (1, 2, 3, 4, 5)
și b = (3, 5, 6)
, avem intersecția lor c = (3, 5)
.
Rezolvare: Intersecția a două mulțimi este similar cu algoritmul pentru reuniune:
c
;Implementare în C++
//Intersecția a două mulțimi
#include <iostream>
using namespace std;
//Declarăm cei trei vectori
int a[101], b[101], c[201], n, m, k;
int main()
{
//Citim vectorii a și b
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
cin >> m;
for(int i = 1; i <= n; i++)
cin >> b[i];
//Interclasarea
int i = 1, j = 1;
while(i <= n && j <= m) {
if(a[i] == b[j]) {
k++;
c[k] = a[i]; //sau b[j]
i++;
j++;
} else if(a[i] < b[j]) {
i++;
} else {
j++;
}
}
for(int i = 1; i <= k; i++)
cout << c[i] << " ";
return 0;
}
# | Problemă | Dificultate | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
5. | Timbre | Ușoară (2 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
287. | Interclasare 3 | Medie (4 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
285. | Intersectia multimilor | Ușoară (2 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
284. | Reuniunea multimilor | Ușoară (2 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
693. | Partitura | Grea (8 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Vrei mai multe probleme? Pe această pagină găsești întreaga listă de probleme propuse. |