Professional Documents
Culture Documents
Rjesenja PDF
Rjesenja PDF
Rjesenja PDF
P = int(input())
print(P + 2)
Iz teksta zadatka je jasno da će X učenika navedene škole moći otići na izlet samo
ako je ukupan broj mjesta u svim autobusima (Y * M) veći ili jednak od X.
X = int(input())
Y = int(input())
M = int(input())
if Y * M >= X:
print("DA")
else:
print("NE")
Kako bismo odredili koliko karata iz svake boje nedostaje dovoljno je pročitati svaki
treći znak iz ulaza te zbrojiti koliko karata iz svake boje smo vidjeli u ulazu. Na
kraju od broja 13 oduzmemo izračunati zbroj za svaku boju i rezultat ispišemo
ukoliko nismo pronašli grešku.
Kako bismo provjerili postoji li greška dovoljno je sa dvije ugnježđene for petlje
provjeriti postoje li pozicije i, j takve da su podstringovi duljine 3 koji počinju na
pozicijama i, j jednaki.
Alternativno, moguće je u dvodimenzionalnom nizu pamtiti je li karta neke boje i
broja već pronađena dok učitavamo karte iz stringa. Za implementacijske detalje
pogledajte službeno rješenje.
Prvo uočimo da se nikako ne isplati knjige raspoređivati u grupe koje sadrže manje
od 3 knjige jer popust vrijedi samo za grupu od 3 knjige (prisjetimo se popusta: od
3 knjige, najjeftiniju dobijemo besplatno). Stoga valja sve knjige rasporediti u
grupe po 3, tako da na kraju možda ostane samo jedna grupa koja ima manje od
3 knjige (jer broj knjiga koje je kupac uzeo nije višekratnik broja 3).
Uočimo sada iz skupa svih knjiga dvije najskuplje knjige na popisu (one mogu
imati i istu cijenu). Budući da ne postoje knjige koje su skuplje od njih, ne možemo
napraviti nikoju grupu u kojoj bi za te dvije knjige dobili popust (jer su upravo one
najskuplje), ali možemo tada uzeti treću najskuplju i nju staviti zajedno u grupu s
prve dvije. Tada ćemo popust dobiti za tu treću knjigu. Sada smo početni skup
knjiga smanjili za tri knjige. Ponavljanjem ovog postupka skroz dok imamo još
knjiga u skupu, upravo zbog toga što u svakom grupiranju dobijemo popust za
najskuplju moguću knjigu (to je treća najskuplja od preostalih knjiga), osiguravamo
da će konačna cijena biti najmanja moguća. Ako broj knjiga nije višekratnik broj 3,
u zadnjem grupiranju imat ćemo 1 ili 2 knjige i morat ćemo ih obje platiti, ali to ne
narušava valjanost algoritma.
U ovom zadatku postojalo je više strategija uništavanja balona. Ovdje ćemo navesti
jednu koja je implementirana u službenom rješenju.
Strategija koja je optimalna je sljedeća: odaberi prvi balon s lijeva koji nije uništen
i ispali strijelu na njegovoj visini. Pokušajmo okvirno dokazati točnost algoritma.
Najljeviji balon sigurno moramo pogoditi strijelom tako da će barem jedna strijela
početi na njemu, samo je pitanje je li ponekad bolje prvo uništiti neki balon desno
od njega koji je viši od njega pa onda kasnije njega.
Promatrajmo dva slučaja:
1) U slučaju da se skup balona koji bi bili uništeni ispucajem strijele u taj viši
balon i prvi balon nemeaju presjek očito je svejedno koji prvi od ta dva
uništimo.
2) U slučaju da ta dva skupa imaju presjek primijetimo da je taj presjek sufiks
dva skupa tj. uvijek će biti presjek ako postoji biti nekoliko najdesnijih
elemanata. Što ponovno znači da je svejedno koji prvi uništimo.
Ako koristimo binarno stablo (npr. map u C++-u) za održavanje podataka ukupna
vremenska složenost algoritma je O(Q lg N), a memorijska složenost O(N).
Pokušajmo prvo riješiti zadatak za slučaj kada nema promjena i rješavamo ga nad
stalnim zahtjevima za slikama u boji ai i crno bijelim slikama bi. Potrebno je
odgovoriti na koliko je načina moguće odabrati različite prodaje slika sa svojstvom
da je barem C slika u boji. Početni problem kada ne dolazi do promjene zahtjeva
kupaca rješavamo dinamičkim programiranjem. Označimo s dpij broj načina za
odabrati prvih i prodaji tako da je točno j zahtjeva zadovoljeno slikama u boji.
Relacija kojom računamo dpij jest:
dpij = dpi-1 j * bi + dpi-1 j-1 * ai
Na kraju je rješenje suma svih dpn i za svaki i veći ili jednak od C. Računanje si
možemo još olakšati ako definiramo da je dpi K broj načina za ne točno K slika u
boji već barem K slika u boji. Rješenje koje za svaku promjenu ponovno računa ovu
dinamiku u složenosti O(N * C) donosilo je 30% bodova.
Za ostatak bodova bilo je potrebno pronaći način za efikasno održavanje vrijednosti
dinamike nakon promjena. Inspiracija proizlazi iz tournament stabla. Ukoliko niste
upoznati sa strukturom definitivno pročitajte članak na
http://wiki.xfer.hr/tournament/. Pod pretpostavkom da sada znate kako funkcionira
tournament stablo nastavljamo rješavati zadatak. Rješenje ćemo održavati tako što
će nam svaki čvor tournamenta stabla pamtiti broj načina za odabrati slike u tom
podstablu za svaki broj odabranih slika u boji i od 0 do K.
Preostaje nam samo održavati tu dinamiku nakon što promijenimo zahtjeve jedne
osobe. Očito je za svaki list tournament stabla promjenu broja načina vrlo
jednostavno za izračunati. Pitanje je kako spojiti dva lista.
Tu možemo primijetiti kako je broj načina za odabrati kupnje nad cijelim
podstablom (sastavljenom od lijevog - L i desnog djeteta - R) s barem i prodaja
slika u boji Ts = ∑ Li*Rs - i za svaki i <= s.
Ukupna vremenska složenost je O((N + Q) lg N * K^2).
Označimo sa Sx skup svih mogućih intervala viceva koje možemo pronaći na zabavi
ako promatramo osobu x i sve njezine direktno ili indirektno podređene osobe
(podstablo osobe x).
Naime, označimo sa Ql skup svih desnih krajeva intervala viceva koje možemo
dobiti u podstablu osobe x, a kojima je lijevi kraj intervala jednak l.
Iteriramo padajuće po svim mogućim lijevim krajevima l te za svaki l po svim
mogućim desnim krajevima r tako da postoji dijete čvora x koje ima u svom skupu
interval [l, r] i radimo osvježavanje:
Ql = Ql ∪ Qr + 1
Ql = {vx} ∪ Ql + 1