Rjesenja

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 9

HRVATSKO OTVORENO NATJECANJE IZ

INFORMATIKE 2012/2013

3. KOLO

OPISI ALGORITAMA
HONI 2012/2013 Zadatak KNJIGA
3. kolo, 15. prosinca 2012. Autor: Adrian Satja Kurdija

S sati sadrži S * 60 minuta.


D dana sadrži D * 24 sata, a to je D * 24 * 60 minuta.
Valja dakle ispisati broj M + S * 60 + D * 24 * 60.

Potrebno znanje: naredbe unosa i ispisa, osnovne računske operacije

Kategorija: ad hoc

HONI 2012/2013 Zadatak MNOGOKUT


3. kolo, 15. prosinca 2012. Autor: Adrian Satja Kurdija

Razmatranje dijelimo na dva slučaja:

1) A > B. Ovdje možemo putovati:


i) od B do A u CW smjeru duž A - B stranica,
ii) od B do A u CCW smjeru duž preostalih N - (A - B) stranica.
Preostaje nam odabrati opciju s manjim brojem stranica.

2) A < B. Ovdje možemo putovati:


i) od B do A u CCW smjeru duž B - A stranica,
ii) od B do A u CW smjeru duž preostalih N - (B - A) stranica.
Preostaje nam odabrati opciju s manjim brojem stranica.

Potrebno znanje: ugnijeđžene naredbe grananja (if - then)

Kategorija: ad hoc
HONI 2012/2013 Zadatak ŠAHOVNICA
3. kolo, 15. prosinca 2012. Autor: Adrian Satja Kurdija

Postoji više mogućih pristupa problemu: možemo koristiti znakovnu matricu,


ali i ne moramo.

Prvi pristup.

Pomoću dviju for-petlji, od kojih jedna prolazi po ukupnom broju redaka a


druga (unutar prve) po ukupnom broju stupaca, ispisujemo odgovarajuće
znakove. Ovdje nam je potrebna funkcija koja će nam za trenutni redak i
stupac (r, s) reći je li odgovarajući znak crveni ili bijeli.

Primijetimo da, počnemo li brojati retke i stupce od 0 (što znači


0 ≤ r < R * A te 0 ≤ s < S * B), transformacijom (r, s) → (r div A, s div B)
dobivamo red i stupac traženog većeg obojenog polja (taj red je iz intervala
0 ≤ r div A < R, a stupac iz intervala 0 ≤ s div B < S). Nije teško zaključiti
da je to polje crveno ukoliko je zbroj reda i stupca (r div A + s div B) paran,
a inače je bijelo.

Drugi pristup.

Koristimo znakovnu matricu u koju crtamo jedno po jedno veće obojeno


polje. Dotično veće polje biramo dvjema for-petljama te ga potom crtamo
unutar tražene matrice, ponovno dvjema for-petljama. Potrebno je pritom
izračunati početne koordinate traženog većeg polja: one iznose (1 + r * A,
1 + s * B) pri čemu su r i s (0 ≤ r < R, 0 ≤ s < S) red i stupac većeg polja,
a naša znakovna matrica numerirana od (1, 1).

Potrebno znanje: ugniježđene for-petlje, uočavanje jednostavnih


matematičkih principa

Kategorija: ad hoc
HONI 2012/2013 Zadatak POREDAK
3. kolo, 15. prosinca 2012. Autor: Adrian Satja Kurdija

Potrebno je učitati dva niza od po N stringova i potom za svaka dva stringa u


prvom nizu pronaći pozicije istih stringova u drugom nizu. Ako su pozicije u
ispravnom poretku, rješenju pribrajamo 1; na koncu ispisujemo rješenje.

Kako pronaći poziciju stringa u drugom nizu? Jedan je način pomoću for-
petlje, no vremenska složenost algoritma tada iznosi: O(N2) za odabir svih
parova stringova u prvom nizu, puta O(N) za pronalazak pozicija odabrana
dva stringa u drugom nizu (zanemarit ćemo složenost usporedbe stringova,
koja je proporcionalna njihovoj duljini), što ukupno iznosi O(N3). Za dano
ograničenje broja N takav program bit će prespor.

Da bismo složenost smanjili na O(N2), nakon odabira para stringova


potrebno je odmah (u konstantnom vremenu) za bilo koji k-ti string prvog
niza znati njegovu poziciju u drugom nizu. Te stoga pozicije valja izračunati
unaprijed.

