You are on page 1of 7

HRVATSKO OTVORENO NATJECANJE IZ

INFORMATIKE 2013/2014
2. KOLO

OPISI ALGORITAMA
HONI 2013/2014 Zadatak PIR
2. kolo, 9. studenog 2013. Autor: Nikola Dmitrović

Kao opis algoritma, dovoljno je pokazati njegovo pseudo rješenje.

učitaj(POK, S, A, UL, B, IP);


učitaj(PRK, IL, NP)
ispiši((POK + S + A + UL + B + IP) - (PRK + IL + NP));

Potrebno znanje: naredba učitavanja i ispisivanja, zbrajanje i oduzimanje

Kategorija: ad hoc

HONI 2013/2014 Zadatak ZID


2. kolo, 9. studenog 2013. Autor: Adrian Satja Kurdija

Dva uzastopna reda sadrže ukupno 9 cigli. Ako je N paran, zid možemo
rastaviti na N / 2 takvih parova uzastopnih redova, pa je rješenje u ovom
slučaju N / 2 * 9.

Ako je pak N neparan, smanjimo ga za 1 da postane paran, izračunamo broj


cigli po istoj formuli i tome pridodamo 5 cigli za red koji smo uklonili. Dakle,
(N - 1) / 2 * 9 + 5.

Potrebno znanje: grananje (if, then, else) i osnovne matematičke operacije

Kategorija: ad hoc

HONI 2013/2014 Zadatak VOLIM


2. kolo, 9. studenog 2013. Autor: Nikola Dmitrović

Rješenje zadatka je simulacija opisane igre. Za svako pitanje, ukupno


vrijeme trajanja igre treba povećati za vrijeme trajanja tog pitanja. Ako je
odgovor na pitanje bio “T”, tada treba igraču “K” zbrojiti jedan. (problem koji
može nastati je ako se tijekom igre kutija ode dalje od igrača s oznakom
osam što možemo jednostavno rješiti korištenjem ostatka pri djeljenju).
To radimo dok je ukupno vrijeme trajanja igre manje ili jednako od 210
sekundi (3 minute i 30 sekundi). Uočite da događaji “netočan(N)” i
“preskočeno(P)” ne utječu na promjenu igrača na potezu te ih uopće ne
treba pratiti. Iz uvjeta zadatka je jasno da se postavljanje pitanja može
nastaviti i nakon eksplozije kutije. Uočite da nije problem prekinuti program
prije nego što se učitaju svi ulazni podaci. Bitan je samo točan ispis.
Pogledajmo pseudo kod kojim ćemo predstaviti jedno od mogućih rješenja
ovog zadataka.

učitaj (K)
učitaj (N)
igra := 0 // vrijeme trajanja igre, u početku je nula

dok je (igra <= 210) radi


{
učitaj (T, Z)
igra := igra + T // uvijek povećaj vrijeme trajanje igre za T
ako je (Z = 'T') i (igra <= 210) tada
K = (K % 8) + 1
}
ispiši(K)

Potrebno znanje: naredba ponavljanja (while), naredba odlučivanja

Kategorija: jednostavna simulacija

HONI 2013/2014 Zadatak MISA


2. kolo, 9. studenog 2013. Autor: Adrian Satja Kurdija

Za svako mjesto u crkvi provjeravamo je li prazno ili zauzeto. Ako je prazno,


tražimo broj njegovih zauzetih susjeda, da znamo hoće li na nj sjesti Mirko.
Ako je zauzeto, ponovno nam treba broj njegovih zauzetih susjeda kako
bismo ih ubrojili u ukupan broj rukovanja.

Kako za neko polje (redak, stupac) na jednostavan način provjeriti svih osam
susjeda? Ti susjedi su sljedeći:

(redak - 1, stupac - 1)
(redak - 1, stupac)
(redak - 1, stupac + 1)
(redak, stupac - 1)
(redak, stupac + 1)
(redak + 1, stupac - 1)
(redak + 1, stupac)
(redak + 1, stupac + 1)

Za svako od ovih polja valja provjeriti je li unutar tablice (tj. jesu li mu


koordinate veće od nule i ne premašuju R odnosno S) te je li zauzeto.
Pisanje svih ovih uvjeta naporno je i komplicirano. Srećom, posao možemo
veoma skratiti. U tome će nam pomoći dva pomoćna niza:

niz pomak_po_retku = (-1, -1, -1, 0, 0, 1, 1, 1),


niz pomak_po_stupcu = (-1, 0, 1, -1, 1, -1, 0, 1).

For petljom proći ćemo varijablom i od 1 do 8 te za svaki takav i izračunati:


redak_susjeda = redak + pomak_po_retku[i]
stupac_susjeda = stupac + pomak_po_stupcu[i]

Ako malo razmislite, vidjet ćete da na ovaj način stvarno biramo svih osam
gore navedenih susjeda. Unutar petlje još valja provjeriti spomenute uvjete
za susjeda.

Ukupan broj rukovanja na misi, bez Mirka, jednak je zbroju svih dobivenih
brojeva susjeda za zauzeta polja, podijeljen s dva -- jer smo svako
rukovanje brojali dvaput, za svaku osobu po jednom. Još valja dodati broj
Mirkovih rukovanja, a to je maksimalan broj susjeda nekog praznog polja.

Potrebno znanje: rad s matricom

Kategorija: ad hoc

HONI 2013/2014 Zadatak SLOM


2. kolo, 9. studenog 2013. Autor: Marin Tomić

Iz dobivene riječi, lako je rekonstruirati koja je to riječ bila prije jednog


treptaja. Nazovimo to obrnutim treptanjem. Početnu riječ možemo naći
ponavljanjem obrnutog treptaja X puta. To rješenje ima složenost O(NX) što
je bilo dovoljno brzo za 50 bodova.

Uz malo crtanja na papiru, lako se vidi da je obrnuto treptanje periodično, tj.


nakon P obrnutih treptaja, riječ će se vratiti u početno stanje. Dakle, ako
napravimo k * P + l obrnutih treptaja to je isto kao da smo ih napravili samo
l.
Za rješenje je potrebno samo pronaći broj P (što se može jednostavnom
ponavljanjem obrnutog treptaja dok se riječ ne vrati u početnu) i onda X
mod P puta ponoviti obrnuti treptaj na početnu riječ.

Može se pokazati da je P uvijek manji od N tako da je ukupna složenost


algoritma najviše O(N2), što je bilo dovoljno za 100% bodova.

Potrebno znanje: for-petlja, moć zapažanja


Kategorija: ad-hoc

HONI 2013/2014 Zadatak PUTNIK


2. kolo, 9. studenog 2013. Autor: Adrian Satja Kurdija

Bilo koji niz gradova koji zadovoljava Mirkov uvjet možemo izgraditi na
sljedeći način. Najprije u niz dodamo grad 1. Potom dodamo grad 2 lijevo ili
desno od grada 1. Potom dodamo grad 3 na lijevi ili desni kraj trenutnog
niza gradova. Potom grad 4, ponovno, na lijevi ili desni kraj. I tako dalje.
Takav niz zadovoljavat će Mirkov uvjet, a i obratno, bilo koji niz koji
zadovoljava Mirkov uvjet može se dobiti na opisani način.

Sada zadatak možemo riješiti dinamičkim programiranjem. Stanje je opisano


lijevim i desnim krajem trenutnog niza. To je dovoljno da znamo i koji
sljedeći grad nam valja staviti. Zašto? Grad koji smo posljednji stavili ili je na
lijevom, ili na desnom kraju, pa je njegova oznaka zapravo maksimum tih
dvaju brojeva. Grad koji sljedeći stavljamo ima, naravno, za jedan veću
oznaku. Za njega biramo hoćemo li ga staviti na lijevi ili desni kraj: za svaku
od tih mogućnosti računamo ukupnu duljinu letova kao duljinu upravo
odabranog leta uvećanu za vrijednost sljedećeg stanja u dinamici, te
odabiremo povoljnije rješenje kao vrijednost za trenutno stanje. Složenost je
algoritma O(N2).

Potrebno znanje: dinamičko programiranje

Kategorija: dinamičko programiranje


HONI 2013/2014 Zadatak PALETA
2. kolo, 9. studenog 2013. Autor: Domagoj Ćevid

