Professional Documents
Culture Documents
Opisi algoritama
Zadatak Zvono Autor: Nikola Pintarić
Budući da je Ivica tek nakon M minuta odlučio krenuti brojati, broj od kojeg Ivica treba početi
brojati se dobije izračunavanjem 45 - M.
Kategorija: ad-hoc
Pošto Marica jede čokolade koje imaju manje ili jednako M grama, potrebno je
jednostavnim if-om provjeriti zadovoljava li Ivičina čokolada taj uvjet. Ukoliko zadovoljava,
Marica će pojesti cijelu čokoladu, pa ispisujemo masu cijele čokolade. Ukoliko ne
zadovoljava, Marica neće pojesti ništa, pa ispisujemo nulu. Masu cijele čokolade možemo
izračunati kao broj kockica pomnožen s masom jedne kockice. Dakle, masa čokolade je
R*S*G.
Kategorija: ad-hoc
Kategorija: ad-hoc
Kako bi riješili ovaj zadatak potrebno je naći bilo koji put kojim Barry može proći od početne
pozicije do bilo koje pozicije u zadnjem stupcu.
To se može korištenjem BFS ili DFS algoritma, nakon kojeg je potrebno iskonstruirati put.
Na kraju, sve što je potrebno je formatirati put u oblik koji je zadan u tekstu zadatka.
Za implementacijske detalje pogledajte službeno rješenje zadatka.
Najprije moramo riječi posložiti u poredak koji odgovara permutaciji. Sada vidimo da neka
riječ nakon šifriranja mora biti leksikografksi manja od svih riječi koje se nalaze nakon nje.
Da budemo sigurni da riječ A koja se nalazi nakon riječi B nije manja od B zbog prvog uvjeta
dovoljno je pogledati sve parove i provjeriti je li A prefiks od B.
Drugi uvjet provjeravamo tako da napravimo usmjereni graf od 26 čvorova gdje svaki čvor
predstavlja pripadajuće slovo engleske abecede.
U grafu postoji usmjereni brid Bi -> Ai ako i samo ako postoje riječi A i B takve da je A u nizu
prije riječi B i one se prvi put razlikuju u i-tom slovu.
Drugim riječima ako postoji usmjereni brid Bi -> Ai onda slovo kojim ćemo zamijeniti slovom
Ai mora biti leksikografski manje od slova kojim ćemo zamijeniti Bi.
Ako u grafu nema ciklusa onda je graf DAG (directed acyclic graph) što znači da njegove
čvorove možemo topološki sortirati.
Za svaki čvor X vrijedi da su svi čvorovi do kojih se može doći iz X u topološko sortiranom
nizu prije njega.
Iz prethodnih uvjeta vidljivo je da slovu koje je predstavljeno prvim čvorom u topološki
sortiranom nizu moramo pridruziti slovo 'a', drugom 'b', i tako dalje.
Kategorija: grafovi
Ako čvor minimalne magije ima magiju veću od 1, vrlo lako se pokaže da je rješenje put
duljine 1, tj. taj čvor.
Ako u stablu ima čvorova magije 1 (u daljnjem tekstu jedinica), može se pokazati da je (neki)
put minimalne magije (u daljnjem tekstu o ptimalni put) u jednom od sljedeća dva oblika:
a) put od k jedinica za neki k,
b) put od 2k + 1 čvorova gdje je samo središnji čvor magije 2, a sve ostalo su jedinice.
Dokaz se svodi na rastavljanje pretpostavljenog minimalnog optimalnog puta na pogodno
odabrana dva dijela. Tada jedan od dijelova mora također biti optimalan osim u navedenim
slučajevima, što kontradiktira minimalnost.
U rješenju ćemo koristiti slabiju tvrdnju: optimalni put sadrži najviše jedan čvor koji nije
jedinica. Nazovimo put kroz čvor v u kojem su svi ostali čvorovi jedinice v -dobar put.
Dovoljno je za svaki čvor pronaći najveći dobar put, jer dodavanje dodatnih jedinica na kraj
puta smanjuje magiju puta.
Sada pomoću dinamika za prefikse i sufikse djece za svako dijete u nekog čvora v možemo
odrediti najveći v-dobar put sadržan u podstablu od v koji ne sadrži u.
(Uzmemo maksimum prefiksa do djeteta prije u i sufiksa od djeteta nakon u .)
Staru dinamiku koristimo u drugom prolazu DFS-a. Kada smo na nekom čvoru u , pomoću
dinamike za njegovog roditelja v možemo izračunavati najveći u -dobar put koji sadrži v.
Moramo uzeti u obzir i puteve kroz v koji ne sadrže nijedno njegovo dijete, što rješavamo još
jednom dinamikom.
Kada za neki čvor v imamo najdulji v -dobar put u njegovom podstablu i najdulji v -dobar put
kroz njegovog roditelja, prolaskom po djeci od v lako možemo dobiti duljine dva najdulja
v-dobra puta koja počinju u v, čija je unija traženi najveći v -dobar put. Sada samo
usporedimo magije najvećih v-dobrih puteva za sve čvorove v i uzmemo najmanju.
U opisu ovog rješenja sve oznake promatrat ćemo ciklično, što znači da oznaka n+1 je
zapravo 1, n+2 je zapravo 2, itd.
Za bilo koji redoslijed slanja vilenjaka, postojat će pozicija k tako da nijedan od njih nije
prošetao od k-tog do k+1-og patuljka jer je k -ti bio zauzet. Ovo je prilično očito jer to vrijedi
za patuljka koji je zadnji dobio svojeg protivnika. Međutim, vrijedi i mnogo jača tvrdnja: uvijek
postoji barem jedna pozicija k tako da z a svaki redoslijed slanja vilenjaka nijedan od njih nije
prošetao od k-tog do k+1-og. Definirajmo R i kao broj patuljaka čiji zadani protivnik ima
oznaku manju ili jednaku i, te neka je Pi = Ri - i. Primijetite da nužno vrijedi P
n = 0.
Uzmimo najmanji broj od svih Pi, recimo da se on postiže za poziciju m . Pokazat ćemo da je
nemoguće da vilenjak prošeta od pozicije m do m +1. Pretpostavimo suprotno, to bi značilo
da postoji niz pozicija a, a+1, a+2, … m-1, m za koji vrijedi da je broj vilenjaka čiji se
protivnik nalazi na nekoj od tih pozicija veći od broja tih pozicija. Međutim, vrijedi da je
razlika broja vilenjaka čiji je protivnik na nekoj od tih pozicija i broja tih pozicija jednaka točno
Pm - Pa. To vrijedi bez obzira je li a ili manji od m
, zato što je Pn = 0. No zbog odabira pozicije
m, ta razlika ne može biti pozitivna.
Sada možemo “prerezati” krug, tj. promatrati ga kao niz duljine n koji počinje na poziciji m +1.
Zadatak na nizu možemo riješiti pohlepnim algoritmom. Prolazeći od početka do kraja niza,
ubacit ćemo u set snagu vilenjaka kada dođemo do pozicije na kojoj je njegov zadani
protivnik. Za protivnika nekom patuljku odabrat ćemo najslabijeg vilenjaka iz s eta koji ga
može pobijediti, a ako takav ne postoji, najslabijeg vilenjaka u s etu. Vilenjaka kojeg smo
odabrali potom ćemo izbaciti iz seta. Redoslijed izbacivanja vilenjaka iz s eta ujedno je i
redoslijed kojim će ulaziti u dvoranu.
Za riješiti podzatak vrijedan 40% bodova, bilo je dovoljno implementirati pohlepni algoritam s
početkom niza na prvoj poziciji, a moguće ga je i riješiti binarnim pretraživanjem.
Za uspješno rješavanje zadatka potrebno je primijetiti sljedeće: ako gradimo prefiksno stablo
za neki skup riječi sigurno je optimalno započeti prefiksno stablo tako da sva slova koja su
zajednička svim riječima iskoristimo kao početni lanac tog podstabla. Npr. ukoliko imamo
riječi aaab, baab i cab optimalno je iskoristiti slova abc za stvaranje zajedničkog prefiksa
svih riječi, nakon toga od riječi će nam ostati: aa, ab, c. Sada smo u stanju kada više
nemamo nijedno slovo koje se nalazi u sve tri riječi, potrebno je nekako nastaviti graditi
stablo.
S obzirom da znamo da ostali sufiksi tri riječi neće moći biti u istom podstablu jer nemaju
nijedno slovo koje dijele; biramo dva podskupa riječi za koje ćemo reći da se nastavljaju
graditi u različitim podstablima, u našem slučaju optimalno je odabrati (aa, ab) u jedan
podskup i (c) u drugi. Podjelu za neki podskup radimo na 2n načina, ukoliko je u skupu n
riječi. Svaka riječ se može nalaziti ili u jednom ili u drugom skupu u koji dijelimo te riječi.
Potrebno je također primijetiti da iako su neke dvije riječi u istom skupu ne znači da će se
graditi dalje u istom podstablu barem jedan korak, već se odmah može dogoditi da budu još
dalje podijeljene, rekurzivno.
Kategorija: dinamika