Rjesenja

You might also like

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

HRVATSKO OTVORENO NATJECANJE IZ

INFORMATIKE 2012/2013

6. KOLO

OPISI ALGORITAMA
HONI 2012/2013 Zadatak VRT
6. kolo, 9. ožujka 2013. Autor: Adrian Satja Kurdija

Primijetimo da je zapravo potrebno iz veličine opsega i duljine jedne


stranice pravokutnika izračunati drugu stranicu pravokutnika.

Označimo duljinu tražene nepoznate stranice pravokutnika sa X.


Tada je D + X očito poluopseg pravokutnika (O / 2) pa je X = O / 2 - D.

Potrebno znanje: unos/ispis prirodnih brojeva, osnovne računske


operacije

Kategorija: ad hoc
HONI 2012/2013 Zadatak POVIJEST
6. kolo, 9. ožujka 2013. Autor: Nikola Dmitrović

Uočimo da je za rješenje ovog zadatka potrebno prvo provjeriti da li se


među četiri zadana broja nalaze tri različite vrijednosti. To možemo
napraviti provjeravanjem svih mogućih situacija.

Pretpostavimo da smo brojeve označili oznakama a, b, c, d. Tada treba


provjeriti koliko je sljedećih izraza bilo istinito: a ≠ c, a ≠ d, b ≠ c, b ≠ d.
Ako je broj istinitih izraza bio tri, tada je moguće odrediti sva tri broja,
poredati ih po veličini i ispisati.

Postoji i jednostavnije rješenje. Niz od 30 komponenti (toliko ima učenika


u razredu) inicijaliziramo na vrijednost nula. a-tu, b-tu, c-tu i d-tu
komponentu promijenimo u vrijednost jedan. Ako je zbroj elemenata u
nizu jednak tri, tada je jasno da postoje tri različita broja. Sortirani ispis
jednostavno se dobije slijednim prolaženjem kroz niz i ispisivanjem
indeksa komponente čija je vrijednost jedan. Ako je zbroj komponenti u
nizu jednak dva, tada treba ispisati zadanu poruku.

Potrebno znanje: naredba učitavanja i ispisivanja, naredba odlučivanja,


naredba ponavljanja (dodatno: nizovi)

Kategorija: ad hoc
HONI 2012/2013 Zadatak BAKA
6. kolo, 9. ožujka 2013. Autor: Adrian Satja Kurdija

Potrebno je učitati dani string, proći po njegovim znakovima for-petljom i


za svaki znak (slovo) odrediti na kojoj se znamenki telefona nalazi.

Načinimo pomoćni string u kojem se nalaze početna slova svih tipki (A, D,
G, J, M, P, T, W). Za promatrano bakino slovo proći ćemo po pomoćnom
stringu i u njemu naći posljednje slovo koje je od promatranoga manje ili
jednako (to će npr. biti slovo M ako je promatrano slovo O, ili slovo T ako
je promatrano slovo T). Time smo zapravo zamijenili promatrano slovo
početnim slovom koje pripada istoj znamenki. Sada traženu znamenku Z
određujemo iz pozicije pronađenog slova u pomoćnom stringu te konačno
rješenje uvećavamo za Z + 1.

Potrebno znanje: rad sa stringom, ugniježđena for-petlja

Kategorija: ad hoc
HONI 2012/2013 Zadatak SUME
6. kolo, 9. ožujka 2013. Autor: Adrian Satja Kurdija

Slučaj N = 2 ostavljamo čitateljima za vježbu. Ako je N barem 3,


promatrajmo prva tri (zasad nepoznata) elementa niza i njihove
međusobne sume (pročitane iz tablice):

a + b = s1,
b + c = s2,
c + a = s3.

Zbrajanjem ovih jednakosti dobivamo 2a + 2b + 2c = s1 + s2 + s3, a


odatle a + b + c = (s1 + s2 + s3) / 2.

Sada je a = (a + b + c) - (b + c) = (s1 + s2 + s3) / 2 - s2.

Znajući prvi element niza, lako nalazimo i ostale: i-ti element jednak je
sumi prvog te i-tog elementa (koju čitamo iz dane tablice) umanjenoj za
prvi element.

Želimo li izbjeći gornje matematičko zaključivanje, ograničenja za


elemente dana u zadatku dozvoljavaju nam da isprobamo sve moguće
vrijednosti za prvi element niza. Za svaku od tih mogućnosti generiramo
ostale elemente niza kao u prethodnome odlomku i testiramo ispravnost
dobivenog niza zbrajajući bilo koja dva elementa različita od prvoga. Zašto
je takav test dovoljan, razmislite sami.

Za vježbu razmislite o istom zadatku u kojem su mogući i slučajevi da


nema rješenja te da postoji beskonačno mnogo rješenja (takve slučajeve
potrebno je detektirati).

Potrebno znanje: matematička analiza problema

