You are on page 1of 10

 

 
 
 
 
 
 
 
 

 
 
HRVATSKO OTVORENO NATJECANJE U INFORMATICI 
7. kolo, 7. ožujka 2015. 
 
opisi algoritama 
 
 
Zadatak DUET  Autor: ​
Adrian Satja Kurdija 
 
Ako  je   ​
A  broj  ​
ženskih  natjecatelja  u timu,  očito  je  ​
12  ­  A  broj  ​
muških  natjecatelja. ​
Manji 
od  ovih  dvaju  brojeva  traženi  je  broj  dueta   u  dotičnome  timu:  ne  može  ih biti  više  jer  će 
nedostajati  ženskih  ili  muških  natjecatelja.  Konačno  je  rješenje  zbroj  ovih  minimuma 
min(A,  12  ­  A)  za  sva  četiri  tima.   Alternativno  rješenje  u  samo  jednoj  liniji  Python  koda 
dano je u prilogu. 
 
Potrebno znanje:​  osnovne naredbe 
Kategorija​ : ad­hoc 
 
   
Zadatak TABLICA  Autor: ​
Adrian Satja Kurdija 
 
Lako   zaključujemo  da  valja  ispisati  2R  ­  1  redaka  i  2S  ­  1  stupaca.  Ugnježđenom 
for­petljom  (vanjska  bira  redak,  unutarnja  bira  stupac)  ispisujemo  znak  po  znak. Koji znak 
valja  ispisati?  Ovisi  o  poziciji  na  kojoj  se  nalazimo.  Ako  smo  u  parnome  retku  (nultom, 
drugom,  četvrtom…),  redak  izgleda  ovako:  ​ +­+­+­+​ ...,  a  trenutni  znak  (plus  ili  minus) 
ovisi  o  parnosti  stupca.  Ako  smo  pak  u neparnome retku (prvom, trećem, petom…), redak 
izgleda ovako: ​ |.|.|.|​ ..., a trenutni znak (crta ili točka) ovisi o parnosti stupca. 
 
Potrebno znanje:​  ugnježđena for­petlja 
Kategorija​ : ad­hoc 
 
 
   
Zadatak TETA  Autor: ​
Marin Tomić 
 
Cijene   jela  koja  nisu  na meniju  možemo  samo  pribrojiti  u  konačno  rješenje  i  maknuti  ih s 
pladnja.  Nakon  toga,  pogledamo  koja  sve  jela  s  menija  su  preostala na pladnju i uzmemo 
po  jedan  primjerak  od  svakog.  Ako  je  zbroj  njihovih  cijena   veći  od  cijene  menija,  platit 
ćemo  meni  i  maknuti  jela  s  pladnja,  a  inače  ćemo  platiti  svako  jelo zasebno i maknuti ih s 
pladnja. 
 
Za detalje pogledajte izvorni kod. 
 
Potrebno znanje:​  while­petlja 
Kategorija​ : pohlepni algoritmi 
 
 
   
Zadatak KRIZA  Autor: ​
Ivan Paljak 
 
Naivan  pristup  svodi  se na simulaciju svakog pokušaja otključavanja vrata. Budući da Sizif 
pri  nailasku  na  svaka vrata mora na drugu stranu prebaciti  najviše ​ N ključeva, a posjetio je 
ukupno ​ K​ vrata, složenost takvog algoritma je ​ O(N*K)​  što donosi 40% bodova na zadatku.  
 
Valja  primijetiti  da  dolaskom  do  ​ i​
­tih  vrata  najdesniji  ključ  na  privjesku  otključava vrata  ​ i­1 
te   da  se  između  ključeva  s  oznakama  ​ i  ​
i  ​
j  ​
uvijek  nalazi  konstantan  broj  drugih ključeva. 
Tada  možemo  u  ​ O(1)  saznati  koliko  je  pogrešnih  ključeva  Sizif  stavio  u   vrata  s  nekom 
fiksnom  oznakom   ​ i​
.  To  nas dovodi  do  rješenja  složenosti  ​ O(K)  koja  donose  60%  bodova 
na zadatku.  
Na  kraju,  valjalo  je  primijetiti  da  se  različita  stanja  ključeva  na   privjesku  nužno  ulaze  u 
ciklus  duljine  ​N​.  Popunimo  li  neki niz ​ A[]​
, gdje ​ A[i] ​
govori koliko je pogrešnih ključeva Sizif 
stavio  od  prvih  do  ​ i­​tih  vrata  (za  ​
i  ​
<=  ​
N​
),  možemo  u  ​ O(1)  odgovoriti  na   traženo  pitanje. 
Popunjaanje niza ​ A[] ​ radimo u složenosti ​ O(N)​ , što donosi 100% bodova na zadatku.  
 
