Standardna biblioteka (STL) ima gotove strukture podataka i algoritme koje takmičari koriste u skoro svakom zadatku: par vrednosti, sortiranje sa sopstvenim pravilom, skup bez ponavljanja, binarnu pretragu i red sa prioritetom. U ovoj lekciji su najkorisniji delovi, sa složenošću svake operacije.
Pre nego što počneš: potrebno predznanje – mape u C++-u, vector. Kako da učiš: svaki primer prekucaj i pokreni, a zadatke na kraju prvo reši sam/a; uputstvo i rešenje otvori tek posle toga. Svi programi su u C++-u (C++17) i provereno se prevode i daju navedeni izlaz.
pair: dve vrednosti zajedno
pair<A, B> čuva dve vrednosti – npr. ime i bodove, ili koordinate tačke. Poređenje parova ide leksikografski: prvo po first, pa po second.
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<pair<int, string>> takmicari(n); // (bodovi, ime)
for (auto& [bodovi, ime] : takmicari) // strukturno vezivanje (C++17)
cin >> ime >> bodovi;
sort(takmicari.begin(), takmicari.end()); // po bodovima, pa po imenu
for (auto& [bodovi, ime] : takmicari)
cout << ime << " " << bodovi << "\n";
return 0;
}
Iva je pre Marka jer imaju iste bodove, a „Iva“ < „Marko“. make_pair(a, b) ili samo {a, b} pravi par.
sort sa sopstvenim pravilom
sort(v.begin(), v.end()) sortira rastuće u O(n log n). Za drugi redosled daje se funkcija poređenja (komparator) – najčešće lambda koja vraća true ako a treba da bude preb:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<pair<string, int>> v(n); // (ime, bodovi)
for (auto& [ime, bodovi] : v) cin >> ime >> bodovi;
// više bodova je bolje; kod istih bodova – abecedno po imenu
sort(v.begin(), v.end(), [](const pair<string, int>& a, const pair<string, int>& b) {
if (a.second != b.second) return a.second > b.second;
return a.first < b.first;
});
for (int i = 0; i < n; i++)
cout << i + 1 << ". " << v[i].first << " " << v[i].second << "\n";
return 0;
}
Poziv
Šta radi
sort(v.begin(), v.end())
rastuće
sort(v.rbegin(), v.rend()) ili sort(..., greater<int>())
opadajuće
stable_sort(...)
isto, ali jednaki elementi zadržavaju početni redosled
obrtanje, uklanjanje uzastopnih duplikata, najveći element, zbir
Pravilo za komparator: za jednake elemente mora vratiti false (koristi < i >, nikad <=). U suprotnom sort može da radi pogrešno ili da sruši program.
Binarna pretraga u sortiranom nizu
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, q;
cin >> n >> q;
vector<int> a(n);
for (int& x : a) cin >> x;
sort(a.begin(), a.end());
while (q--) {
int x;
cin >> x;
// koliko elemenata je < x, a koliko <= x
int manjih = lower_bound(a.begin(), a.end(), x) - a.begin();
int najvise = upper_bound(a.begin(), a.end(), x) - a.begin();
cout << x << ": pojavljuje se " << najvise - manjih << " puta, manjih je " << manjih << "\n";
}
return 0;
}
lower_bound vraća prvo mesto gde je element ≥ x, upper_bound prvo mesto gde je > x – obe u O(log n). Detaljno: Binarna pretraga.
set i map: uređeni skup
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
set<int> s;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
s.insert(x); // duplikati se ne dodaju, O(log n)
}
cout << "razlicitih: " << s.size() << "\n";
cout << "najmanji: " << *s.begin() << ", najveci: " << *s.rbegin() << "\n";
cout << "ima 7: " << (s.count(7) ? "da" : "ne") << "\n";
auto it = s.lower_bound(6); // najmanji element >= 6
if (it != s.end()) cout << "prvi >= 6: " << *it << "\n";
s.erase(9);
for (int x : s) cout << x << " "; // uvek u rastućem redosledu
cout << "\n";
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int main() {
// k najvecih brojeva iz niza: cuvamo k najvecih u "min-hip"-u
int n, k;
cin >> n >> k;
priority_queue<int, vector<int>, greater<int>> pq; // na vrhu je NAJMANJI
for (int i = 0; i < n; i++) {
int x;
cin >> x;
pq.push(x);
if ((int)pq.size() > k) pq.pop(); // izbaci najmanjeg
}
vector<int> rez;
while (!pq.empty()) { rez.push_back(pq.top()); pq.pop(); }
reverse(rez.begin(), rez.end());
for (int x : rez) cout << x << " ";
cout << "\n";
return 0;
}
priority_queue<int> drži najveći element na vrhu (top); push i pop rade u O(log n). Sa greater<int> na vrhu je najmanji. Ovde je složenost O(n log k) umesto O(n log n) za sortiranje celog niza. Red sa prioritetom je osnova Dijkstrinog algoritma: Red sa prioritetom.
Zadaci za vežbu
Za svaki zadatak postoji primer, uputstvo i rešenje. Rešenja su provereno tačna na primerima iz teksta.
ZADATAK 01Težina: srednje
Rang lista
Učitava se n, pa n redova sa imenom i bodovima na tri zadatka. Ispisati rang listu: po ukupnom broju bodova opadajuće, kod jednakog zbira po većem broju bodova na trećem zadatku, a zatim abecedno.
Primer
Ulaz
4
Ana 10 20 30
Iva 30 20 10
Luka 20 20 20
Mila 5 5 5
Izlaz
Ana 60
Luka 60
Iva 60
Mila 15
Uputstvo
Čuvaj strukturu ili tuple<string,int,int> (ime, zbir, treći). Komparator: prvo zbir (veći), pa treći (veći), pa ime (manje).
Rešenje (C++)
#include <bits/stdc++.h>
using namespace std;
struct Takmicar {
string ime;
int zbir, treci;
};
int main() {
int n;
cin >> n;
vector<Takmicar> v(n);
for (auto& t : v) {
int a, b, c;
cin >> t.ime >> a >> b >> c;
t.zbir = a + b + c;
t.treci = c;
}
sort(v.begin(), v.end(), [](const Takmicar& x, const Takmicar& y) {
if (x.zbir != y.zbir) return x.zbir > y.zbir;
if (x.treci != y.treci) return x.treci > y.treci;
return x.ime < y.ime;
});
for (auto& t : v) cout << t.ime << " " << t.zbir << "\n";
return 0;
}
ZADATAK 02Težina: lako
Prvi put viđen
Učitava se n brojeva. Za svaki ispisati NOVO ako se pojavljuje prvi put, a VEC ako se već pojavio.
Primer
Ulaz
6
3 5 3 1 5 3
Izlaz
NOVO
NOVO
VEC
NOVO
VEC
VEC
Uputstvo
Skup viđenih brojeva; insert vraća par čiji je drugi član true ako je element zaista ubačen.
Rešenje (C++)
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
set<int> vidjeni;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
bool nov = vidjeni.insert(x).second; // true ako x nije bio u skupu
cout << (nov ? "NOVO" : "VEC") << "\n";
}
return 0;
}
Česte greške i saveti
Komparator za sort koristi strogo poređenje (<, >), nikad <=.
lower_bound na vector-u radi samo ako je niz sortiran; za set koristi metodu s.lower_bound(x), ne opštu funkciju (ona je spora za set).
Pre čitanja pq.top() ili *s.begin() proveri da struktura nije prazna.
Proveri znanje
Otvori kviz
STL
1. Koja je složenost sort-a nad n elemenata?
2. Šta se dešava kada u set dodaš broj koji već postoji?
3. Koji element je na vrhu priority_queue<int>?
4. Šta vraća lower_bound(a.begin(), a.end(), x) u sortiranom nizu?
Podešavanja kolačića
Koristimo kolačiće da bismo vam pružili najbolje moguće iskustvo. Takođe nam omogućavaju da analiziramo ponašanje korisnika kako bismo stalno poboljšavali veb lokaciju za vas.