Kategorija: matematika
HONI 2012/2013 Zadatak DOBRI
6. kolo, 9. ožujka 2013. Autor: Ivan Mandura

Naivno rješenje koje za svaku poziciju i iskuša sve moguće trojke presporo je. To je rješenje
složenosti O(N4) i nosi 40% bodova.

Budući da su brojevi u nizu maleni, možemo održavati niz P koji će nam reći postoji li neki broj u
nizu do pozicije i, odnosno P[x] = 1 ako broj x postoji u nizu A do pozicije i, inače P[x] = 0.
Pomoću njega možemo ubrzati naše početno rješenje. Umjesto da iskušamo svaku moguću
trojku, iskušamo svaki mogući par pozicija (j, k) manjih od i i pitamo se, postoji li broj A[i] ­ A[j] ­
A[k] u nizu do pozicije i. Taj podatak spremljen je u nizu P na poziciji A[i] ­ A[j] ­ A[k]. Nakon
obrade pozicije i, P[A[i]] postavimo na 1. Ovom optimizacijom ostvarujemo rješenje vremenske
složenosti O(N3) koje nosi 70% bodova.

Za 100% bodova treba nam algoritam vremenske složenosti O(N2). Umjesto da se za svaki par
brojeva (j, k) pitamo postoji li broj A[i] ­ A[j] ­ A[k] u nizu do pozicije i, možemo se za svaku
poziciju j pitati postoji li par brojeva brojeva do pozicije i takvih da je njihova suma jednaka A[i] ­
A[j]. Ponovno za odgovor na to pitanje možemo koristiti niz P, jer suma dva mala broja je
ponovno malen broj. Nakon obrade pozicije i, za sve parove (i, j) postavimo P[A[i] + A[j]] na 1.
Ovom optimizacijom dobivamo traženu složenost za sve bodove.

Primijetimo da je prostorna složenost algoritma O(max Ai), no da su u zadatku bili zadani veliki
brojevi, mogli bismo koristiti balansirano stablo umjesto niza P. U jeziku C++ ponuđene su nam
strukture set i map. Time bismo dobili rješenje prostorne složenosti O(N) i vremenske O(N2 log
N); takvo rješenje u ovom zadatku nosilo je 70% bodova.

Potrebno znanje: operacije nad nizovima

Kategorija: ad hoc
HONI 2012/2013 Zadatak BUREK
6. kolo, 9. ožujka 2013. Autor: Adrian Satja Kurdija

Promatrajmo samo rezove oblika x = c (rješenje za rezove oblika y = c bit


će analogno).

Primijetimo da su bureci prerezani pravcem x = c točno oni koji su nisu ni


posve lijevo, ni posve desno od tog pravca. Drugim riječima, rješenje za
taj pravac iznosi

N - broj_bureka_lijevo_od(c) - broj_bureka_desno_od(c).

Vrijednosti funkcija broj_bureka_lijevo_od(x) i broj_bureka_desno_od(x)


izračunat ćemo prije učitavanja rezova (stoga ćemo na svaki rez odgovoriti
u konstantnoj složenosti). Vrijednosti računamo uz pomoć očite relacije

broj_bureka_lijevo_od(x) = broj_bureka_lijevo_od(x - 1) +
broj_bureka_kojima_je_najdesnija_točka_jednaka(x)

i analogne relacije za drugu funkciju. Pritom vrijednosti pomoćne funkcije


broj_bureka_kojima_je_najdesnija_točka_jednaka(x) čitamo iz niza čije
elemente povećavamo prilikom unosa samih bureka.

Alternativno rješenje koristi sweep-line pristup te ga ostavljamo


čitateljima za vježbu.

Potrebno znanje: korištenje pomoćnih nizova i njihovo pripremanje


unaprijed (precomputing)

Kategorija: sweep
HONI 2012/2013 Zadatak JEDAN
6. kolo, 9. ožujka 2013. Autor: Anton Grbin

Stepenastu piramidu, odnosno reljef, možemo promatrati kao histogram.


Histogram je valjan ako ga je moguće dobiti potezima opisanima u zadatku.
Primjetimo prvo da je svaki histogram valjan ako i samo ako vrijede sljedeća tri
uvjeta:
● prvi i zadnji stupić visine su 0
● razlika visina susjedna dva stupića najviše je 1
● svi su stupići nenegativni

Dokaz
Vidljivo je da potez u zadatku ne narušava ova tri uvjeta. Prvi zbog toga što nikada
ne izdižemo prvi ili zadnji interval, drugi zbog toga što izdizanje radimo za jedan i
to na onom intervalu u kojem su sve visine jednake i ne diramo rub intervala. Treći
jer reljef samo povećavamo.
Zbog toga što inicijalna situacija zadovoljava uvjete i što ih potez ne narušava,
dokazali smo jednu stranu dokaza.