Dodatno  je  trebalo  pripaziti  na  prvo  otključavanje,  odnosno  prijelaz  iz  početnog  stanja  u 
stanje  nakon  prvih  vrata  koje  može,  ali  i  nemora  biti  dio   ciklusa  opisanog  u  prošlom 
odlomku. Također, valja primijetiti kako rješenja mogu izači van opsega 32­bitnog broja.  
 
Potrebno znanje:​  Ciklusi 
Kategorija​ : ad­hoc 
 
 
   
Zadatak ACM  Autor: ​
Adrian Satja Kurdija 
 
Rješenje  koje  na sve  moguće  načine  dijeli  niz  zadataka  na  tri  dijela  presporo  je.  Zadatak 
stoga  rješavamo  dinamičkim  programiranjem.  Stanje  je  opisano  zadatkom  na  kojem  se 
trenutno  nalazimo  i  članom  tima  (prvi,  drugi  ili  treći)  kome  je  dodijeljen prethodni zadatak. 
U  prijelazu  biramo   hoćemo  li  i  ovaj  zadatak  dodijeliti  istom  članu  tima  ili  ćemo  prijeći  na 
sljedećeg  člana.  U  priloženom  kodu  dinamika  je  implementirana  rekurzivno,  koristeći 
memoizaciju. Naravno, moguća je i iterativna implementacija. 
 
Potrebno znanje:​  dinamičko programiranje 
Kategorija​ : dinamika 
 
   
Zadatak JANJE   Autor: ​
Ivan Paljak 
 
Primijetimo  najprije  da  svaku  sliku  možemo  predstaviti grafom gdje broj čvorova odgovara 
broju  površina  koje  je  potrebno  ispuniti,  a  dva  su  čvora  povezana  ako  su  odgovarajuće  
dvije  površine   susjedne.  Svakom  čvoru  grafa  potrebno  je  pridružiti  jednu  od  ​ K  boja  na 
način  da   su  dva  susjedna  čvora  različito  obojena   i  iskorištene  su  maksimalno  3  različite 
boje.  
 
Dobar  dio  službenih  test  podataka  sadržavao  je  dovoljno  mali  broj  ​ K  i  sliku  sa  dovoljno 
malim brojem čvorova tako da su naivne implementacije gore  opisanog postupka nosile do 
50% bodova na zadatku.  
 
neka   ​j(n),  d(n)  ​
i  ​
t(n​
)  redom  označavaju  broj  načina  na  koji  je  moguće  ​ n­​tu  sliku  obojiti  
točno  ​ jednom,  ​ točno  ​ dvije  i  ​
točno  ​ tri   različite  boje.  Tada  je  konačno  rješenje  jednako  
j(n)*K  + d(n)*K*(K ­ 1)/2 + t(n)*K*(K­1)*(K­2)/6. ​ Na svim silkama vrijedi  ​ j(n) = 0 pa bojenje 
jednom  bojom  možemo ignorirati.  Ukoliko  je  sliku  moguće  obojiti  u  dvije boje, tada je ​ d(n) 
= 2. Ostaje problem određivanja ​ t(n).  
 
Sve  slike  osim   gusjenice,  piramide  i  trampolina  predstavljamo  grafom  koji   ima  dovoljno 
mali   broj   čvorova  ​ v  da  će  određivanje  broja  ​ t(n)  ​
u  složenosti  ​
O​(3^​
v​
)  biti  dovoljno  brzo. 
Koristeći ovaj pristup mogli ste osvojiti 75 bodova na zadatku.  
 
Valja  istaknuti  kako  je  brojeve  ​ j(n),  ​
d(n)  i  ​
t(n)  bilo moguće izvesti na papiru za svaku sliku 
posebno.  Mnogi  natjecatelji  su  na  taj  način  i  pristupili  zadatku,  ali  su  nerijetko  napravili 
neku pogrešku u izračunu. 
 
Spomenute  3  slike  (gusjenica, piramida  i  trampolin)  valja  detaljnije  analazirati.  Primjerice, 
možemo  primijetiti kako ćemo ispunom drugog reda piramide jednoznačno odrediti ostatak 
piramide. Slične dosjetke na slikama gusjenice i trampolina ostavljamo čitateljici za vježbu.  
 
 
Potrebno znanje:​  grafovi, kombinatorika 
Kategorija​ : ad­hoc 
 
 
   