Možemo primjerice, prije traženja rješenja, za svaki k-ti string iz prvog niza
for-petljom pronaći njegovu poziciju u drugom nizu i spremiti je u pomoćni
niz. Ovo zvuči slično gornjemu, ali postoji bitna razlika: ovdje po drugom
nizu prolazimo O(N) umjesto O(N2) puta. Složenost ispada O(N) puta O(N)
za opisano generiranje pomoćnog niza, plus O(N2) za provjeru svih parova,
što je ukupno O(N2), a to je dovoljno brzo.

Iako za dana ograničenja to nije bilo nužno, pozivamo čitatelje da osmisle


još brže, O(N log N) rješenje.

Potrebno znanje: uspoređivanje stringova, princip precomputinga


(računanja pomoćnih podataka prije računanja rješenja)

Kategorija: ad hoc
HONI 2012/2013 Zadatak MALCOLM
3. kolo, 15. prosinca 2012. Autor: Adrian Satja Kurdija

Rješenje koje za svaki uneseni string prolazi po prethodnih K stringova i


broji one s jednakim brojem slova da bi odgovarajuće parove pribrojilo
traženom rješenju – presporo je.

Brže rješenje učitava string, broji njegova slova – označimo njihov broj sa D
– i potom odmah, bez nove for-petlje, odgovara na pitanje: koliko od
prethodnih K stringova ima točno D slova?

Da bismo na to pitanje mogli brzo odgovoriti, u pomoćnom ćemo nizu držati


traženi broj za svaki D. Taj niz, naravno, treba i održavati: pojavom novog
stringa duljine D povećat ćemo D-ti član pomoćnog niza za 1, dok ćemo
D’-ti član niza smanjiti za 1, pri čemu je D’ duljina stringa koji je upravo
“ispao” iz intervala od posljednjih K stringova, tj. više ne ulazi u skup
prijatelja dolaznih stringova.

Ovo rješenje zapravo koristi sweep-line princip: zamišljeni skener prolazi


rang listom i obrađuje događaje poput: dolazi novo ime, ime izlazi iz skupa
potencijalnih prijatelja.

Potrebno znanje: korištenje pomoćnog niza radi ubrzanja algoritma

Kategorija: sweep
HONI 2012/2013 Zadatak AERODROM
3. kolo, 15. prosinca 2012. Autor: Adrian Satja Kurdija

Moguće je implementirati rješenje koje za svaku osobu (dovoljno brzo)


računa šalter na kojem bi ta osoba najranije bila registrirana. To se može
ostvariti npr. korištenjem strukture priority_queue; detalje prepuštamo
čitateljima. Ovakvo rješenje ima vremensku složenost O(M log N).
Primijetimo da je ovo, pohlepno rješenje ujedno i točno: ako svaka osoba
odabere šalter koji je njoj najpovoljniji, moguće ih je poredati tako da ne
moraju nepotrebno čekati jedna na drugu, pa će takvo ponašanje biti
najbolje za čitav tim. Razmislite zašto.

Kakvo god bilo, gornje rješenje ne radi dovoljno brzo za M = 1 000 000 000.
Dovoljno brzo rješenje, složenosti O(N log M), koristi binarno pretraživanje:
zanima nas najranije vrijeme u kojem se svi ljudi mogu registrirati, a u
stanju smo za bilo koje vrijeme T provjeriti je li ono manje ili veće od
traženog, odnosno – može li se M ljudi u vremenu T registrirati, ili ne može.

Kako to provjeriti? Za svaki šalter k izračunamo koliko osoba on može


registrirati u vremenu T (što iznosi T div Tk) i dobivene brojeve zbrojimo.
Ako je zbroj veći ili jednak M, možemo registrirati M ljudi (uz pretpostavku
da dovoljno pametno biraju šaltere), a u suprotnom očigledno ne možemo.

Algoritam bi sada trebao biti jasan: održavamo donju i gornju granicu za


traženo vrijeme, biramo broj T koji je prosjek ovih granica, računamo (kao u
gornjem odlomku) je li on veći ili manji od traženog rješenja i na temelju
toga pomičemo donju ili gornju granicu na T, prepolavljajući tako interval
potencijalnih rješenja dok u njemu ne ostane samo jedan broj.

Potrebno znanje: binarno pretraživanje

Kategorija: binarno pretraživanje


HONI 2012/2013 Zadatak HERKABE
3. kolo, 15. prosinca 2012. Autor: Adrian Satja Kurdija

Prvo rješenje.