Predstavimo bojanku kao graf kojemu sličice predstavljaju vrhove a, dva


vrha su spojena bridom ako ih ne smijemo obojati istom bojom.

Riješimo prvo slučaj kada su svi brojevi na ulazu različiti. Tada nam se graf
sastoji od disjunktnih ciklusa. Označimo broj načina na koji možemo obojati
ciklus od n vrhova sa f(n). Zamislimo da bojamo sličice redom. Prvu možemo
obojati na k načina. Drugu sličicu možemo obojati na k - 1 način jer mora
biti različito obojana od prve sličice. Za ostale se sličice zaključuje analogno.
No, u tih k(k - 1)n - 1 bojanja ćemo imati neka bojanja u kojima su nam
sličica broj 1 i sličica broj n iste boje. Spajanjem vrhova 1 i n, ako su iste
boje, dobivamo ciklus velčine n - 1 sa različito obojanim vrhovima te
zaključujemo da vrijedi rekurzivna relacija f(n) = k(k - 1)n - 1 - f(n - 1). Stoga
tu funkciju možemo lagano izračunati u linearnoj složenosti.

Ako brojevi nisu nužno različiti, naši će ciklusi imati na sebi repove koji su
stabla. Zamislimo si da smo obojali cikluse te sada bojamo te repove. Vrh
direktno spojen na ciklus možemo obojati na k - 1 načina (mora biti različit
od onoga na koji je spojen), vrh spojen na njega na također k - 1 načina itd.
Stoga zaključujemo da za svaki vrh koji nije u ciklusu naše trenutno rješenje
trebamo pomnožiti sa k - 1.

Graf obilazimo DFSom i određujemo koliko ima ciklusa koje veličine.

Potrebno znanje: Grafovi, rekurzivne formule, DFS

Kategorija: Grafovi

HONI 2013/2014 Zadatak LINIJE


2. kolo, 9. studenog 2013. Autor: Domagoj Ćevid

Nazovimo pravac paralelan s x-osi ili y-osi dobrim ako postoji točka koja leži
na njemu.

Pravce i točke možemo predstaviti kao bipartitan graf. Čvorovi s jedne strane
grafa predstavljaju dobre pravce paralelne s x-osi, a čvorovi s desne strane
grafa predstavljaju dobre pravce paralelni s y-osi. Za svaku točku (x, y) iz
ulaza ćemo postaviti brid između pravca x s lijeve strane i pravca y s desne
strane.

Sada igru možemo predstaviti ovako:


u prvom potezu Mirko odabire neki čvor i briše ga iz grafa
nakon toga Slavko briše bilo koji dosad neobrisani čvor koji je
bio povezan s prošlim obrisanim čvorom
nakon toga Mirko radi isto, i tako naizmjence
gubitnik je onaj koji više ne može ništa obrisati

Budući da se radi o bipartitnim grafovima, za očekivati je da će rješenje


imati veze s maksimalnim uparivanjem na grafu.

Upravo tako!
Ukoliko postoji savršeno uparivanje (uparivanje u kojem je svaki čvor iz
grafa uparen s točno jednim drugim čvorom s kojim dijeli brid) pobijediti će
Slavko, a inače će pobijediti Mirko.

Zašto?
Pretpostavimo da postoji savršeno uparivanje na grafu. Koji god Mirko
odabrao čvor, on će imati para s druge strane grafa, tako da će Slavko uvijek
moći odigrati njega. Dakle, štogod Mirko odigrao, Slavko mu može uzvratiti.
Zato, Mirko nužno gubi.

U slučaju da ne postoji savršeno uparivanje, promatrajmo ono maksimalno.


Mirko može na početku odigrati bilo koji neupareni čvor. Sada će čvor koji
odigra Slavko sigurno imati para (ako ne bi imao para, onda bi mogli
popraviti maksimalno uparivanje tako da spojimo Mirkov i Slavkov odigrani
čvor), pa Mirko može upotrijebiti istu taktiku kao i Slavko u gornjem
paragrafu.

Potrebno znanje: maksimalno uparivanje na bipartitnom grafu

Kategorija: kombinatorika, teorija igara, grafovi

You might also like