Zadatak PROSJEK  Autor: Ivan Katanić 
 
Direktno odgovaranje na pitanje koji je najveći mogući  prosjek je težak problem, no što ako 
umjesto   toga  pokušamo  odgovoriti  na  pitanje  je   li  najveći  mogući  prosjek  veći  ili  jednak 
nekoj  vrijednosti  P. Ako  to  uspijemo onda zadatak možemo rješiti binarnim pretraživanjem 
po vrijednosti P. 
 
I  taj  problem  izgleda  teško,  no  primjetimo  ovo:  ako  svim  brojevima  u  nizu  oduzmemo  X, 
tada  će  se  i  prosjek svih  podnizova  smanjiti  za  točno  X.  Sada  možemo  svim brojevima u 
nizu   oduzeti  vrijednost  P  i  ono  što  nas  zanima  jest  postoji  li  podniz s  prosjekom  većim  ili 
jednakim  0.   Taj  problem  je  jednostavniji  jer  je  to  ekvivalentno  pitanju  postoji li  podniz  sa 
sumom većom ili jednakom nuli. 
 
Ako  izračunamo  prefiks sume  S  ulaznog  niza,  tada  je  suma  nekog  podniza  [a, b] jednaka 
S[b]  ­  S[a­1].  Za  svaki  mogući  b  možemo  se pitati postoji li a takav  da je S[b]  ­  S[a­1] >= 0 
tj.  S[b] >= S[a­1] te, ne zaboravimo uvjet na minimalnu  duljinu podniza, da je b­a+1 >= K tj. 
a <= b+1­K. 
 
Prolazeći  vrijednostima  granice  b  slijeva  na  desno  u  posebnoj  varijabli  možemo  držati 
najmanju  dosad  viđenu  vrijednost  S[a­1]  i  provjeravati  zadovoljava  li  ona  uvjet  za  trenutni 
b, ako zadovoljava pronašli smo podniz s prosjekom većim ili jednakim P. 
Pri  svakom  povećanju vrijednosti b za 1 točno jedna nova vrijednost za a dolazi u obzir i to 
je  a  =  b­K+1.  Održavanje  varijable  onda  radimo  tako  da  pri  svakom povećanju  vrijednosti 
provjerimo je li S[b­K] manji od trenutne najmanje vrijednosti te ju osvježimo ako jest.  
Za detalje pogledati priloženi kod. 
 
Potrebno znanje:​  binarno pretraživanje, matematika 
Kategorija​ : razno 
 
   
Zadatak POLICE  Autor: ​
Mislav Bradač 
 
Prvo  što  moramo  provjeriti   je  postoji li  prazno  mjesto  na  bilo  kojoj  polici.  U  slučaju  da  ne 
postoji  provjeravamo  jesu  li  sve  knjige  na  pravom  položaju,  ako  nisu,  nema  rješenja  te 
ispisujemo ­1, inače je rješenje 0. 
 
Pogledajmo  kako  riješiti  test  podatke vrijedne 50% bodova u kojima za svaku knjigu vrijedi 
da je na istoj polici na početku i na kraju. Police dijelimo u tri kategorije: 
1. polica na kojoj na početku postoji prazno mjesto 
­ k​  ­ broj knjiga na polici 
­ lis​  ­  najdulji podniz knjiga koji su na početku u dobrom relativnom poretku 
­ svaku  knjigu  koja  se  ne  nalazi  u  ​ lis​­u  moramo  podići  da  bi  posložili  knjige 
na toj polici, tj. treba nam ​ k ­ lis​
 dizanja 
­ primijetimo   da  uvijek   guranjem  knjiga  možemo  osloboditi  poziciju  na  polici 
na koju moramo staviti knjigu prije nego ju podignemo 
­ lis  lako  nalazimo  u  ​ O(k  log  k)  poznatim  algoritmom  za  traženje  najdužeg  
rastućeg podniza 
2. polica je puna, ali sve su knjige na svome mjestu 
­ za police ove vrste nam ne treba nijedno dizanje 
3. polica je puna, ali postoji knjiga koja nije na svom mjestu 
­ jednu  knjigu  koja  se  ne  nalazi  u  ​ lis​­u  prebacimo  na prazno mjesto na nekoj 
drugoj polici 
­ posložimo   ostale  knjige  na  polici u  pravi  poredak,  pri  tome  ne  dižući  knjige 
koje se nalaze u lis­u 
­ vraćamo knjigu koju smo prebacili na neku drugu policu na pravu poziciju 
­ za police ove vrste nam treba ​ k ­ lis + 1​  podizanje 
 