Od danih riječi izgradimo prefiks stablo (http://en.wikipedia.org/wiki/Trie).


Zamislimo da se nalazimo u korijenu stabla i da vidimo M podstabala. U
svakom podstablu riječi započinju istim slovom, a to se slovo za svih M
podstabla razlikuje: zbog toga moramo najprije odabrati sve riječi iz jednog
podstabla, pa sve riječi iz drugog, pa sve riječi iz trećeg i tako dalje. Drugim
riječima, imamo zasebnih M potproblema koje ćemo riješiti rekurzivno.

Ako smo za k-to podstablo rekurzijom ustanovili da je njegove riječi


moguće poredati na Ak načina, ukupan broj poredaka za sva podstabla
istodobno umnožak je tih brojeva (A1 * A2 * … * AK). Potom biramo poredak
samih podstabala (blokova njihovih riječi), a njih je M!, što valja uključiti u
umnožak.

Prefiks stablo valja pažljivo implementirati tako da bude dovoljno brzo i da


ne zauzima previše memorije.

Drugo rješenje.

Idejno slično, ali implementacijski jednostavnije rješenje (bez prefiks


stabla). Sortirajmo riječi po abecedi. Pogledajmo prvo slovo svih riječi: naći
ćemo M blokova takvih da sve riječi bloka imaju isto prvo slovo. Kao u
prvom rješenju, konačni rezultat iznosi M! puta umnožak rekurzivno
dobivenih rezultata za pojedine blokove.

U rekurziji, za svaki od spomenutih blokova valja nam izdvojiti njegove


blokove. No sada prvo slovo promatranih riječi možemo zanemariti, jer
znamo da je jednako u svim tim riječima, pa možemo promatrati samo
druga slova riječi. Analogno, u sljedećoj dubini rekurzije dovoljno je
promatrati samo treća slova riječi. Zaključujemo da je složenost algoritma
proporcionalna ukupnom broju slova. Jasno, ovdje će rekurzija kao
parametre primati donju i gornju granicu promatranog bloka te redni broj
slova koje nam je promatrati.

Potrebno znanje: rekurzija, prefiks stablo

Kategorija: stringovi
HONI 2012/2013 Zadatak PROCESOR
3. kolo, 15. prosinca 2012. Autor: Ivan Katanić

Promatrajmo N 32-bitnih registara kao N * 32 binarnih varijabli.


Na prvi pogled zadatak izgleda kao klasičan primjer 2SAT problema
(http://en.wikipedia.org/wiki/2-satisfiability). Međutim, zbog malog
vremenskog i memorijskog ograničenja takvo rješenje ne donosi sve bodove
na zadatku.

Primijetimo: ako postoji neko rješenje, onda postoji barem još jedno, a
njega dobijemo tako da invertiramo bitove svim registrima u prvom rješenju.

Zbog toga je točan sljedeći algoritam:


1. Pronađi neku dosad neriješenu varijablu b.
2. Postavi vrijednost b po izboru (0 ili 1).
3. Postavi vrijednost svim binarnim varijablama koje su ikada
XOR-ane s varijablom b jer ih sada možemo jednoznačno
odrediti.
4. Ako više nema neriješenih varijabli, prekini algoritam; inače se
vrati na korak 1.

Ako u 3. koraku postavljamo vrijednost nekoj varijabli, a ona u tom trenutku


već ima postavljenu suprotnu vrijednost, došlo je do kontradikcije i rješenje
ne postoji. Možemo primijetiti da će do postavljanja obje takve suprotne
vrijednosti doći u istom koraku 3, jer su zbog XOR-a implikacije dvosmjerne.

U početku dakle možemo bilo koju varijablu postaviti na 0 ili 1, zbog


postojanja barem dvaju rješenja sa suprotnim vrijednostima svih varijabli.
Nakon odrađenih preostalih triju koraka algoritma, ostajemo s manjim
skupom neriješenih varijabli koji više nema veze s dosad obrađenim
varijablama pa možemo primijeniti isto pravilo (postoje barem dva rješenja)
te ponovo postaviti vrijednost bilo koje varijable na 0 ili 1 itd.

Odabir neriješene varijable i njene vrijednosti u 1. koraku obavljat ćemo


tako da dobijemo leksikografski najmanje rješenje: pronalazimo
najznačajniji bit prvog registra čije varijable nisu u potpunosti riješene te
njegovu vrijednost postavljamo na 0 i prelazimo na korak 2.
Zbog manjeg memorijskog ograničenja potrebno je korak 3 implementirati
iterativno (npr. s redom). Vremenska je složenost rješenja O(N + O).

Potrebno znanje: manipulacije bitmaskama, red (queue)

Kategorija: ad-hoc

You might also like