U obratu treba dokazati da je svaki valjani histogram moguće dobiti nekom serijom
poteza.
U valjanom histogramu odaberimo sve stupiće visine 0. Takvih ima najmanje dva, a
to su prvi i zadnji. Između svake dvije ne-susjedne nule "odigramo potez" tako da
sve stupiće između tih nula smanjimo za jedan. Budući da vrijedi uvjet da je razlika
visina svaka susjedna dva stupića najviše jedan, u histogram smo dodali barem
dvostruko novih nula od poteza koje smo napravili. Postupak ponavljamo dok svi
stupići u histogramu ne poprime visinu 0. Poteze koje smo napravili su potezi s
kojima se konstruira početni histogram. Time je tvrdnja dokazana.

Rješenje
Rješenje je moguće konstruirati u kvadratnoj složenosti pamteći u stanju broj
načina na koji je moguće složiti prvih K stupića tako da zadnji stupić ima visinu H.
Budući da visina zadnjeg stupića ovisi isključivo o predzadnjem, relacija je
konstantne složenosti. Rješenje je memorijski najefikasnije implementirati
iterativno, pamteći samo O(n) stanja prethodnih iteracija.

Potrebno znanje: matematička analiza, dinamičko programiranje

Kategorija: dinamičko programiranje


HONI 2012/2013 Zadatak BAKTERIJE
6. kolo, 9. ožujka 2013. Autor: Ivan Katanić

Promatrajmo jednu bakteriju: njezino stanje možemo opisati trima


parametrima X, Y i C, gdje X i Y predstavljaju oznaku retka odnosno
stupca polja u kojem se bakterija trenutno nalazi, a C označava smjer u
kojem je bakterija okrenuta. Ako simuliramo kretanje bakterije, možemo
primijetiti da će se bakterija u jednom trenutku naći u stanju u kojemu je
već bila i, budući da se pravila kretanja ne mijenjaju, bakterija je zatvorila
petlju u kojoj će kružiti zauvijek (ili do kraja igre). Put bakterije bit će
oblika kao na slici:

Kružići predstavljaju stanja bakterije, a strelice njezino kretanje. Dio puta


koji nije u petlji zovemo “rep”. Neka Li broj stanja u petlji i-te bakterije, a
Ti,X,Y,C sekunda u kojoj se bakterija prvi put našla u stanju (X, Y, C). Ako
je stanje (X, Y, C) na “repu”, tada je ta sekunda ujedno i jedina u kojoj se
bakterija nalazi u stanju (X, Y, C), a ako je u petlji, tada će se u njemu
nalaziti u sekundama t = Ti,X,Y,C + k * Li, k ≥ 0.

Pretpostavimo da će se u posljednjoj sekundi igre bakterija i nalaziti u


stanju (Xe, Ye, Ci), gdje Xe, Ye označava polje sa zamkom. Ako se neka od
bakterija prvi i jedini put (bez obzira na kraj igre) nalazi u tom stanju,
tada je trivijalno provjeriti hoće li se ostale bakterije nalaziti u završnom
stanju u toj sekundi. U suprotnom, imamo sljedeći sustav od K jednadžbi:

t = Ti,X,Y,C + ki * Li, ki ≥ 0

koji se može zapisati na drugi način pomoću kongruencija:

t ≡ Ti,X,Y,C (mod Li), uz uvjet t ≥ Ti,X,Y,C.


Ovaj poznati problem rješava se uz pomoć Kineskog teorema o ostacima
(http://en.wikipedia.org/wiki/Chinese_remainder_theorem). Budući da
teorem nudi rješenje ako su moduli (u našem slučaju Li) relativno prosti,
prije svega moramo svaki Li rastaviti na relativno proste faktore (potencije
prostih brojeva) čime ćemo dobiti veći broj jednadžbi ali će moduli sada
biti relativno prosti. U slučaju da se među modulima nalaze dvije potencije
istog prostog broja p, manju možemo eliminirati jer je ostatak pri
dijeljenju s njom jednoznačno određen iz ostatka pri dijeljenju s većom
(ako se ne podudaraju, rješenje ne postoji). Nakon što smo pronašli
rješenje, ne smijemo zaboraviti na uvjete t ≥ Ti,X,Y,C : ako ih naše rješenje
t ne zadovoljava, samo ga dovoljan broj puta povećamo za umnožak svih
modula jer Kineski teorem o ostacima kaže da su sva rješenja sustava
kongruentna s tim umnoškom. Budući da su duljine svih petlji parne
duljine te da je najveća moguća duljina petlje 10 000, spomenuti
umnožak, kao i rješenje sustava, stat će u 64-bitni cjelobrojni tip podatka
s predznakom.

Sada jednostavno isprobamo svih 4K kombinacija za treći parametar Ci


završnih stanja i uzmemo ono koje daje najmanje rješenje.

Potrebno znanje: Kineski teorem o ostacima

Kategorija: matematika

You might also like