U  test  podacima  u  kojima  postoje  knjige  koje  se  na  početku  i  na  kraju  ne  nalaze  na  istoj 
polici podijelit ćemo police u 2 kategorije: 
1. police  na  kojima  su  knjige  koje  se  nalaze  na  početku  i  na  kraju na  toj  polici  te  se 
svaka knjiga koja se na kraju nalazi na toj polici nalazila i na početku 
­ ove  police  rješavamo  na  isti  način  na  koji  smo  rješavali  i  u  test  podacima 
vrijednim 50% bodova 
2. ostale police 
 
Sada  nam  preostaje  riješiti drugu kategoriju polica. Izgradimo neusmjereni graf u kojem su 
police  čvorovi.  Dva   čvora  su  povezana  ako  postoji  knjiga  koja  se  na  početku  nalazi  na 
polici koju predstavlja prvi čvor, a na kraju na polici koju predstavlja drugi čvor. 
 
Sada  ćemo  svaku  komponentu  tog  grafu  riješiti  posebno  te  ćemo  ponovo  uvesti  dva 
slučaja: 
1. sve police u komponenti su na početku pune 
­ izgradimo  sada  usmjereni  graf  ove  komponente  tako   da  usmjerimo  brid  iz 
čvora  u  kojeg  dolazi  knjiga  (čvor u  kojem  je  knjiga  na  kraju)  u  čvor  iz  kojeg 
dolazi knjiga (čvor u kojem je knjiga na početku) 
­ primijetimo   da  će  svaki  čvor   imati  isti  indegree  i  outdegree  te  da  možemo  
izgraditi eulerov ciklus 
­ jednu  knjigu  iz  nekog  čvora  ​A  koja  se  ne  nalazi  na  istoj  polici  na početku  i 
na  kraju  stavljamo  na  prazno  mjesto  na  neku  policu  koja  ima  slobodno 
mjesto u tom trenutku 
­ krećemo  iz  čvora  ​ A  i  krećemo se eulerovim ciklusom, kad pređemo iz čvora 
A​  u čvor ​B​ prebacimo knjigu iz čvora ​ B​  u čvor ​

­ tijekom   obilaska   eulerovog  ciklusa  u  trenutku  kada  neka  polica  ima 
slobodno  mjesto  knjige  koje  se  na  toj  polici  nalaze   na  početku  i  na  kraju 
stavljamo  u  dobar  relativni  poredak  ­  to  radimo  na  način  opisan  u  prvoj 
kategoriji u rješenju za 50% bodova 
­ sum_k​  ­ broj knjiga na policama u toj komponenti 
­ sum_lis​  ­ suma ​lis​
­ova pojedinih polica te komponente 
­ treba nam ​ sum_k ­ sum_lis + 1​  podizanje da riješimo ovu komponentu 
­ primijetimo  da  uopće  ne  trebamo graditi eulerov ciklus jer se od  nas ne traži 
rekonstrukcija rješenja 
 
2. postoji polica u komponenti koja na početku nije potpuno puna 
­ izaberimo  neki   čvor  koji  ima  veći  indegree  od  outdegreea  te  neki  čvor koji 
ima  veći  outdegree  od  indegreea  te  dodamo   dummy  brid  između  ta  dva 
čvora 
­ ovaj postupak ponavljamo sve dok postoje takvi čvorovi 
­ izgradimo  eulerov  ciklus  te  krenemo  od  čvora  koji  ima  prazno   mjesto  na 
početku,  ako  prođemo  pravim  bridom  prebacujemo  knjigu,  ako  prođemo 
dummy bridom ništa ne prebacujemo 
­ važno  je  primijetiti  da će  uvijek  postojati  prazno  mjesto  u  čvoru  u  kojem  se 
nalazimo  čak  i  ako  smo  u  taj  čvor  došli  dummy  bridom,  to  vrijedi  zbog 
činjenice  da  ako  polica  ima  veći  outdegree  od   indegreea  onda  je  broj 
slobodnih  mjesta na početku na toj polici veći jednak od razlike outdegreea i 
indegreea 
­ knjige  koje  su  na  istoj  polici  na  početku  i  na  kraju  rješavamo  na  isti  način 
kao i u prethodnom slučaju 
­ treba nam ​ sum_k ­ sum_lis​  podizanja da riješimo ovu komponentu 
 
Ukupna složenost algoritma je O(N * M * log M). 
 
Potrebno znanje:​  dfs, longest increasing subsequence 
Kategorija​
: kombinatorika, grafovi 
 

You might also like