You are on page 1of 97

Univerzitet u Sarajevu

Elektrotehniki fakultet u Sarajevu


KANTONALNO TAKMIENJE IZ INO!MATIKE
ZA S!E"NJE #KOLE
ZA"A$I ZA %!I%!EMU SA !JE#ENJIMA
%rire&ili'
(r )e&ran Lju*ovi+, &i-l. in/. el.
Alvin A*&a/i+, MoE 0 &i-l. in/. el.
Marko Lali+
A(er Me1anovi+
"o2. &r Sa(i( Konji2ija, &i-l. in/. el.
Sarajevo, Mart 3453. /o&ine
1
Ovaj dokument e biti aktivno doraivan. Posljednja verzija dokumenta bit e dostupna na stranici
http://takmicenje.etf.unsa.ba. Trenutna verzija dokumenta je: 6.5.
Sa&r7aj'
P!"#$! %!&TO&!$&O' T!%(#)*&+! #, #&-O(!T#%*.................................................................
/#$!01/ %!&TO&!$&O' T!%(#)*&+! #, #&-O(!T#%*.................................................................2
1./trate3ija rje4avanja pro3ramskih zadataka.............................................................................................................11
,adatak 1.1. Prethodni i sljedei datum................................................................................................................11
,adatak 1.5. azlika datuma...................................................................................................................................16
,adatak 1.7. imski brojevi....................................................................................................................................55
,adatak 1.8. &umeri9ka matematika.....................................................................................................................58
,adatak 1... 0azen :jednostavnija varijanta;........................................................................................................52
5.Operacije s nizovima..................................................................................................................................................5<
,adatak 5.1. &ajvei meu najmanjima................................................................................................................5<
,adatak 5.5. =isto3ram...........................................................................................................................................7>
,adatak 5.7. Operacije sa skupovima....................................................................................................................75
7.Prosti brojevi................................................................................................................................................................77
,adatak 7.1. azdvojiti proste od slo?enih..........................................................................................................77
,adatak 7.5. %azna...................................................................................................................................................7@
,adatak 7.7. #3ra.......................................................................................................................................................7<
,adatak 7.8. Prosti blizanci.....................................................................................................................................81
8.#scrpna pretra3a :eAhaustive searchB bruteCforce metod;.....................................................................................87
,adatak 8.1. %onjiev skok.....................................................................................................................................87
..0inarna pretra3a..........................................................................................................................................................8@
,adatak ..1. Pretra3a brojeva.................................................................................................................................8@
@.ekurzija.......................................................................................................................................................................86
,adatak @.1. =anojske kule......................................................................................................................................1
,adatak @.5. -lood fill...............................................................................................................................................7
2./ortiranje.......................................................................................................................................................................2
,adatak 2.1. *lementarna nepo3oda......................................................................................................................6
<.*fikasno stepenovanje...............................................................................................................................................@5
,adatak <.1. *fikasno stepenovanje......................................................................................................................@5
6.Pohlepni :3reedD; al3oritmi.......................................................................................................................................@8
,adatak 6.1. $opov...................................................................................................................................................@8
1>.Osnovna 3eometrijska tijela :pravou3aoniciB kru?nice;......................................................................................@2
,adatak 1>.1. (ajansko prokletstvo......................................................................................................................@2
,adatak 1>.5. Obuhvatanje ta9aka.........................................................................................................................25
11.ad sa strin3ovima....................................................................................................................................................2.
,adatak 11.1. Eenzura.............................................................................................................................................2.
,adatak 11.5. Pravilan jezik....................................................................................................................................2.
,adatak 11.7. Prijemni ispit....................................................................................................................................2<
,adatak 11.8. /pellchecker......................................................................................................................................26
15."eliki broj...................................................................................................................................................................<>
,adatak 15.1. ,bir i proizvod dva velika broja....................................................................................................<>
17.'rafovi i stabla..........................................................................................................................................................<8
,adatak 17.1. Presjedanje........................................................................................................................................<8
5
,adatak 17.5. 0#=!(%..........................................................................................................................................<2
,adatak 17.7. &omenklatura..................................................................................................................................61
,adatak 17.8. -arma.................................................................................................................................................6@
$iteratura..........................................................................................................................................................................62
Za&atak Naziv Te7ina
1.1. Prethodni i sljedei datum O
1.5. azlika datuma /
1.7. imski brojevi O
1.8. &umeri9ka matematika /
1... 0azen :jednostavnija varijanta; O
5.1. &ajvei meu najmanjima O
5.5. =isto3ram /
5.7. Operacije sa skupovima O
7.1. azdvojiti proste od slo?enih /
7.5. %azna /
7.7. #3ra /
7.8. Prosti blizanci /
8.1. %onjiev skok &
..1. Pretra3a brojeva &
@.1. =anojske kule &
@.5. -lood fill &
2.1. *lementarna nepo3oda &
<.1. *fikasno stepenovanje /
6.1. $opov &
1>.1. (ajansko prokletstvo &
1>.5. Obuhvatanje ta9aka /
11.1. Eenzura /
11.5. Pravilan jezik /C&
11.7. Prijemni ispit /
11.8. /pellchecker /C&
15.1. ,bir i proizvod dva velika broja &
7
17.1. Presjedanje &
17.5. 0#=!(% &
17.7. &omenklatura &
17.8. -arma #
Le/en&a'
O F osnovno znanje :o9ekuje se da zadatak mo?e uraditi u9esnik sa znanjem ste9enim u redovnoj
srednjo4kolskoj nastaviB bez posebne pripreme;
S F srednje :preporu9ujemo takmi9arima da ponove ove oblasti;
N F napredne teme :teme koje su mo3ue na kantonalnom takmi9enju :maA. jedan zadatak;B potrebna je
posebna priprema;
I F teme koje nee biti obuhvaene kantonalnim takmi9enjemB ali su mo3ue na dr?avnom takmi9enju iz
informatike i meunarodnoj olimpijadi :#O#;
8
%!A)ILA KANTONALNO8 TAKMIENJA IZ INO!MATIKE
/vi zadaci na %antonalnom takmi9enjimu iz informatike isklju9ivo su pro3ramerski zadaci i te?i4te je
na dizajniranju ispravno3 i :vremenski i memorijski; efikasno3 al3oritma. ,adaci se mo3u rje4avati u bilo
kojem od ponuenih pro3ramskih jezika. 1lazne i izlazne operacije o3rani9avaju se na osnovne operacije
:9itanje iz tekstualne datoteke i upis u tekstualnu datoteku;B tako se pa?nja takmi9ara mo?e usmjeriti na sam
al3oritam. Ta9an pre3led oblasti i tema koje su obuhvaene takmi9arskim zadacima :silabus; dostupan je u
nastavku dokumenta.
O-re(a, -ri*or i (aterijal za tak(ienje, tok tak(ienja
,a takmi9enje se koriste standardni PE ra9unari sa o3rani9enim mre?nim pristupom. Takmi9ari e na
radnim mjestima dobiti printane verzije zadataka za takmi9enjeB dovoljno praznih papiraB pribor za pisanje i
pristupne podatke za takmi9arski Geb interfejs. Takmi9arima nije dozvoljeno unositi bilo kakav dodatni
priborB literaturu ili opremu. Takmi9arima je dopu4tena samo usmena komunikacija sa osobom koja je
de?urna u kabinetu ili sa administratorom i to isklju9ivo na temu li9ne ili tehni9ke prirode a nikako na temu
zadataka. 0ilo kakvo odstupanje od ovih pravila rezultirat e diskvalifikacijom.
%ro/ra(9ki jezi2i i okru7enje
Takmi9arima je dopu4teno kori4tenje pro3ramskih jezika Pascal i E/EHH za izradu rje4enja. &a samom
takmi9enjuB ra9unari e biti sa instaliranim $inuA :1buntu; operativnim sistemomB te -reePascal i
Eode::0lock razvojnim okru?enjima. /vi detalji o okru?enju mo3u se preuzeti sa Geb stranice
http://takmicenje.etf.unsa.ba
:roj za&ataka i trajanje tak(ienja
Takmi9ari imaju 15> minuta za izradu rje4enja. Takmi9ari e usmeno biti napomenuti onda kada do
kraja takmi9enja ostane 1. minuta i . minuta. je4avaju se tri zadatka.
O/ranienja i zahtjevi na -ro/ra(
"a4 pro3ram treba da ulazne podatke 9ita iz ulazne datotekeB te da svoja rje4enja zapisuje u izlaznu
datoteku. &azivi i format sadra?aja obje datoteke bit e precizno definiran za svaki zadatak. "a4 pro3ram
ne smije koristiti bilo kakve dru3e datoteke osim dvije navedene. "a4 pro3ram treba da se izvr4ava unutar
odreenih vremenskih i memorijskih o3rani9enja koja e biti navedena za svaki zadatak. ,abranjeno je
pozivanje bilo kakvih dru3ih sistemskih funkcija kao i forkCanje :otvaranje dodatnih threadCova;. #spravnost
zapisane izlazne datoteke bit e provjeravana samo ukoliko je pro3ram sa izvr4avanjem zavr4io
InormalnoJB odnosno ako je operativnom sistemu vratio vrijednost >.
Si9te( *o&ovanja
*valuacija takmi9arskih rje4enja vr4i se automatiziranim sistemom odmah po zavr4etku takmi9enja. ,a
svaki zadatak komisija unaprijed defini4e skup testova koje e sistem provesti. /vaki test se evaluira
individualno i nosi odreeni broj bodova. Test se sastoji od sadr?aja ulazne datoteke i o9ekivano3 sadr?aja
izlazne datoteke. Test se smatra uspje4nim i za nje3a se dodjeljuju bodovi onda kada takmi9arski pro3ram
pod ranije navedenim o3rani9enjima za specifi9ni sadr?aj ulazne datoteke 3eneri4e o9ekivani sadr?aj izlazne
datoteke. &eophodno je pridr?avati se ta9no definisanih formata obje datoteke. /vaki zadatak e uklju9ivati
dovoljan broj testova razli9ite kompleksnosti kako bi se na taj na9in osi3urala adekvatna distribucija bodova
u skladu sa vremenskom i memorijskom efikasno4u takmi9arsko3 rje4enja :uz neophodnu ispravnost
rje4enja;.
Tak(iar9ki ;e* interfej9
.
Takmi9ari e za vrijeme takmi9enja imati o3rani9en mre?ni pristup samo prema serveru za takmi9enje
kroz Geb pre3lednik u vidu takmi9arsko3 Geb interfejsa. Ovaj interfejs prvenstveno omo3uava
takmi9arima da 4alju svoju rje4enja za vrijeme takmi9enja. +edino rje4enja poslata na ovaj na9in e biti
evaluirana na ranije opisani na9in. &akon slanja rje4enjaB sistem e rje4enje odmah testirati na jednom ili
vi4e tzv. trivijalnih testova i rezultate ponuditi takmi9aru. /adr?aj ulaznih datoteka trivijalnih testova kao i
o9ekivani sadr?aj izlaznih datoteka ovih testova bit e dostupan takmi9arima u sklopu postavke zadatka.
Trivijalni testovi su po slo?enosti jako jednostavni i slu?e kako bi se testiralo da li takmi9ar ispravno koristi
ulazne i izlazne datotekaB pridr?ava se navedeno3 formata ulaznih i izlaznih podataka i sli9no. Trivijalni
testni slu9ajevi ne donose nikakve poeneB ali se rje4enja koja ne prolaze trivijalne testove nee evaluirati po
zavr4etku takmi9enja i bodovat e se sa > bodova. &e postoji o3rani9enje na broj koliko puta takmi9ar
smije poslati rje4enje neko3 zadataka. Posljenje rje4enje koje je pro4lo trivijalne testove za odreeni zadatak
e biti testirano po zavr4etku takmi9enja. Takmi9arski Geb interfejs e se koristiti i za eventualna pitanja
koja takmi9ari mo3u imati za komisiju. Takmi9ari e prije samo3 takmi9enja imati priliku da se upoznaju sa
takmi9arskim Geb interfejsom. Termini kada e ovo biti mo3ue e biti objavljeni na stranici
http://takmicenje.etf.unsa.ba
%itanja
Takmi9ari pitanja postavljaju i komisija na njih daje od3ovor kroz takmi9arski Geb interfejs. %omisija
na pitanja takmi9ara mo?e dati od3ovor K!B &* ili 0*, %O(*&T!!. Pitanja trebaju biti postavljena
tako da je na njih mo3u K! ili &* od3ovor. 1koliko pitanje nije tako postavljenoB komisija daje od3ovor
0*, %O(*&T!!. Osim to3aB ukoliko takmi9ar postavi pitanje na koje komisija ne mo?e dati od3ovor
zato 4to bi to u nepovoljan polo?aj dovela dru3e takmi9areB daje se od3ovor 0*, %O(*&T!!. 1
slu9ajevima kada se daje od3ovor 0*, %O(*&T!!B komisija mo?e dodatno pojasniti za4to takmi9ar
nije dobio od3ovor na svoje pitanje.
!ezultati i rekla(a2ije
Po zavr4etku automatske evaluacijeB objavljuju se preliminarni rezultati. Takmi9ari mo3u kori4tenjem
pristupnih podataka koje se koristili i za vrijeme takmi9enjaB pristupiti takmi9arskom Geb interfejsu.
#nterfejs e po zav4etku takmi9enja omo3uiti detaljan pre3led svih testova i rezultata testiranja. /vi
eventualni pri3ovori podnose se u pismenoj formi komisiji koja ih razmatra.
@
SILA:US KANTONALNO8 TAKMIENJA IZ INO!MATIKE
<-re/le& o*la9ti i te(a koje 9u o*uhva+ene tak(iar9ki( za&a2i(a=
$e3enda zahtjevnosti pojedinih oblasti:
O F osnovno znanje :o9ekuje se da zadatak mo?e uraditi u9esnik sa znanjem ste9enim u redovnoj
srednjo4kolskoj nastaviB bez posebne pripreme;
S F srednje :preporu9ujemo takmi9arima da ponove ove oblasti;
N F napredne teme :teme koje su mo3ue na kantonalnom takmi9enju :maA. jedan zadatak;B potrebna je
posebna priprema;
I F teme koje ne+e biti obuhvaene kantonalnim takmi9enjemB ali su mo3ue na dr?avnom takmi9enju iz
informatike i meunarodnoj olimpijadi :#O#;
,nanja iz domena o9novne raunar9ke -i9(eno9ti koja su preduslov za u9e4e na takmi9enju su:
C Osnovna struktura i na9in rada ra9unara :EP1B memorijaB ulaz/izlaz;
C 1potreba standardno3 3rafi9ko3 okru?enja
C 1potreba uobi9ajenih pomonih aplikacija u operativnom sistemu
C 1potreba inte3risano3 razvojno3 okru?enja :#K*;
C ad sa datote9nim sistemom :kreiranje direktorija/folderaB kopiranjeB premje4tanje i brisanje
datoteka;
C 1potreba Geb pre3lednika i rad sa internetom :posebno: slanje datoteke putem Geb
pre3lednika;
5. MATEMATIKA
Te?ina T*(!
O Eijeli brojevi :en3l. integers; i brojevni sistemi
O (atemati9ke operacije i poreenja
O Osobine cijelih brojeva :pozitivni/ne3ativniB parni/neparniB djeljivostB prosti brojevi /en3l.
primes/;
O azlomciB postotni ra9un
O Ta9ke u Kekartovom koordinatnom sistemu :dvodimenzionalnom;B vektori
O *uklidova udaljenostB Pita3orina teorema
# Ku?iB osobine presjeka
/ 13lovi
O Osnovni 3eometrijski oblici: trou3aoB pravou3aonikB kvadratB kru3
2
# "i4eu3aonik :poli3on;
O (atematske funkcijeB relacijeB skupovi
# Kirihleov princip
O Osnove matematske lo3ike :lo3i9ke operacijeB istinosne tabele;
# &apredne teme iz matematske lo3ike :predikatska lo3ikaB modus ponens i modus tolens;
# Tehnike dokazivanja :direktan dokazB dokaz preko kontradikcijeB matematska indukcija;
& &izoviB redoviB aritmeti9ke i 3eometrijske pro3resijeB -ibonaijevi brojevi
/ Permutacije i kombinacije
/ -aktorijelB binomni koeficijentiB Paskalova jedna9inaB binomni teorem
& /tabla
/ &eusmjereni i usmjereni 3rafovi
/ /trate3ije prolaska kroz 3rafove
# /pannin3 treesB decorated 3raphsB multi3raphs
3. OSNO)E %!O8!AMI!ANJA I ST!UKTU!E %O"ATAKA
Te?ina T*(!
O Osnove sintakse i semantike pro3ramsko3 jezika Pascal ili E
O Promjenljive :varijable;B tipovi podataka :booleanB inte3erB character;B izraziB naredba dodjele
O +ednostavan ulaz/izlaz
O 1slovi i 3rananje
O Petlje
O -unkcijeB prosljeivanje parametara
O /trukturna dekompozicija problema :razbijanje problema na podprobleme;
/ /trate3ije rje4avanja pro3ramskih zadataka
/ Pojam al3oritmaB ulo3a al3oritma u procesu rje4avanja zadatka
/ /trate3ije uklanjanja 3re4aka :debu33in3;
& Osobine al3oritama: korektnostB efikasnost
O &izovi :arraDs;
O /lo3ovi :records;
O /trin3ovi :strin3s;
/ /tati9ke :static; i 3lobalne :3lobal; varijable
& $inkovane liste :linked list; C implementacija preko niza
& 'rafovi :3raph; i stabla :tree; C implementacija preko niza
<
# /tekovi :stack; i redovi :Lueue; C implementacija preko niza
# 'omile :heap;B -enGickCovo stablo
# /trate3ije za izbor optimalne strukture podataka
# !pstraktni tipovi podataka :abstract data tDpes C !KT;B prioritetni red :prioritD Lueue;B
dinami9ki skup :dDnamic set;B dinami9ka mapa :dDnamic map;
& ekurzija :recursion;B jednostavne rekurzivne procedure
# ekurzivne matematske funkcije
# /trate3ije MzavadiCpaCvladajM :divideCandCconLuer;
>. AL8O!ITMI
Te?ina T*(!
# -ormalna specifikacija al3oritamaB korektnostB invarijantnost
# !simptotska analiza 3ornje 3ranice kompleksnostiB bi3CO notacija
# /tandardni slu9ajevi kompleksnosti
# "remenski i prostorni kompromisi u al3oritmima
O +ednostavne strate3ije dizajna petlje
/ !l3oritmi brutalne sile :bruteCforce;B odnosno iscrpne pretra3e :eAhaustive search;
& Pohlepni :3reedD; al3oritmi
# !l3oritmi MzavadiCpaCvladajM :divideCandCconLuer;
# 0acktrackin3 al3oritmi :rekurzivni i nerekurzivni;
# 0ranchCandCbound al3oritmi
/ Prepoznavanje uzoraka i al3oritmi za rad sa strin3ovima :pri 9emu se ne zahtijeva razumijevanje
korektnosti i efikasnosti ovih al3oritama;
# Kinami9ko pro3ramiranje :dDnamic pro3rammin3;
# !l3oritmi diskretne aproksimacije :discrete approAimation;
O !l3oritmi za konverziju brojevnih sistema
O *uklidov al3oritam
/ Provjera da li je broj prost
/ *rastotenovo sito
/ -aktorizacija
/ *fikasno stepenovanje
& Operacije nad cijelim brojevima proizvoljno3 broja cifara
O Popunjavanje niza
6
/ Pomjeranje nizaB izbacivanje elementa iz nizaB rotiranje niza
/ Okretanje niza
/ Promjena veli9ine niza
O Tra?enje najvee3/najmanje3 9lana u nizu
/ =isto3ram niza :prebrojavanje 9lanova niza;
O /umiranje niza :uklju9ujui parcijalne sume;
O /ekvencijalna obrada 9lanova niza :uklju9ujui sekvencijalno pretra?ivanje niza;
/ 0inarna pretra3a :binarD search;
/ +ednostavni al3oritmi sortiranja: selection sortB insertion sortB bubble sort
# Nuick sortB =eap sortB (er3e sort
& !l3oritmi za kretanje kroz 3rafove :implementirane preko niza;B uklju9ui kretanje po dubini
:depthCfirst search C K-/; i po 4irini :breadthCfirst search C 0-/;
& !l3oritmi za kretanje kroz stablo :implementirano preko niza;
# !l3oritmi najkrae3 puta :KijkstraB 0ellmanC-ordB -loDdCOarshall;
# !l3oritmi minimalno3 stabla :+arnikCPrimB %ruskal;
# Topolo4ko sortiranje
# !l3oritmi za odreivanje *ulerovo3 puta/ciklusa
# Osnove teorije i3araB minimaks al3oritmi
# 'eometrijski al3oritmi :presjeci du?iB lokacija ta9ke u poli3onuB al3oritmi za odreivanje
konveksno3 omota9a /conveA hull/ itd.; ali:
/ $ociranje ta9ke u osnovnim 3eometrijskim oblicima: kru?nicaB pravou3aonikB kvadrat
1>
5. Strate/ija rje1avanja -ro/ra(9kih za&ataka
1 nastavku smo dali nekoliko primjera zadataka u kojima se diskutuje 3eneralan pristup rje4avanju
pro3ramskih zadataka kod kojih ne postoji neki specifi9an al3oritam ili model rje4avanjaB ne3o je potrebno
koristiti zdrav razumB dekompoziciju problema i proceduralni pristup.
Za&atak 5.5. %retho&ni i 9lje&e+i &atu(
Te7ina' O
Ovaj zadatak je bio na Kantonalnom takmienju iz informatike 2010. godine
Kat je niz datuma u obliku Mdd mm 3333M. ,a svaki datum potrebno je ispisati prethodni i sljedei datum.
Ka bi neka 3odina bila prestupna mora biti djeljiva sa 8. (eutimB od onih 3odina koje su djeljive sa 8B
3odine koje su djeljive sa 1>> a nisu sa 8>> nisu prestupne. &pr. 16>>. nije bila prestupna dok je 5>>>.
3odina bila prestupna. 1 prestupnoj 3odini mjesec februar ima 56 dana dok u ostalim 3odina ima 5<.
Ulaz'
&ajprije je dat jedan cijeli broj & :maksimalno 1>>; koji predstavlja broj datuma. &akon to3aB svaka linija
ulaza sastoji se od tri cijela broja razdvojena znakom razmak koji predstavljaju danB mjesec i 3odinu.
Izlaz'
,a svaku liniju ulaza treba ispisati tekst oblika:
Katum: dd.mm.3333 Predhodni dd.mm.3333. &aredni dd.mm.3333. 3odine
iliB ukoliko je datum na ulaznoj liniji neispravanB treba ispisati:
Katum: dd.mm.3333 neispravan.
%ri(jer ulaza'
.
5< 5 16>>
1 7 16>>
5< 5 5>>>
1 7 5>>>
56 5 5>>1
%ri(jer izlaza'
Katum: 5<.5.16>> Prethodni 52.5.16>>. &aredni 1.7.16>>. 3odine
Katum: 1.7.16>> Prethodni 5<.5.16>>. &aredni 5.7.16>>. 3odine
Katum: 5<.5.5>>> Prethodni 52.5.5>>>. &aredni 56.5.5>>>. 3odine
Katum: 1.7.5>>> Prethodni 56.5.5>>>. &aredni 5.7.5>>>. 3odine
Katum: 56.5.5>>1 neispravan.
%oja1njenje'
%ao i svi pro3ramski zadaciB ovaj zadatak treba rje4avati dio po dio kreui od stvari koje su vam poznateB
te koristiti osobinu pro3ramskih jezika da dijelove problema izdvojite u zasebne cjeline :funkcije; kako biste
ih odvojeno rje4avali i testirali.
&ajprije emo uraditi najlak4i dio zadatkaB a to je napraviti petlju za unos niza od n datuma i njihov ispis na
11
ekran u tra?enom formatu: MKatum: dd.mm.DDDDM. 0ie nam potrebne sljedee varijable :promjenljive;:
cjelobrojne promjenljive za danB mjesec i 3odinu
cjelobrojna promjenljiva n za broj datuma
po4to za blok koda koji se izvr4ava poznat broj puta koristimo for petljuB uve4emo i cjelobrojnu
promjenljivu i kao kontrolnu promjenljivu for petlje.
Pro3ramski jezik E:
int n,i;
scanf("%d",&n);
int dd,mm,gg;
for(i=0;i<n;i++)
{
scanf("%d %d %d",&dd,&mm,&gg);
printf("Datum: %d.%d.%d ",dd,mm,gg);
}
Okvirni pro3ram u PascalCu koji emo popunjavati blokovima koda:
program Datumi(output);
var
i,n,dd,mm,gg : intgr;
begin
rad!n(n);
for i := " to n do
begin
rad!n(dd,mm,gg);
#rit!n($Datum: $,dd,$.$,mm,$.$,gg);
end;
end.
&ajjednostavnije rje4enje je poveati varijablu dd za jedan kako bismo dobili sljedei datumB odnosno
umanjiti za jedan kako bismo dobili prethodni:
printf("Prethodni: %d.%d.%d ",dd-1,mm,gg);
printf("Sljedeci: %d.%d.%d ",dd+1,mm,gg);
(eutim ovo rje4enje bi bilo neta9no za odreeni broj slu9ajeva. Ka vidimo koji su to slu9ajevi:
!ko je ddP1B oduzimanjem 1 dobiemo > 4to je neispravan datumB ne3o bismo u tom slu9aju
trebali umanjiti mm za jedanB a dd treba imati broj dana u prethodnom mjesecu. &pr. ako je unijet
datum 1.5.5>15 prethodni datum e biti 71.1.5>15 po4to januar ima 71 dan.
Ka bismo ovo mo3li utvrditiB potrebno nam je da znamo koliko koji mjesec u 3odini ima dana. 1 pitanju je
15 cijelih brojeva dana u mjesecimaB pa emo deklarisati niz od 15 elemenata koji imaju te vrijednosti.
Pro3ramski jezik E:
int broj_dn!1"# $ %&,"1,'(,"1,"&,"1,"&,"1,"1,"&,"1,"&,"1);
Pro3ramski jezik Pascal:
broj_dn: rr*!1..1'# of integer $ ("1,'(,"1,"&,"1,"&,"1,"1,"&,"1,"&,"1);
15
1 pro3ramskom jeziku E prvi indeks u nizu je >. Ka bismo mo3li dobiti ta9an broj dana naredbom tipa
brojQdanaRmmSB mo?emo deklarisati niz od 17 elemenata pri 9emu je vrijednost prvo3 9lana nula ili
mo?emo uvijek od mjeseca oduzimati broj 1. Opredijelili smo se za prvu varijantu.
Pascal nema ovakav problem.
,atim odreujemo prethodni broj dana u kodu na sljedei na9in :E;:
prt%odni&dan = dd'";
prt%odni&m(sc = mm;
prt%odna&godina = gg;
/*
provjeravamo da li je potrebno smanjivati mjesec
*/
if(prt%odni&dan<")
{
prt%odni&m(sc'';
/*
podesavamo da je prethodni dan zadnji dan u prethodnom mjesecu
*/
prt%odni&dan = )ro(&dana*prt%odni&m(sc+;
}
Pascal:
prt%odni&dan := dd'";
prt%odni&m(sc := mm;
prt%odna&godina := gg;
{ provjeravamo da li je potrebno smanjivati mjesec }
if prt%odni&dan<" then
begin
prt%odni&m(sc := prt%odni&m(sc'";
{ podesavamo da je prethodni dan zadnji dan u prethodnom mjesecu }
prt%odni&dan := )ro(&dana*prt%odni&m(sc+;
end;
!li 4ta ako je mjesec bio januarB odnosno ako tra?imo prethodni datum od datuma 1.1.5>15 T #spravan
od3ovor je 71.15.5>11. KakleB ako je prethodniQmjesec postao >B moramo umanjiti 3odinu za jedan a
mjesec postaviti na 15. Kakle kod sada 3lasi ovako :E;:
prt%odni&dan = dd'";
prt%odni&m(sc = mm;
prt%odna&godina = gg;
/*
provjeravamo da li je potrebno smanjivati mjesec
*/
if(prt%odni&dan<")
{
prt%odni&m(sc'';
/*
provjeravamo da li je potrebmo smanjivati godinu
*/
if(prt%odni&m(sc<")
{
prt%odni&m(sc = ",;
17
prt%odna&godina'';
}
/*
podesavamo da je prethodni dan zadnji dan u prethodnom mjesecu
*/
prt%odni&dan = )ro(&dana*prt%odni&m(sc+;
}
Pascal:
prt%odni&dan := dd'";
prt%odni&m(sc := mm;
prt%odna&godina := gg;
{ provjeravamo da li je potrebno smanjivati mjesec }
if prt%odni&dan<" then
begin
prt%odni&m(sc := prt%odni&m(sc'";

{ provjeravamo da li je potrebmo smanjivati godinu }
if prt%odni&m(sc<" then
begin
prt%odni&m(sc := ",;
prt%odna&godina := prt%odna&godina'";
end;
{ podesavamo da je prethodni dan zadnji dan u prethodnom mjesecu }
prt%odni&dan := )ro(&dana*prt%odni&m(sc+;
end;
!nalo3nim kodom rje4avamo pitanje sljedee3 datuma. 1ve4emo jo4 tri varijable naredniQdanB
naredniQmjesec i narednaQ3odina te postaviti uslove za slu9aj da je varijabla naredniQdan poprimila
vrijednost veu od broja dana u trenutnom mjesecu :u kojem slu9aju se naredniQmjesec uveava za jedan;B
kao i slu9aj kada je naredniQmjesec dobio vrijednost 17 :u kojem slu9aju se narednaQ3odina uveava za
jedan;.
Ostaje jo4 jedan problemati9an slu9aj a to je prestupna 3odina. 1 prestupnoj 3odini kao 4to je 5>15.
februar ima 56 dana umjesto uobi9ajenih 5<. &apraviemo pomonu funkciju koja provjerava da li je
3odina 33 prestupnaB pa ako ona vrati lo3i9ku istinu :u ECu broj 1; odmah nakon unosa datuma emo
postaviti broj dana u februaru na 56B u suprotnom na 5<. -unkcija 3lasi ovako u ECu:
/*
Odredjuje da li je godina prestupna
*/
int prstupna(int gg)
{
/*godina je prestupna ako je djeljiva sa 400*/
if(gg%-00==0) return ";
/*godina je prestupna ako je djeljiva sa 4, ali ne sa 100*/
if(gg%-==0 && gg%"00.=0) return ";
return 0;
}
18
Pascal:
function prstupna(gg : intgr) : )oo!an;
begin
if (gg mod -00 = 0) then prstupna := true
else if (gg mod - = 0) and (gg mod "00 </ 0) then prstupna := true
else prstupna := false;
end;
%ona9noB trebali bismo ispisati poruku za neispravne datume na ulazu. &apraviemo pomonu funkciju
koja provjerava da li je datum ispravan i vraa lo3i9ku istinu :u ECu 1; ako jesteB u suprotnom lo3i9ku
neistinu. Katum je neispravan ako je:
dan ili mjesec manji od 1
dan vei od broja dana u mjesecu
mjesec vei od 15
!ko funkcija odredi da je datum neispravanB presko9iemo sve ostale naredbe u 3lavnoj petlji naredbom
continue.
-unkcija u ECu 3lasi:
int ispra0an(int dd,int mm,int gg)
{
if(dd<" 11 dd/)ro(&dana*mm+)
return 0;
if(mm<" 11 mm/",) return 0;
return ";
}
! u Pascalu:
function ispra0an(dd,mm,gg : intgr) : )oo!an;
begin
if (dd<") or (dd/)ro(&dana*mm+) then ispra0an := false
else if (mm<") or (mm/",) then ispra0an := false
else ispra0an := true;
end;
Time je pro3ram zavr4en.
%ro/ra(9ki ko& <$='
2inc!ud <stdio.%/
2inc!ud <std!i).%/
/*iz deklariran kao globalna varijabla !dostupna je svakoj "unkciji u programu#
koji sadrzi broj dana svakog mjeseca, ubacena je nula na pocetku jer indeksiranje
u $%u pocinje od nule */
int )ro(&dana*"3+ = {0,3",,4,3",30,3",30,3",3",30,3",30,3"};
1.
/*
Odredjuje da li je godina prestupna
*/
int prstupna(int gg)
{
/*godina je prestupna ako je djeljiva sa 400*/
if(gg%-00==0) return ";
/*godina je prestupna ako je djeljiva sa 4, ali ne sa 100*/
if(gg%-==0 && gg%"00.=0) return ";
return 0;
}
/*
&retpostavljeno je da se radi o pozitivnoj godini, tj' poslije nove ere
"unkcija ispituje da li je ispravan uneseni datum, tj' da li su dani i mjeseci u
datim granicama
*/
int ispra0an(int dd,int mm,int gg)
{
if(dd<" 11 dd/)ro(&dana*mm+)
return 0;
if(mm<" 11 mm/",) return 0;
return ";
}
int main()
{
int n,i;
scanf("%d",&n);
int dd,mm,gg;
int nardni&m(sc,nardni&dan,nardna&godina;
int prt%odni&m(sc,prt%odni&dan,prt%odna&godina;
for(i=0;i<n;i++)
{
scanf("%d %d %d",&dd,&mm,&gg);
printf("Datum: %d.%d.%d ",dd,mm,gg);
/*
podesavamo broj dana "ebruara u zavisnosti da li je godina prestupna
*/
if(prstupna(gg)) )ro(&dana*,+ = ,5;
else )ro(&dana*,+ = ,4;
/*
provjeravamo ispravnost datuma
*/
if(.ispra0an(dd,mm,gg))
{
printf("nispra0an6n");
continue;
}
nardni&dan = dd+";
nardni&m(sc = mm;
1@
nardna&godina = gg;
/*
ispitujemo da li je naredni dan u sljedecem mjesecu, u tom slucaju
povecavamo broj mjeseca, a dan stavljamo da je 1
*/
if(nardni&dan/)ro(&dana*mm+)
{
nardni&dan=";
nardni&m(sc++;
}
/*
ukoliko je naredni(mjesec veci od 1) !tj' jedak 1*#, potrebno je
povecati godinu za 1
*/
if(nardni&m(sc/",)
{
nardni&m(sc = ";
nardna&godina++;
}
prt%odni&dan = dd'";
prt%odni&m(sc = mm;
prt%odna&godina = gg;
/*
provjeravamo da li je potrebno smanjivati mjesec
*/
if(prt%odni&dan<")
{
prt%odni&m(sc'';
/*
provjeravamo da li je potrebmo smanjivati godinu
*/
if(prt%odni&m(sc<")
{
prt%odni&m(sc = ",;
prt%odna&godina'';
}
/*
podesavamo da je prethodni dan zadnji dan u prethodnom mjesecu
*/
prt%odni&dan = )ro(&dana*prt%odni&m(sc+;
}
printf("7rd%odni %d.%d.%d. 8ardni %d.%d.%d. godin6n", prt%odni&dan,
prt%odni&m(sc, prt%odna&godina, nardni&dan, nardni&m(sc, nardna&godina);
}
return 0;
}
%ro/ra(9ki ko& <%a92al='
program Datumi(output);
12
var
i,n,dd,mm,gg : intgr;
prt%odni&dan, prt%odni&m(sc, prt%odna&godina, nardni&dan,
nardni&m(sc, nardna&godina : intgr;
)ro(&dana: array*"..",+ of intgr = (3",,4,3",30,3",30,3",3",30,3",30,3");
function prstupna(gg : intgr) : )oo!an;
begin
if (gg mod -00 = 0) then prstupna := true
else if (gg mod - = 0) and (gg mod "00 </ 0) then prstupna := true
else prstupna := false;
end;
function ispra0an(dd,mm,gg : intgr) : )oo!an;
begin
if (dd<") or (dd/)ro(&dana*mm+) then ispra0an := false
else if (mm<") or (mm/",) then ispra0an := false
else ispra0an := true;
end;
begin
rad!n(n);
for i := " to n do
begin
rad!n(dd,mm,gg);
#rit($Datum: $,dd,$.$,mm,$.$,gg);
if prstupna(gg) then )ro(&dana*,+ := ,5 else )ro(&dana*,+ := ,4;
if not ispra0an(dd,mm,gg) then
begin
#rit!n($ nispra0an$);
continue;
end;
prt%odni&dan := dd'";
prt%odni&m(sc := mm;
prt%odna&godina := gg;
{ provjeravamo da li je potrebno smanjivati mjesec }
if prt%odni&dan<" then
begin
prt%odni&m(sc := prt%odni&m(sc'";

{ provjeravamo da li je potrebno smanjivati godinu }
if prt%odni&m(sc<" then
begin
prt%odni&m(sc := ",;
prt%odna&godina := prt%odna&godina'";
end;
{ podesavamo da je prethodni dan posljednji dan u prethodnom
mjesecu }
prt%odni&dan := )ro(&dana*prt%odni&m(sc+;
end;
nardni&dan := dd+";
1<
nardni&m(sc := mm;
nardna&godina := gg;
{ provjeravamo da li je potrebno povecati mjesec }
if nardni&dan/)ro(&dana*mm+ then
begin
nardni&m(sc := nardni&m(sc+";

{ provjeravamo da li je potrebno povecati godinu }
if nardni&m(sc/", then
begin
nardni&m(sc := ";
nardna&godina := nardna&godina+";
end;
{ podesavamo da je naredni dan 1 }
nardni&dan := ";
end;
#rit($ 7rt%odni: $, prt%odni&dan, $.$, prt%odni&m(sc, $.$,
prt%odna&godina, $.$);
#rit!n($ 8ardni: $, nardni&dan, $.$, nardni&m(sc, $.$,
nardna&godina, $.$);
end;
end.
Za&atak 5.3. !azlika &atu(a
Te7ina' S
Ovaj zadatak je bio na Kantonalnom takmienju iz informatike 2008. godine
&apisati pro3ram koji u9itava dva datuma i ispisuje broj dana koliko je proteklo izmeu ta dva datuma.
Ulaz'
Kvije linije koje predstavljaju datume. /vaka linija sastoji se od tri cijela broja razdvojena razmakom koji
predstavljaju danB mjesec i 3odinu.
Izlaz'
+edan pozitivan cijeli broj koji predstavlja broj dana koji su protekli izmeu dva datuma. 1koliko je prvi
datum bio poslije dru3o3 treba ispisati apsolutnu vrijednost razlike. 1koliko je jedan od datuma ile3alan
treba ispisati M#le3alan datumM.
%rin2i- rje1avanja'
Osnovni princip je sljedei: najprije oba datuma trebamo pretvoriti u dva cijela broja koji predstavljaju broj
dana od neko3 hipotetsko3 datuma 1.1.1. 3odine do ?eljeno3 datumaB a zatim jednostavno oduzmemo ta
dva broja. 1 slu9aju da je dru3i datum poslije prvo3B dobiemo ne3ativan broj pa trebamo uzeti apsolutnu
vrijednost to3 broja.
Pri tome pravimo pretpostavku da se isklju9ivo koristi 're3orijanski kalendarU odnosno ovakav pro3ram
16
nema nikakvo3 smisla za datume ranije od 1.<5. 3odine. Prema tome i broj dana od M1.1.1.M ustvari nije
ta9anB ali je za potrebe rje4avanja zadatka zadovoljavajui.
Pretvaranje datuma dd.mm.33. u ?eljeni broj dana se obavlja na sljedei na9in:
najprije saberemo broj dana u 3odinama od 1. do :33C1;. :zato 4to je 3odina 33 jo4 uvijek u toku;B
pri 9emu za prestupne 3odine dodajemo 7@@ danaB a za ostale 7@.U ovdje e nam pomoi funkcija
za provjeru da li je 3odina prestupna koju smo razvili u prethodnom zadatkuU
zatim saberemo dane za sve mjesece koji su protekliB od januara do mjeseca :mmC1;. iz istih razlo3aU
ovdje e nam trebati broj dana u mjesecuB 4to smo takoer rije4ili u prethodnom zadatkuU
kona9no saberemo dane koji su protekli u tekuem mjesecu a to je broj dd.
adi ljep4e3 rje4enja u ovom zadatku uvodimo i koncept struktura u pro3ramskom jeziku E :klju9na rije9
struct;. ,bo3 ovo3a je neznatno izmijenjena funkcija ispravan:;.
%ro/ra(9ki ko& <$='
/*
napomena+
u proracunu nije uzeta u obzir promjena kalendara sa ,ulijanskog na
-regorijanski, ali jesu prestupne godine
*/
2inc!ud <stdio.%/
2inc!ud <std!i).%/
/*iz deklariran kao globalna varijabla !dostupna je svakoj "unkciji u programu#
koji sadrzi broj dana svakog mjeseca, ubacena je nula na pocetku jer indeksiranje
u $%u pocinje od nule */
int )ro(&dana*"3+ = {0,3",,4,3",30,3",30,3",3",30,3",30,3"};
struct datum
{
int dan;
int m(;
int god;
};
/*
Odredjuje da li je godina prestupna
*/
int prstupna(int gg)
{
/*godina je prestupna ako je djeljiva sa 400*/
if(gg%-00==0) return ";
/*godina je prestupna ako je djeljiva sa 4, ali ne sa 100*/
if(gg%-==0 && gg%"00.=0) return ";
return 0;
}
5>
/*
&retpostavljeno je da se radi o pozitivnoj godini, tj' poslije nove ere
"unkcija ispituje da li je ispravan uneseni datum, tj' da li su dani i mjeseci u
datim granicama
*/
int ispra0an(struct datum d)
{
if(d.dan<" 11 d.dan/)ro(&dana*mm+)
return 0;
if(d.m(<" 11 d.m(/",) return 0;
return ";
}
/* .roj dana od 1'1'1' godine do datuma */
int )ro(&dana(struct datum d)
{
int r9u!tat = 0, i;
/* ajprije sabiramo godine */
for (i="; i<d.god; i++)
{
if (prstupna(i))
r9u!tat += 3::;
else
r9u!tat += 3:;;
}
/* zatim mjesece */
for (i="; i<d.m(; i++)
{
r9u!tat += )ro(&dana*i+;
/* /odatni dan u "ebruaru za prestupnu godinu */
if (i == , && prstupna(d.god))
r9u!tat++;
}
/* i na kraju dane */
r9u!tat += d.dan;
return r9u!tat;
}
/* -lavni program */
int main()
{
/* /eklaracija i unos datuma */
struct datum pr0i, drugi;
int ra9!i<a;
scanf("%d %d %d", &pr0i.dan, &pr0i.m(, &pr0i.god);
scanf("%d %d %d", &drugi.dan, &drugi.m(, &drugi.god);
/* /a li su ispravni datumi */
if (.ispra0an(pr0i) 11 .ispra0an(drugi)) {
printf("=!ga!an datum6n");
return 0;
51
}
/* 0zimamo razliku */
ra9!i<a = )ro(&dana(pr0i) ' )ro(&dana(drugi);
/* 1psolutna vrijednost razlike */
if (ra9!i<a < 0) ra9!i<a = 'ra9!i<a;
printf ("%d", ra9!i<a);
return 0;
}
Za&atak 5.>. !i(9ki *rojevi
Te7ina' O
Ovaj zadatak je bio na Kantonalnom takmienju iz informatike 2010. godine
&apisati pro3ram koji u9itava parove rimskih brojevaB a zatim ispisuje zbir ovih parovaB takoe u formi
rimsko3 broja.
O ri(9ki( *rojevi(a
imskim brojevima se ne mo3u predstaviti nula ili ne3ativni brojeviB a za predstavljanje broja 8>>> i veih
koriste se simboli koji se ne mo3u predstaviti !/E## znakovima. #z to3 razlo3a e svi rimski brojevi
obavezno u opse3u 1C7666.
imske cifre su:
# " V $ E K (
1 . 1> .> 1>> .>> 1>>>
Ostali brojevi dobijaju se kombinovanjem ovih vrijednostiB od veih ka manjim ciframa npr.
5@72 P ((KEVVV"##
#zuzetak su cifre 8 i 6 koje se dobijaju po sljedeoj tabeli:
#" #V V$ VE EK E(
8 6 8> 6> 8>> 6>>
Ulaz'
&ajprije je dat jedan cijeli broj & :maksimalno 1>>; koji predstavlja broj rimskih brojeva. &akon to3a. svaki
red ulaza predstavlja jedan rimski broj opisan kombinacijom velikih slova 9ije je zna9enje dato iznad.
Izlaz'
,a svaka dva broja na ulazu bie ispisan jedan rimski broj koji predstavlja njihov zbir. 1 slu9aju da zbir
brojeva bude vei od 7666B umjesto zbira bie ispisana poruka MPrekoracenjeM. 1 slu9aju da se na ulazu
55
nalazi neparan broj redova posljednji red e biti i3norisan.
%ro/ra(9ki ko& <$??='
2inc!ud <string/
2inc!ud <iostram/
2inc!ud <fstram/
using namspac std;
string rimcifr*"3+ = { ">", "?>", "D", "?D", "?", "@?", "A", "@A", "@", "=@", "B",
"=B", "=" };
int arapcifr*"3+ = { "000, 500, ;00, -00, "00, 50, ;0, -0, "0, 5, ;, -, "};
int rims<i,araps<i(string rims<i)
{
int <(0);
int araps<i(0);
for (int i(0); i<"3; i++) {
while (rims<i.su)str(<, rimcifr*i+.!ngt%()) == rimcifr*i+) {
araps<i += arapcifr*i+;
< += rimcifr*i+.!ngt%();
}
}
return araps<i;
}
string araps<i,rims<i(int araps<i) {
string rims<i("");
for (int i(0); i<"3; i++) {
while (araps<i/=arapcifr*i+) {
araps<i '= arapcifr*i+;
rims<i += rimcifr*i+;
}
}
return rims<i;
}
int main() {
string sa)ira<", sa)ira<,,9)ir;
gt!in(cin,sa)ira<");
gt!in(cin,sa)ira<,);
9)ir = araps<i,rims<i( rims<i,araps<i(sa)ira<") +
rims<i,araps<i(sa)ira<,) );
cout<<9)ir<<nd!;
return 0;
}
57
Za&atak 5.@. Nu(erika (ate(atika
Te7ina' S
Ovaj zadatak je bio na Kantonalnom takmienju iz informatike 2007. godine
(etodom polovljenja intervala nai rje4enje funkcije :nulu funkcije;:
f(! " a
1

#
$a
2

#%1
$...a
#%
$a
#$1
na intervalu (&'(! sa 3re4kom manjom od (#)10!. ezultat ispisati na ekran.
Ulaz'
&a ulazu se nalazi redom :svaki u zasebnom redu;:
C cijeli brojevi ! i 0 razdvojeni razmakom
C realan broj
C prirodan broj & :manji od 1>; koji defini4e red funkcije
C realni brojevi koji predstavljaju vrijednosti koeficijenata a
1
' a
2
'... a
#$1
Izlaz'
&a izlazu treba ispisati realan broj koji predstavlja vrijednost na intervalu x( A, B) za koju je f:A;P>.
Pretpostaviti da e uvijek postojati ta9no jedna takva vrijednost na zadatom intervalu.
%oja1njenje'
(etoda polovljenja intervala :metoda bisekcijeB en3l. bisection method; je jedna od osnovnih metoda
numeri9ke matematike. Ovom metodom mo?e se odrediti vrijednost x(A , B) za koju je f:A;W>
:ustvari f (x)( ,) 3dje je neka unaprijed zadata maksimalna 3re4ka;.
1slovi za primjenu metode su da je funkcija neprekidna na intervalu :!B0; i da ima jedno rje4enje :nulu; na
tom intervalu. (atemati9ki se mo?e dokazati da iz ova dva uslova proizlazi da vrijednosti f:!; i f:0; moraju
imati razli9it predznak.
Princip rada al3oritma je sljedei: neka je trenutni interval
:!B0;:
&ajprije se izra9unava vrijednost funkcije na sredini
intervala f:/; pri 9emu je /P:!H0;/5.
!ko je ta vrijednost u opse3u :CB; onda je / na4a
tra?ena vrijednost A i petlja se prekida.
!ko f:/; ima isti predznak kao f:!; novi interval je
:/B0;B a ako ima isti predznak kao f:0; novi interval je
:!B/;.
Kru3im rije9imaB interval se su?ava oko ta9ke u kojoj se nalazi
nula funkcije kao na slici.
Ka bismo rije4ili ovaj pro3ramski zadatakB najprije emo
napisati funkciju koja izra9unava vrijednost dato3 polinoma za
dati niz koeficijenata:
f(! " a
1

#
$a
2

#%1
$...a
#%
$a
#$1
58
*lika 1+ ,etoda -olovljenja intervala
Ova funkcija bi mo3la iz3ledati ovako:
/* 2zracunavanje vrijednosti polinoma'
a 3 niz koe"icijenata, 3 red polinoma, 4 3 tacka u kojoj trazimo vrijednost */
f!oat po!inom(f!oat a*+, int 8, f!oat C) {
f!oat r9u!tat = 0;
int i;
for (i=0; i<=8; i++) {
r9u!tat += a*i+ D po#(C, 8'i);
}
return r9u!tat;
}
&iz a i vrijednost # su date na ulazuB dok umjesto uvr4tavamo *. ,atim mo?emo postaviti okvirnu
petlju. Petlja se izvr4ava sve dok je f:/; po apsolutnoj vrijednosti vee od B odnosno:
+hile (polinom(,,,S) - ep.ilon // polinom(,,,S) 0 -ep.ilon) %
...
)
1 petlji emo izra9unati novu vrijednost za !B 0 i /. ,a ovo je potrebno da odredimo predznak vrijednosti
f:!;B f:0; i f:/;. (o?emo napraviti pomonu funkciju za odreivanje predznaka :ovakva funkcija se u
matematici obi9no zove si3num ili s3n;:
int sgn(f!oat C) {
if (C<0) return '";
return ";
}
/ada popunjavamo u petlji dio koji smo ozna9ili sa tri ta9ke:
while (po!inom(a,8,E) / psi!on 11 po!inom(a,8,E) < 'psi!on) {
if (sgn(po!inom(a,8,E)) == sgn(po!inom(a,8,F)) {
F = E; /* ovi pocetak intervala */
} else {
G = E; /* ovi kraj intervala */
}
E = (F+G)H,; /* ova sredina intervala */
}
Ovakvo rje4enje je prili9no neefikasno. &aimeB najsporiji dio ovo3 pro3rama je izra9unavanje polinoma
koje se u ovoj petlji izvr4ava 9ak 8 puta. Ka bismo to popraviliB uvesti emo pomone varijable f/ i f! koje
predstavljaju ranije izra9unate vrijednosti polinoma:
while (fE / psi!on 11 fE < 'psi!on) {
if (sgn(fE) == sgn(fF)) {
F = E; /* ovi pocetak intervala */
fF = fE; /* 5oristimo ranije izracunatu vrijednost polinoma */
} else {
G = E; /* ovi kraj intervala */
}
E = (F+G)H,; /* ova sredina intervala */
fE = po!inom(a,8,E);
}
5.
"idimo da se u ovoj petlji funkcija polinom:; poziva samo jednom u odnosu na ranija 8 puta. Ostaje jo4
samo da napravimo deklaracijeB ulaz i izlaz vrijednosti.
%ro/ra(9ki ko& <$='
2inc!ud <stdio.%/
2inc!ud <mat%.%/ /* 6unkcija po7!# */
/* 2zracunavanje vrijednosti polinoma'
a 3 niz koe"icijenata, 3 red polinoma, 4 3 tacka u kojoj trazimo vrijednost */
f!oat po!inom(f!oat a*+, int 8, f!oat C) {
f!oat r9u!tat = 0;
int i;
for (i=0; i<=8; i++) {
r9u!tat += a*i+ D po#(C, 8'i);
}
return r9u!tat;
}
/* &redznak broja 4 */
int sgn(f!oat C) {
if (C<0) return '";
return ";
}
int main() {
f!oat a*"0+, F, G, E, fF, fE, psi!on;
int 8, i;
/* 0nos vrijednosti */
/* &retpostavljamo da sve vrijednosti zadovoljavaju uslove zadatka */
scanf("%f %f", &F, &G);
scanf("%f", &psi!on);
scanf("%d", &8);
for (i=0; i<=8; i++) {
scanf("%f", &a*i+);
}

/* &ostavljam pocetne vrijednosti za 8, "1, "8 */
E = (F+G)H,;
fF = po!inom(a,8,F);
fE = po!inom(a,8,E);
/* &olovljenje intervala */
while (fE / psi!on 11 fE < 'psi!on) {
if (sgn(fE) == sgn(fF)) {
F = E; /* ovi pocetak intervala */
fF = fE; /* 5oristimo ranije izracunatu vrijednost polinoma */
} else {
G = E; /* ovi kraj intervala */
}
E = (F+G)H,; /* ova sredina intervala */
fE = po!inom(a,8,E);
}
5@
printf ("%f", E);
return 0;
}
Za&atak 5.6. :azen <je&no9tavnija varijanta=
Te7ina' O
Ovaj zadatak je bio na Kantonalnom takmienju iz informatike 200.. godine
#zra9unati broj plo9ica potrebnih za prekrivanje bazena. 1 obra9unu predvidjeti otpad plo9ica: !ko postoji
ostatak dijeljenja du?ina/4irine povr4ine bazena i du?ine/4irine plo9ice dodaj jedan red plo9ica.
Ulaz'
1 prvom redu ulaza su data tri cijela broja AB D i z koji predstavljaju dimenzije bazena :du?inaB 4irina i
visina; u cm.
1 dru3om redu su dva cijela broja koji predstavljaju dimenzije jedne plo9ice :du?ina i 4irina; u cm.
Izlaz'
+edan cijeli broj koji predstavlja broj plo9ica potrebnih za prekrivanje bazena.
%ro/ra(9ki ko& <%a92al='
Program Ga9n(input, output);
Var a,),C,I,9,p : =ntgr;
!*a duzina, b sirina plocice*#
!*4 duzina, 9 sirina, z visina bazena*#
Function po&du9(<,! : =ntgr) : =ntgr;
Begin
If (< mod ! = 0) Then po&du9 := < div !
Else po&du9 := (< div !) +"
End;
Function po&po0()",),,p",p, : =ntgr) : =ntgr;
Begin
po&po0 := po&du9()", p") D po&du9(),, p,)
End;
Begin
Jrit(KLnsi dimn9i( )a9na: M); Nad!n(C,I,9);
Jrit(KLnsi dimn9i( p!ocic: M); Nad!n(a,));
p := ,D(po&po0(C, 9, a, )) + po&po0(I, 9, a, ))) + po&po0(C, I, a, ));
Jrit!n(KGro( potr)ni% p!ocica (: M,p)
End.
52
3. O-era2ije 9 nizovi(a
Za&atak 3.5. Najve+i (eAu naj(anji(a
Te7ina' O
Kata je matrica dimenzija A %B va4 zadatak je da za svaku kolonu te matrice odredite najmanji elementB te
zatim da meu tim elementima odredite najvei. *lementi matrice mo3u biti proizvoljni brojevi.
Ulaz'
1 prvom redu ulaza se nalaze dva broja r i k : rBk X 1>>> ; koji predstavljaju broj redova i kolona matriceB
respektivno. 1 sljedeih r redova e se nalaziti po k brojeva koji predstavljaju elemente matrice.
Izlaz'
1 jedini red izlaza potrebno je ispisati tra?eni broj.
%oja1njenje <Nala7enje (ini(u(a i (ak9i(u(a niza='
1 takmi9arskim zadacima 9esto se zahtjeva od pro3ramera da nae najefikasnije rje4enje neko3 problemaB
4to se 9esto posti?e tra?enjem najvee ili najmanje odreene vrijednosti. ,bo3 to3a emo ovdje ukratko
opisati proceduru nala?enja najmanje3/najvee3 elementa niza.
,a nala?enje najvee3 elementa neko3 nizaB polazimo od sljedee3:
- Keklari4emo varijablu npr. ma i dodijelimo joj vrijednost prvo3 9lana niza. *ventualno mo?emo
koristiti najmanju mo3uu vrijednost ako je ona poznata :npr. ako znamo da su svi 9lanovi pozitivni
mo?emo postaviti maA na >;.
- Prethodno e mo?da biti potrebno provjeriti da li niz ima ijedan elementB jer u tom slu9aju tra?enje
maksimuma/minimuma nee imati smisla.
- !naliziramo svaki 9lan niza redom te ukoliko je on vei od vrijednosti varijable maAB dodijelimo
vrijednost to3 9lana niza na4oj varijabli maA. Ponekad je potrebno i dodatno 9uvati indeks najvee3
9lanaB 4to se jednostavno implementira pomou dodatne varijable.
#mplementacija navedene procedure u pro3ramskom jeziku E:
int maC = a*0+;
for(i=";i<a&0!icina;i++) {
if(a*i+/maC) {
maC = a*i+;
}
}
#mplementacija navedene procedure u pro3ramskom jeziku Pascal:
m1 :$ ni2!1#;
for i :$ ' to 3elicin do
begin
if ni2!i#-m1 then m1 :$ ni2!i#;
end
Procedura je analo3na i za nala?enje najmanje3 elementa niza.
Primijetimo da navedeni proces ima O(n! kompleksnost. &ajefikasniji al3oritmi za sortiranje niza imaju
5<
O:n log n! kompleksnost i zbo3 to3a ih ne trebamo koristiti osim ako nam nije potreban cijeli sortiran niz.
%ro/ra(9ki ko& <$='
4incl5de 0.tdio.h-
4incl5de 0.tdlib.h-
int min()
%
int r,6;
flot mtric!1&&&#!1&&&#;
int i,j,pr3i;
flot min, m1;
.cnf("%d %d",7r,76);
for(i$&; i0r; i++)
%
for(j$&;j06;j++)
%
.cnf("%f",7mtric!i#!j#);
)
)
/*
kod za odredjivanje najmanjeg elementa, odmah nakon sto smo ga odredili,
poredimo ga sa dosadasnjim najvecim elementom, da ih ne bismo
morali cuvati u zasebnom nizu.
Ovo se moglo implementirati odmah tokom ulaza, i ne bi postojala potreba
za matricom, ali radi jednostavnosti uradjena je ovakva implementacija
*/
m1 $ &;
pr3i $ 1;
for(i$&;i0r;i++)
%
min $ mtric!i#!&#;
for(j$1; j06;j++)
%
if(mtric!i#!j#0min)
%
min $ mtric!i#!j#;
)
)
if(min - m1 // pr3i $$ 1)
%
m1 $ min;
pr3i $ &;
)
)
printf("%f",m1);

return &;
56
)
%ro/ra(9ki ko& <%a92al='
program 8a(0ci8a(man(i%(output);
var
i,(,maC,min,pr0i,r,< : intgr;
matrica: Array*".."000+ of Array*".."000+ of =ntgr;
begin
rad!n(r);
rad!n(<);
for i := " to r do
begin
for ( := " to < do
begin
rad!n(matrica*i+*(+);
end;
end;
maC := 0;
pr0i := ";
for i := " to r do
begin
min := matrica*i+*"+;
for ( := , to < do
begin
if matrica*i+*(+<min then min := matrica*i+*(+;
end;
if (min/maC) or (pr0i=") then
begin
maC := min;
pr0i := 0;
end;
end;

#rit!n(maC);
end.
Za&atak 3.3. Bi9to/ra(
Te7ina' S
Ovaj zadatak je bio na Kantonalnom takmienju iz informatike 200.. i 2008. godine.
Potrebno je odrediti histo3ram nizaB odnosno broj ponavljanja razli9itih 9lanova niza prirodnih brojeva
manjih od 1>>>.
Ulaz'
Eijeli broj & koji predstavlja broj 9lanova niza :maksimalno 1>>;.
&akon to3a slijedi & brojevaB svaki u zasebnom reduB pri 9emu su svi brojevi na intervalu R>B666S.
Izlaz'
/vaki red sadr?i dva broja razdvojena razmakom. Prvi broj je 9lan nizaB a dru3i broj je broj ponavljanja to3a
7>
9lana u nizu. )lanovi niza trebaju biti poredani po veli9ini u rastuem redoslijedu i ne smiju se ponavljati. 1
slu9aju da se 9lan niza ne javlja niti jednomB ne treba 3a ispisati.
%ri(jer ulaza'
.
578
15
578
<
15
%ri(jer izlaza'
< 1
15 5
578 5
%ro/ra(9ki ko& <$='
2inc!ud <stdio.%/
int main()
{
int %istogram*"000+;
int i,n,)ro(;

/* &ostavljamo sve :lanove niza histogram na 0 */
for (i=0; i<"000; i++)
%istogram*i+ = 0;
/* 0:itavamo broj :lanova niza */
scanf ("%d", &n);
/* 0:itavamo :lanove i istovremeno ra:unamo njihov histogram */
for (i=0; i<n; i++) {
scanf("%d", &)ro();
%istogram*)ro(+++;
}
/* 2spisujemo histogram */
for (i=0; i<"000; i++) {
if (%istogram*i+/0) {
printf("%d %d6n", i, %istogram*i+);
}
}
return 0;
}
%ro/ra(9ki ko& <%a92al='
program Oistogram7rog(output);
var
i,n,)ro( : intgr;
%istogram: Array*".."000+ of =ntgr;
71
begin
{ &ostavljamo sve :lanove niza histogram na 0 }
for i := " to "000 do
%istogram*i+ := 0;
{ 0:itavamo broj :lanova niza }
rad!n(n);
{ 0:itavamo :lanove i istovremeno ra:unamo njihov histogram }
for i := " to n do
begin
rad!n()ro();
%istogram*)ro(+"+ := %istogram*)ro(+"+ + ";
end;
{ 2spisujemo histogram }
for i := " to "000 do
begin
if %istogram*i+/0 then
begin
#rit!n(i'", $ $, %istogram*i+);
end;
end;
end.
Za&atak 3.>. O-era2ije 9a 9ku-ovi(a
Te7ina' O
Ovaj zadatak je bio na Kantonalnom takmienju iz informatike 200.. godine
Kata su dva skupa cijelih brojeva V i Y. #spisati nizove koji predstavljaju:
a; uniju skupova V i Y
b; presjek skupova V i Y
c; razliku skupova V i Y
75
>. %ro9ti *rojevi
Prost broj se defini4e kao prirodan broj koji je djeljiv samo sa jedinicom i samim sobom. Ovdje treba
na3lasiti rije9 9a(o. &aime svaki prirodan broj je djeljiv sa jedinicom i samim sobomB ali prosti brojevi nisu
djeljivi niti sa jednim dru3im brojem. +edini na9in da provjerimo da li je neki broj & prost je da 3a probamo
podijeliti sa svim brojevima na intervalu :1B&;. 1stvari dovoljno je da idemo do
N
:uklju9ivo; jer &
si3urno nije djeljiv veim brojevima.
Pri rje4avanju zadatka mo?emo koristiti operator moduloB pa ako on vrati nulu zna9i da je prvi operand
djeljiv dru3im.
Kod u -rogramskom jeziku /+
pro.t $ 1;
for (i=,; i<=sPrt(8); i++) {
if (n%i == 0) {
prost = 0;
break;
}
}
Kod u -rogramskom jeziku 0ascal+
prost := true;
for i := , to Qrunc(sPrt(n)) do
{ cijeli i realni brojevi se ne mogu direktno porediti u &ascalu }
begin
if n mod i = 0 then
begin
prost := false; break;
end;
end;
Primjena *reak naredbe za prekid petlje ako smo ustanovli da broj nije prost u praksi mo?e donijeti znatno
pobolj4anje performansi.
Ovdje je potrebno na3lasiti da broj 1 nije niti prost niti slo?en. %od dat iznad e za &P1 vratiti da je prostB
pa ukoliko to ima efekta na va4 pro3ram trebate dodati poseban uslov koji provjerava da li je u pitanju broj
1 ili ne.
Ova relativna kompleksnost provjere da li je broj prost dovela je do vrlo ra4irene upotrebe prostih brojeva
u kripto3rafiji. !ko biste na4li efikasniji al3oritam za provjeru prostosti brojaB 9eka vas svjetska slava jer
biste mo3li MprovalitiM mno3e poznate oblike kripto3rafske za4titeZ
Za&atak >.5. !az&vojiti -ro9te o& 9lo7enih
Te7ina' S
&a ulazu se nalazi niz od maksimalno 1>> pozitivnih cijelih brojeva. Pro3ram treba da ispi4e iste te brojeve
preslo?ene tako da se najprije ispi4u svi 9lanovi niza koji su prosti brojeviB a zatim svi 9lanovi koji su slo?eni
77
brojevi. 1nutar skupova prostih i slo?enih brojeva treba biti o9uvan redoslijed iz polazno3 nizaB dakle
brojevi trebaju biti dati istim redom kao i u polaznom nizu.
Ulaz'
0roj & koji ozna9ava veli9inu nizaB nakon 9e3a slijedi & pozitivnih cijelih brojeva.
Izlaz'
Eijeli brojevi preslo?eni na opisani na9in razdvojeni znakom novi red.
%ri(jer ulaza'
.
<
2
6
7
.
%ri(jer izlaza'
2
7
.
<
6
%ro/ra(9ki ko& <$='
2inc!ud <stdio.%/
int main() {
int u!a9*"00+, prosti*"00+, s!o9ni*"00+;
int n, i, (, prost, )rprosti%, )rs!o9ni%;
scanf("%d", &n);
/* 0nosimo niz ulaz */
for (i=0; i<n; i++)
scanf("%d", &u!a9*i+);
/* 8tavljamo clanove niza ulaz u odgovarajuce nizove */
)rprosti% = )rs!o9ni% = 0;
for (i=0; i<n; i++) {
/* /a li je ulaz;i< prost broj= */
prost=";
for ((=,; (<sPrt(u!a9*i+); (++) {
if (u!a9*i+ % ( == 0) {
prost=0;
break;
}
}
/* 1ko je prost i veci od jedan stavljamo u niz prosti */
if (u!a9*i+/" && prost==") {
/* brprostih nam sluzi kao indeks u nizu prosti */
prosti*)rprosti%+ = u!a9*i+;
78
)rprosti%++;
} !s {
/* a brslozenih u nizu slozeni */
s!o9ni*)rs!o9ni%+ = u!a9*i+;
)rs!o9ni%++;
}
}
/* 2spis niza prosti */
for (i=0; i<)rprosti%; i++)
printf("%d6n", prosti*i+);
/* 2spis niza slozeni */
for (i=0; i<)rs!o9ni%; i++)
printf("%d6n", s!o9ni*i+);

return 0;
}
%ro/ra(9ki ko& <%a92al='
program Na9d0a(an(7rosti%(output);
var
u!a9,prosti,s!o9ni: Array*".."00+ of intgr;
n,i,(,)rprosti%,)rs!o9ni% : intgr;
prost : )oo!an;
begin
rad!n(n);
{ unosimo niz brojeva }
for i := " to n do
rad!n(u!a9*i+);

{ stavljamo clanove niza u odgovarajuce nizove }
)rprosti% := ";
)rs!o9ni% := ";
for i := " to n do
begin
{ da li je ulaz;i< prost broj= }
prost := true;
for ( := , to Qrunc(sPrt(u!a9*i+)) do
begin
if u!a9*i+ mod ( = 0 then
begin
prost := false; break;
end;
end;
{ ako jeste, stavljamo ga u niz prostih }
if (u!a9*i+/") and prost then
begin
prosti*)rprosti%+ := u!a9*i+;
)rprosti% := )rprosti% + ";
end else
{ a ako nije, u niz slozenih }
7.
begin
s!o9ni*)rs!o9ni%+ := u!a9*i+;
)rs!o9ni% := )rs!o9ni% + ";
end
end;
{ ispisujemo sve proste brojeve }
for i := " to )rprosti%'" do
#rit!n()rprosti%*i+);
{ ispisujemo sve slozene brojeve }
for i := " to )rs!o9ni%'" do
#rit!n()rs!o9ni%*i+);
end.
Za&atak >.3. Kazna
Te7ina' S
(ali !lvin nikada nije volio matematikuB zbo3 9e3a je 9esto nemiran na 9asu. ,bo3 to3a mu nastavnik
9esto zadaje poseban problem tokom 9asaB kao poku4aj da izae na kraj sa !lvinovim nesta4lucima.
Profesor bi mu napisao u svesku broj & :3dje je & X 5
71
C1;B i !lvinov zadatak bi bio da napi4e najmanji
broj takav da je proizvod nje3ovih cifara jednak broju &. &aravnoB prije to3a bi profesor uvijek provjerio
da li je to mo3ue.
%ako !lvin ne ?eli da du3o radi zadatkeB zamolio je vas da mu pomo3nete da vara tako 4to ete napisati
pro3ram koji rje4ava dati problem.
Ulaz'
+edan broj & :3dje je & X 5
71
C1;
Izlaz'
+edan broj koji zadovoljava navedene uslove
%oja1njenje <aktoriza2ija='
1 matematiciB faktorizacija broja & predstavlja nje3ovu dekompoziciju na skup prostih brojeva sa tom
osobinom kad se pomno?e da daju broj &. Tako su:
faktorizacije brojeva @>B 1>58 i 56@<8@B dok su npr. brojevi 5B 7 i . prosti faktori broja @>.
&ala?enje prostih faktora je problem sa kojim se takmi9ari 9esto susreu. Ovaj problem rje4avamo bruteC
force metodomB tj. ispitivanjem djeljivosti sa svakim manji brojem.
&ajjednostavnija faktorizacija broja se posti?e tako 4to redom provjeravamo svaki broj koji je manji od &.
1koliko je & djeljivo tim brojemB dijelimo 3a sve dok je taj uslov ispunjenB a zatim prelazimo na sljedei
vei broj.
for(i$'; i0$,;i++)
%
+hile(,%i$$&)
%
, 8$i;
f6tori!inde6.# $ i;
7@
inde6.++;
)
)
(o3ue je napraviti odreene optimizacije da bismo smanjili vrijeme izvr4avanja na4e3 koda.
%ao prvoB primjetimo da ukoliko smo provjerili djeljivost od & brojem 5B ne moramo provjeravati nje3ovu
djeljivost bilo kojim parnim brojem. Tako da djeljivost brojem 5 mo?emo ispitati posebno izvan forFpetljeB
dok emo u for petlji ispitivati djeljivost samo sa neparnim brojevima.
/ljedea optimizacija koju mo?emo napraviti je i 3ornja 3ranica do koje je potrebno provjeravati djeljivost.
(atemati9ki je jednostavno pokazati kako je dovoljno da provjeravamo djeljivost sa prostim brojevima koji
su manji od B sa jo4 malim dodatkom na kraju koda. /ada na4 kod dobija svoj kona9ni oblik:
while(.(8&")) /* provjera djeljivosti brojem ) koristeci binarnu
logiku dodatna optimizacija */
{
8=8//"; /* djeljenje brojem ) pomocu pomjeranja bita > dodatna
optimizacija */
fa<tori*)ro(&fa<tora+++ = ,;
}
<or(n = (int) sPrt(n);
for(i=3;i<=<or(n;i+=,)
{
while(8%i==0)
{
8H=i;
fa<tori*)ro(&fa<tora+++ = i;
}
}

if(8/0) fa<tori*)ro(&fa<tora+++ = 8;
(o3ue je da je da nakon forFpetlje u n [ostaneI jo4 jedan prost brojB koji na ovaj na9in ubacujemo u nizB
npr. ako je n P 5@B provjeru emo raditi do int :;P .B a znamo da je 5@ P 5\17
%ro/ra(9ki ko& <$='
/*
Primjetimo da se navedeni problem svodi na nalazenje svih prostih faktora
broja N, i na njihov ispis od najmanjeg ka najvecem
*/
4incl5de 0.tdio.h-
4incl5de 0.tdlib.h-
4incl5de 0mth.h-
/*
n je broj koji zelimo faktorizirati
faktori pretstavljaju niz koji popunjavamo prostim faktorima, funkcija se ne
brine o tome da il je taj niz dovoljno velik
kao rezultat funkcija vraca velicinu niza faktora
*/
int f6tori2cij(int n, int 9f6tori)
%
72
int i,6orjen;
int broj_f6tor$&;
while(:(n71))
%
n$n--1;
f6tori!broj_f6tor++# $ ';
)
6orjen $ (int) .;rt(n);
for(i$";i0$6orjen;i+$')
%
while(n%i$$&)
%
n8$i;
f6tori!broj_f6tor++# $ i;
)
)
if(n-&) f6tori!broj_f6tor++# $ n;
return broj_f6tor;
)
int min()
%
int i,n;
/*
niz faktori je velicine !" jer je autor logicki zakljucio da je to
najveci moguci broj prostih faktora
kako je n#$"%!& '& i kako je " najmanji prosti faktor, !& pretstavlja
najveci moguci broj prostih faktora (i tome je dodata jedinica
radi dodatne sigurnosti. )okom takmicenja autor bi vjerovatno napravio
ovaj niz da bude velicine npr. *+
*/
int f6tori!"'#;
int br_f6tor $ f6tori2cij(1',f6tori);
for(i$&;i0br_f6tor;i++)
printf("%d",f6tori!i#);
return &;
)
Za&atak >.>. I/ra
Te7ina' S
#vica i =aso su iz dosade odlu9ili da naprave takmi9enje iz matematike. To rade na sljedei na9in: obojica
dobiju po & brojeva k
i
: >]iX& ; i njihov zadatak je da za svaki od brojeva k
i
odrede koji je k
i
Cti prosti broj
po redu. &a krajuB provjeravaju svoje rezultate i pobjednik je onaj koji je ta9no odredio najvi4e prostih
brojeva.
"a4 zadatak je da napi4ete pro3ram koji e odrediti pobjednika.
7<
Ulaz'
1 prvom redu ulaza nalazi se cijeli broj & :& X 1> >>>;. ,atim u sljedeih & redova se nalaze brojevi k
i
:k
i
X 5>>>; i m
i
za #vicuB 3dje je m
i
broj koji je odredio #vica da je k
i
Cti prosti broj. &akon to3a slijedi jo4 &
redova u kojima se nalaze brojevi k
i
i m
i
B ali ovaj put za =asu.
Izlaz'
1 jedini red izlaza potrebno je ispisati pobjednikaB ukoliko postoji: [#vicaI ili [=asoI ili [&erjesenoI.
%ri(jer ulaza'
7
5> 21
8> 127
.>> 7.<1
1. 82
.> 552
@>> 8752
%ri(jer izlaza'
Ivi2a
%oja1njenje <Erato9tenovo 9ito='
*ratostenovo sito je jednostavan i star al3oritam za nala?enje svih prostih brojeva do unaprijed date
3ranice. To 9ini tako 4to iterativno ozna9ava kao slo?ene brojeve umno4ke prostih brojevaB po9ev4i od
broja 5.
"i4ekratnici dato3 prosto3 broja se 3eneri4u po9ev4i od to3 prosto3 brojaB kao aritmeti9ki niz brojeva
kojem je prvi element i razlika upravo taj prosti broj.
*ratostenovo sito je jedan od najefikasnijih na9ina da se nau svi manji prosti brojevi :ispod oko 1>
miliona;.
Postupak dobivanja prostih brojeva pomou *ratostenovo3 sita:
- napi4emo proizvoljan broj uzastopnih prirodnih brojeva po9ev4i od 5
- zaokru?imo najmanji neozna9eni broj
- precrtamo sve nje3ove vi4ekratnikeB koji nisu ve ozna9eni
- ponavljamo postupak od 5. koraka dok svi brojevi nisu ozna9eni :zaokru?eni ili precrtani;
Postupak zavr4i u kona9no mno3o korakaB jer na po9etku imamo kona9no mno3o brojevaB a u svakom
koraku barem jedan broj ozna9imo. ,aokru?eni brojevi su prosti brojevi. Precrtani brojevi su slo?eni
brojevi.
Kobra 3rafi9ka ilustracija al3oritma se mo?e nai na stranici:
http://upload.Gikimedia.or3/Gikipedia/commons/b/b6//ieveQofQ*ratosthenesQanimation.3if
!l3oritamB implementiran u pro3ramskom jeziku E :
for( i$'; i0$gornj_grnic; i++)
%
if(:.ito!i#)
%
pro.ti_broje3i!3elicin++# $ i;
76
tmp $ i+i;
+hile(tmp0$gornj_grnic)
%
.ito!tmp# $ 1;
tmp+$i;
)
)
)
%ro/ra(9ki ko& <$='
4incl5de 0.tdio.h-
4incl5de 0.tdlib.h-
/*
funkcija prima kao argumente gornju granicu do koje ispitujemo postojanje
prostih brojeva te niz u koji cemo stavljati te proste brojeve
kao rezultat vraca velicinu niza
*/
int <rto.teno3o_.ito (int gornj_grnic, int pro.ti_broje3i!#)
%
int 3elicin$&;
int i;
int .ito!1(&&&#;
mem.et(.ito,&,sizeof .ito);
int tmp;
for( i$'; i0$gornj_grnic; i++)
%
if(:.ito!i#)
%
pro.ti_broje3i!3elicin++# $ i;
tmp $ i+i;
while(tmp0$gornj_grnic)
%
.ito!tmp# $ 1;
tmp+$i;
)
)
)
return 3elicin;
)
int min()
%
/*
,deja zadatka jeste da na pocetku jednom pokrenemo funkciju -ratostenovo
sito i tako dobijemo niz prostih brojeva, tako da tokom
citanja ulaza mozemo direktno ispitivati
Nakon sto je implementirana funkcija -ratostenovo.sito, lagano se moze doci
do zakljucka da je dovoljan niz od &/+++ elemenata
da bi sadrzao "+++ prostih brojeva
*/
int pro.ti_broje3i!'1&&#;
8>
int ,;
int i, i3ic$&, h.o$&;
int 6, m;
.cnf("%d",7,);
<rto.teno3o_.ito(1(&&&,pro.ti_broje3i); /* Nije nam potreban podatak o
velicini niza */
for(i$&;i0,;i++)
%
.cnf("%d %d",76,7m);
if(pro.ti_broje3i!6-1#$$m) i3ic++;
)
for(i$&;i0,;i++)
%
.cnf("%d %d",76,7m);
if(pro.ti_broje3i!6-1#$$m) h.o++;
)
if(i3ic-h.o)
printf("=3ic");
else if(h.o-i3ic)
printf(">.o");
else printf(",erje.eno");
return &;
)
Za&atak >.@. %ro9ti *lizan2i
Te7ina' S
Prosti blizanci su parovi prostih brojeva koji su razdvojeni samo jednim parnim brojem npr. 11 i 17 su
prosti blizanci. &apisati pro3ram koji prima cijeli broj & i odreuje broj parova prostih blizanaca koji su
manji od broja &.
Ulaz'
Eijeli broj & :& X 5 >>>;.
Izlaz'
Eijeli broj koji od3ovara broju prostih blizanaca manjih od &.
%ri(jer ulaza'
1>>
%ri(jer izlaza'
<
81
%oja1njenje'
je4enje navedeno ispod 3eneri4e *rastotenovo sito :opisano u prethodnom zadatku;B a zatim prolazi kroz
sve tako 3enerisane brojeve i nalazi blizance.
%ro/ra(9ki ko& <$='
4incl5de 0.tdio.h-
int <rto.teno3o_.ito (int gornj_grnic, int pro.ti_broje3i!#)
%
int 3elicin$&;
int i;
int .ito!1(&&&#;
mem.et(.ito,&,sizeof .ito);
int tmp;
for( i$'; i0$gornj_grnic; i++)
%
if(:.ito!i#)
%
pro.ti_broje3i!3elicin++# $ i;
tmp $ i+i;
while(tmp0$gornj_grnic)
%
.ito!tmp# $ 1;
tmp+$i;
)
)
)
return 3elicin;
)
int min()
%
int pro.ti_broje3i!'1&&#;
int ,, pro.tih, bli2nc;
.cnf("%d",7,);
pro.tih $ <rto.teno3o_.ito(,,pro.ti_broje3i);
bli2nc $ &;
for(i$1; i0pro.tih; i++)
%
if (pro.ti_broje3i!i# ? pro.ti_broje3i!i-1# $$ ') bli2nc++;
)
printf("%d", bli2nc);
return &;
)
85
@. I92r-na -retra/a <eChau9tive 9ear2h, *ruteDfor2e (eto&=
&ekada je jedino mo3ue rje4enje odreeno3 zadatka to da isprobamo sve dostupne varijante i naemo
najpovoljniju. Ovakvo rje4enje je naravno primjenjivo samo tamo 3dje je broj mo3uih rje4enja o3rani9en.
1 svakom slu9aju vrijedi razmisliti o efikasnijem rje4enju.
Za&atak @.5. Konji+ev 9kok
Te7ina' N
Odrediti koliko razli9itih 2Ccifrenih brojeva je mo3ue formirati tako 4to se za svaku sljedeu cifru mo?e
uzeti samo ona do 9ije3 se polja mo?e doi pomijeranjem 4ahovske fi3ure konjia od polja prethodne cifreB
pri 9emu je tabla or3anizovana kao standardna telefonska tastatura.
Ulaz
Po9etna cifra brojaU cijeli broj od 1 do 6.
Izlaz
Tra?eni broj 2Ccifrenih brojeva koji su formirani na opisani na9in.
%ri(jeri'
Ulaz
7
Izlaz
1>8
%ro/ra(9ki ko& 9a -oja1njenje('
&apomena: u rje4enju se koristi rekurzija koja e biti poja4njena kasnije. (o3ue je rije4iti ovaj zadatak i
bez kori4tenja rekurzije.
899
9 @dt6 ce biti rije.en generi.njem .3ih mog5cih broje3 6oji
9 2do3olj3j5 dte 5.lo3e i njiho3im prebroj3njem.
98
4incl5de 0.tdio.h-
88 Atric 6oj opi.5je t.tt5r5.
char t.tt5r!#!"# $ % %B1B, B'B, B"B),
%BCB, BDB, BEB),
%BFB, B(B, BGB),
%B9B, B&B, B4B) );
88 Atric 6oj opi.5je ncin 6retnj 6onj n ploci.
88 S36 3r.t pred.t3lj jedn do mog5cih pote2, pri cem5
87
88 broj 5 pr3oj 6oloni pred.t3lj pom6 fig5re po redo3im,
88 dr5gi pom6 po 6olonm 5 odno.5 n tren5tn5 lo6cij5.
int pote2i!#!'# $ % %-1, -'),
%-1, +'),
%-', -1),
%-', +1),
%+1, -'),
%+1, +'),
%+', -1),
%+', +1) );
88 Hroj element 5 ni25 pote2i
int const HI_PJK<@L $ (;
88 ,i2 6oji ce .dr23ti broj 6oji .e grdi
char broj!F#;
int totl $ &;
899
9 M5n6cij prim 6oordinte (1, *) n 6ojoj .e tren5tno nl2i
9 fig5r i prcijlno i2grdjen broj.
9 Nepth pred.t3lj d5bin5 re65r2ije, tj. cifr5 6oj5 ce odrediti
9 tj po2i3 f5n6cije.
98
void re65r2ij(int 1, int *, int cifr) %
88 O.lo3 2 25.t3ljnje re65r2ije, tj. pretr2i3nj.
88 O6oli6o je broj cifr jedn6 F, prondjen je no3i
88 broj 6oji 2do3olj3 2dne 5.lo3e.
if (cifr $$ F) %
++totl;
return;
)
88 Kreb nci 6oj .5 to polj do.t5pn i2 tren5tne po2icije fig5re.
for (int i $ &; i 0 HI_PJK<@L; ++i) %
88 Ied n 6oji .e dol2i pote2om i i2 trentne po2icije
int const de.tP $ 1 + pote2i!i#!&#;
88 Qolon n 6oj5 .e dol2i pote2om i i2 tren5tne po2icije
int const de.tR $ * + pote2i!i#!1#;
88 Pro3jeriti d li je polje 3lidno -- d li .e nl2i 5n5tr
88 grnic ploce.
if (de.tP 0 & // de.tP -$ C // de.tR 0 & // de.tR -$ ") continue;
88 Polj . 2n6o3im 9 i 4 .e ne 52imj5 5 ob2ir...
if (de.tP $$ " 77 (de.tR $$ & // de.tR $$ ')) continue;
88 Qd je 5t3rdjeno d je no3o polje 3lidno, cifr 6oj .e
88 nl2i n njem5 .e dodje 5 tren5tni broj, te .e f5n6cij
88 po2i3 re65r2i3no . no3om po2icijom fig5re n ploci.
broj!cifr# $ t.tt5r!de.tP#!de.tR#;
re65r2ij(de.tP, de.tR, cifr + 1);
)
)
int min() %
88
88 Pocetn cifr:
int p_cifr;
.cnf("%d", 7p_cifr);
88 Jdrediti pocetni red i 6olon5 n o.no35 5ne.enog broj.
int red$ p_cifr 8 ";
int 6ol $ p_cifr % " - 1;
88 Pr35 cifr5 dodjemo 5 broj
broj!&# $ t.tt5r!red#!6ol#;
88 Po2i3 .e f5n6cij re65r2ij . d5binom 1, jer je potrebno poceti
88 od dr5ge cifre tr2enog broj (pr3 je 2dt).
re65r2ij(red, 6ol, 1);
printf("%dSn", totl);
return &;
)
8.
6. :inarna -retra/a
0inarna pretra3a je metoda efikasno3 pronalaska dato3 elementa u nizu. ,a razliku od iscrpne pretra3e u
kojoj moramo uporediti svaki element u nizu sa tra?enom vrijedno4uB 4to je definicija al3oritamske
kompleksnosti O(n!B binarna pretra3a ima kompleksnost O(log n!. &oB da bi se binarna pretra3a mo3la
koristiti nu?an preduslov je da je niz sortiran :slo?en po veli9ini;.
0inarna pretra3a je u9enicima poznatija pod imenom Mmetoda polovljenja intervalaM. ecimo da se
pretra?uje neki skup vrijednosti na intervalu RPBNS. 1zima se vrijednost u sredini to3 intervala :PHN;/5 te
se ona poredi sa tra?enom vrijedno4u. !ko je tra?ena vrijednost vea od vrijednosti u srediniB novi interval
je dat kao po9etak i sredina prethodno3 intervalaB odnosno RPB :PHN/5S. !ko je tra?ena vrijednost manjaB
novi interval je sredina i kraj prethodno3 intervala dakle R:PHN;/5B NS. Procedura se ponavlja sve dok se
vrijednost ne pronae ili dok du?ina intervala ne postane 1 u kojem slu9aju zaklju9ujemo da se vrijednost
ne nalazi u intervalu.
Za&atak 6.5. %retra/a *rojeva
Te7ina' N
Kat je niz brojeva duzine n sortiran u rastuem redoslijedu. Treba odrediti redni broj prvo3 pojavljivanja
svako3 od m sljedeih brojeva. 1koliko se broj ne nalazi u nizuB ispisati poruku M&ije pronadjenM.
Ulaz
&a prvoj liniji se nalazi prirodan broj n F du?ina niza :maksimalno 1>>;.
,atim slijedi n cijelih brojeva sortiranih u rastuem redoslijedu.
1 sljedeem redu je broj m :takoe maksimalno 1>>;.
/lijedi m cijelih brojeva za koje treba dati redni broj prvo3 pojavljivanja u nizu.
Izlaz
,a svaki od datih m cijelih brojevaB tra?eni redni broj u nizu ili poruku I&ije pronadjenJ :bez navodnika;
na posebnoj liniji.
%ri(jer ulaza'
.
1
1
7
8
.
7
7
<
1
%ri(jer izlaza'
8@
7
&ije pronadjen
1
%ro/ra(9ki ko& <$='
899
9 Qo 5l2 je dt .ortirn ni2 broje3 d52ine n.
9 @tim .lijedi m broje3 2 6oje treb nci redni broj
9 pr3og poj3lji3nj 5 ni25. O6oli6o .e broj ne nl2i
9 5 ni25, i.pi.ti por565 ",ije prondjen".
98
4incl5de 0.tdio.h-
899
9 Hinrn pretrg ni2 rdi t6o .to 5 .36om 6or65
9 polo3i inter3l 5 6ojem .e mo2e nci tr2eni broj.
9 Ko .e rdi t6o .to .e tr2eni broj 5poredi .
9 brojem 5 .redini inter3l, te 56oli6o je tr2eni broj
9 3eci pretrg n.t3i 5 gornjoj polo3ini inter3l, 56oli6o
9 je mnji 5 donjoj polo3ini.
9 O6oli6o inter3l po.tne pr2n, dti broj .e ne nl2i 5 ni25.
98
int binr*_.erch(int ni2!#, int len, int broj) %
int lo+er $ &;
int 5pper $ len - 1;
88 =nter3l ni2 2 6oji 5 .36oj interciji petlje 3rijedi
88 d .e nl2i broj (56oli6o je 5 ni25) je !lo+er, 5pper#
while (lo+er 0$ 5pper) %
88 Jdredj5jemo inde6. element i2 .redine inter3l
int i $ (lo+er + 5pper) 8 ';
if (broj 0 ni2!i#) %
88 L6o je tr2eni broj mnji od .rednjeg element inter3l
88 5 .ljedecoj iterciji je inter3l ogrnicen n donj5 polo3in5
5pper $ i - 1;
) else if (broj - ni2!i#) %
88 L6o je tr2eni broj 3eci od .rednjeg element inter3l
88 5 .ljedecoj iterciji je inter3l ogrnicen n gornj5 polo3in5
lo+er $ i + 1;
) else if (lo+er :$ 5pper) %
88 Srednji element inter3l je jedn6 tr2enom broj5, li 5 inter3l5
88 .e nl2i 3i.e od jednog element, p .e ne mo2e grnto3ti d je
88 prondjeno pr3o poj3lji3nje tr2enog element. =nter3l je
ogrnicen
88 5 .ljedecoj iterciji n donj5 polo3in5 . 56lj5cenim .rednjim
elementom.
5pper $ i;
) else %
88 O inter3l5 .e nl2i .mo jedn element 6oji je jedn6 tr2enom.
return i;
)
)
82
88 =nter3l je po.to pr2n 5 to65 pretrge, .to 2nci d dti element nije
88 prondjen 5 ni25.
return -1;
)
int min() %
int n;
.cnf("%d", 7n);
int ni2!1&&&&#;
for (int i $ &; i 0 n; ++i) %
.cnf("%d", 7ni2!i#);
)
int 6;
.cnf("%d", 76);
for (int i $ &; i 0 6; ++i) %
int broj;
.cnf("%d", 7broj);
88 M5n6cij binr*_.erch 3rc inde1 ni2 n 6ojem
88 .e nl2i pr3o poj3lji3nje dtog broj 5 dtom ni25.
88 Trc -1 56oli6o .e broj ne poj3lj5je 5 ni25.
int inde1 $ binr*_.erch(ni2, n, broj);
if (inde1 $$ -1) %
printf(",ije prondjenSn");
) else %
printf("%dSn", inde1 + 1);
)
)
return &;
)
8<
E. !ekurzija
ekurzivna funkcija je funkcija koja poziva samu sebe. &aj9e4e u
pitanju je neka funkcija f:A; koju mo?emo izraziti preko f:AC1;. +edan
primjer rekurzivne funkcije je faktorijel. -aktorijel broja n :pi4e se nZ;
se defini4e kao proizvod svih brojeva od 1 do n:
n!=123...(n1)n
Odnosno mo?emo pisati:
n!=n(n1)!
Kru3im rije9imaB faktorijel broja n je n 4to mno?i faktorijel broja nC1.
Ovu funkciju mo?emo opisati sljedeom E funkcijom:
int fa<tori(!(int n) {
return n D fa<tori(!(n'");
}
Pascal:
function fa<tori(!(n : intgr) : intgr;
begin
fa<tori(! := n D fa<tori(!(n'");
end;
Ono 4to je ovdje zbunjujue za veinu u9enika je da seB kada funkcija pozove samu sebeB stanje izvr4enja
kao i vrijednosti svih promjenljivih sa9uvaju u memoriji te se kreiraju nove instance svih tih varijabliB pri
9emu nova varijabla n ima vrijednost staro n minus 1.
ecimo da smo 3ore definisanu funkciju faktorijel pozvali sa brojem 8: faktorijel:8;. #zvr4enje pro3rama
te9e ovako:
najprije se kreira promjenljiva n 9ija je vrijednost 8U
zatim izvr4enje pro3rama doe do izraza n\faktorijel:nC1; koji se ne mo?e izra9unati dok se ne
izra9una vrijednost faktorijel:nC1;U
da bi se pozvala funkcija faktorijel:nC1; najprije treba izra9unati koliko je nC1B a to je 7U
poziva se funkcija faktorijel sa parametrom 7U ovom prilikom se kompletno stanje izvr4enja smje4ta
u memoriju :nP8;U
itd. proces se ponavlja za 5B 1B > itd.
Ovdje uo9avamo jednu od najva?nijih stvari u vezi rekurzije: svaka rekurzivna funkcija mora da terminiraB
odnosno mora se postaviti 3ranica do koje e rekurzija iiB u suprotnom rekurzija e se nastaviti sa C1B C5
itd. te e se pro3ram krahirati po4to postoji maksimalan broj puta koliko funkcija mo?e pozvati samu sebe.
1 matematiciB faktorijel ima smisla samo za prirodne :pozitivne; brojeveB pa emo dodati da je faktorijel od
1 jednak 1B 9ime emo osi3urati da se rekurzija zavr4i na tom mjestu:
E:
int fa<tori(!(int n) {
86
*lika 2+ 1ekurzija
if (n==") return ";
else return n D fa<tori(!(n'");
}
Pascal:
function fa<tori(!(n : intgr) : intgr;
begin
if n=" then
fa<tori(! := "
else
fa<tori(! := n D fa<tori(!(n'");
end;
KakleB sada kompletan rekurzivni proces za poziv faktorijel:8; iz3leda ovako:
nP8
n nije jednako 1B izvr4ava se else
n\faktorijel:nC1; C moramo odrediti faktorijel:nC1;
nC1 P 7
pozivamo faktorijel:7;
nP7
n nije jednako 1B izvr4ava se else
n\faktorijel:nC1; C moramo odrediti faktorijel:nC1;
nC1 P 5
pozivamo faktorijel:5;
nP5
n nije jednako 1B izvr4ava se else
n\faktorijel:nC1; C moramo odrediti faktorijel:nC1;
nC1 P 1
pozivamo faktorijel:1;
nP1
po4to je nP1B vraa se vrijednost 1
n\1 P 5\1 P 5
vraa se vrijednost 5
n\5 P 7\5 P @
vraa se vrijednost @
n\@ P 8\@ P 58
vraa se vrijednost 58
8Z P 58 4to je ta9an rezultat.
/vaki rekurzivni zadatak mo?e se rije4iti i bez rekurzije. (eutimB rekurzija nam omo3uuje prirodniji na9in
rje4avanja problema koji je 9esto bli?i matemati9koj definiciji. !ko imamo problem za n koji se mo?e
izraziti preko neke funkcije od nC1B onda se takav problem mo?e rije4iti rekurzivno.
.>
Za&atak E.5. Banoj9ke kule
Te7ina' N
Postoji le3enda da se ne3dje u #ndiji nalazi hram
1
i u njemu tri velika stuba oko kojih su ovje4ena @8 velika
zlatna diska. =induski sveenici vrijedno premje4taju diskove sa jedno3 stuba na dru3iB ispunjavajui
drevno proro9anstvo da e smak svijeta nastupiti onda kada svi diskovi budu premje4teni sa prvo3 stuba na
dru3i :koristei trei kao pomoni;. Trik je u tome da je svaki disk razli9ite veli9ine i da se vei disk nikada
ne smije nalaziti na manjem :jer bi u tom slu9aju propao;.
!ko pretpostavimo da sveeniku treba jedna sekunda da premjesti diskB kada e nastupiti smak svijetaT
Ovaj broj je poznat i iznosi 5
@8
C1 sekundi. 'eneralnoB za n diskova potrebno je 5
n
C1 poteza da bi se i3ra
rije4ila.
&api4ite pro3ram koji ispisuje sve poteze potrebne za rje4avanje i3re za zadati broj n diskova.
Ulaz
Prirodan broj n: broj diskova.
Izlaz
1 svakom redu opisan je jedan korak u i3ri.
Tri stuba su ozna9ena slovima !B 0 i EB a diskovi su ozna9eni brojevima 1B 5B ... n tako da je disk 1 najmanji
a disk n najvei.
+edan potez je opisan brojem koji od3ovara diskuB nakon 9e3a slijede dva slova koja od3ovaraju stubu sa
koje3 je disk premje4ten i stubu na koji je premje4ten.
&pr. <E0 zna9i da je disk < prenesen sa stuba E na stub 0.
%ri(jer ulaza'
7
%ri(jer izlaza'
1!E
5!0
1E0
7!E
10!
50E
1!E
%oja1njenje'
&ajprije probajte rije4iti ovu interesantnu i3ru na papiru i
to sa nekim manjim brojem diskovaB recimo 8. !ko
razmi4ljate na ispravan na9inB trebali biste nadoi na op4ti
princip rje4avanja zadatka za n diskova. Taj princip 3lasi
ovako:
Ka bismo pomjerili n diskova sa stuba ! na stub EB
potrebno je pratiti sljedee korake :po3ledajte sliku 7;:
1 1 dru3oj varijanti le3ende hram se nalazi u =anojuB "ijetnamB pa je pod tim imenom zadatak poznatiji.
.1
*lika .+ O-2ti -rinci- rje2avanja -roblema 3anojske
kule
korak 1: pomjerimo :nC1; diskova sa stuba ! na pomoni stub 0B koristei E kao pomoni stubU
korak 5: po4to je sada na dnu stuba ! ostao najvei diskB premjestimo 3a direktno na stub EU
korak 7: sada pomjerimo :nC1; diskova sa stuba 0 na stub E koristei stub ! kao pomoni.
Ovo rje4enje problema je rekurzivnoB odnosnoB rje4enje problema za n smo opisali preko rje4enja za n%1 koje
smo iskoristili u koracima 1 i 7.
Ovaj opis nam omo3uuje da napi4emo funkciju -rebaci koja prebacuje n diskova sa stuba A na stub D
koristei stub z kao pomoni. 1 slu9aju da je broj diskova nP1B treba samo ispisati na ekranu slova A i D. &a
ovaj na9in smo osi3urali da se ova rekurzivna funkcija terminira.
0rogramski jezik /+
0oid pr)aci(int n, c%ar sa&stu)a, c%ar na&stu), c%ar pomocni&stu))
{
/* &rebacujemo !n%1# diskova sa polaznog stuba na pomocni stub, koristeci
odredisni stub kao pomocni'
1ko je n31 ovaj korak ne moramo raditi' */
if (n/") pr)aci(n'", sa&stu)a, pomocni&stu), na&stu));
/* ajveci disk n je ostao na dnu, njega mozemo direktno prebaciti' */
printf(R%d%c%c6nS, n, sa&stu)a, na&stu));
/* 8ada mozemo prebaciti !n%1# diskova sa pomocnog stuba na odredisni */
if (n/") pr)aci(n'", pomocni&stu), na&stu), sa&stu)a);
}
0ascal+
procedure pr)aci(n : intgr, sa&stu)a, na&stu), pomocni&stu) : c%ar);
begin
{ &rebacujemo !n%1# diskova sa polaznog stuba na pomocni stub, koristeci
odredisni stub kao pomocni'
1ko je n31 ovaj korak ne moramo raditi' }
if n/" then pr)aci(n'", sa&stu)a, pomocni&stu), na&stu));
{ ajveci disk n je ostao na dnu, njega mozemo direktno prebaciti' }
#rit!n(n, sa&stu)a, na&stu));
{ 8ada mozemo prebaciti !n%1# diskova sa pomocnog stuba na odredisni }
if n/" pr)aci(n'", pomocni&stu), na&stu), sa&stu)a);
end;
Preostaje jo4 da napi4emo 3lavni pro3ram koji poziva ovu funkciju.
%ro/ra(9ki ko& <$='
2inc!ud <stdio.%/
/* 6unkcija prebaci obavlja sav bitan posao u ovom programu */
0oid pr)aci(int n, c%ar sa&stu)a, c%ar na&stu), c%ar pomocni&stu))
{
/* &rebacujemo !n%1# diskova sa polaznog stuba na pomocni stub, koristeci
odredisni stub kao pomocni'
1ko je n31 ovaj korak ne moramo raditi' */
if (n/") pr)aci(n'", sa&stu)a, pomocni&stu), na&stu));
.5
/* ajveci disk n je ostao na dnu, njega mozemo direktno prebaciti' */
printf("%d%c%c6n", n, sa&stu)a, na&stu));
/* 8ada mozemo prebaciti !n%1# diskova sa pomocnog stuba na odredisni */
if (n/") pr)aci(n'", pomocni&stu), na&stu), sa&stu)a);
}
int main()
{
int n;
scanf("%d", &n);
pr)aci(n, $F$, $?$, $G$);
return 0;
}
%ro/ra(9ki ko& <%a92al='
program Oano(s<&<u!;
var
)ro(&dis<o0a : intgr;
{ &rocedura prebaci obavlja sav bitan posao u ovom programu }
procedure pr)aci(n : intgr, sa&stu)a, na&stu), pomocni&stu) : c%ar);
begin
{ &rebacujemo !n%1# diskova sa polaznog stuba na pomocni stub, koristeci
odredisni stub kao pomocni'
1ko je n31 ovaj korak ne moramo raditi' }
if n/" then pr)aci(n'", sa&stu)a, pomocni&stu), na&stu));
{ ajveci disk n je ostao na dnu, njega mozemo direktno prebaciti' }
#rit!n(n, sa&stu)a, na&stu));
{ 8ada mozemo prebaciti !n%1# diskova sa pomocnog stuba na odredisni }
if n/" pr)aci(n'", pomocni&stu), na&stu), sa&stu)a);
end;
begin
rad!n()ro(&dis<o0a);
pr)aci()ro(&dis<o0a, $F$, $?$, $G$);
end.
Za&atak E.3. loo& fill
Te7ina' N
Ovaj zadatak je bio na Kantonalnom takmienju iz informatike 2010. godine
0itmapa je tabela :matrica; sastavljena od nula i jedinicaB koja mo?e predstavljati recimo neku crnoCbijelu
sliku. &apravite pro3ram koji u9itava kvadratnu bitmapu :dimenzija &A&; i koordinate jedne ta9ke u toj
bitmapi.
!ko je na datim koordinatama vrijednost 1 pro3ram ne radi ni4ta. !li ako se tu nalazi >B pro3ram treba
zamijeniti vrijednost jedinicomB a zatim zamijeniti i sve susjedne ta9ke sve dok se ne doe do ruba matrice
ili do znaka 1. Kru3im rije9imaB pro3ram treba da se pona4a kao Iflood fillJ :punjenje; u 3rafi9kim
aplikacijama: treba da popuni dio matrice sastavljen od nula omeen rubovima matrice i jedinicama.
.7
Prilikom popunjavanja kroz se matricu kree samo u smjerovima 3oreB doljeB lijevo i desnoB ali ne i po
dija3onali.
Ulaz'
&a ulazu se najprije nalazi broj & koji predstavlja dimenzije bitmape :ne vei od 1>>;B a zatim od3ovarajui
broj nula i jedinicaB te kona9no dva broja u opse3u 1C& koji predstavljaju koordinate ta9ke od koje treba
zapo9eti popunjavanje. %oordinate :1B1; od3ovaraju ta9ki u 3ornjem lijevom u3lu matrice.
Izlaz'
&a izlazu treba ispisati sadr?aj matrice nakon popunjavanjaB tako da su elementi matrice navedeni bez
razmaka a na kraju reda matrice ispisuje se znak za novi red.
%ri(jer ulaza'
1&
&&&&&&&&&&
&&&&&&&&&&
&&111111&&
&&1&&&&1&&
&&1&&&&1&&
&&1&&&&1&&
&&1&&&&1&&
&&111111&&
&&&&&&&&&&
&&&&&&&&&&
D D
%ri(jer izlaza'
&&&&&&&&&&
&&&&&&&&&&
&&111111&&
&&111111&&
&&111111&&
&&111111&&
&&111111&&
&&111111&&
&&&&&&&&&&
&&&&&&&&&&
%ri(jer ulaza'
1&
&&&&1&&&&&
&&&1&1&&&&
&&1&&&1&&&
&1&&&&&1&&
1&&&&&&&1&
&1&&&&&1&&
&&1&&&1&&&
&&&1&1&&&&
&&&&1&&&&&
&&&&&&&&&&
D D
.8
%ri(jer izlaza'
&&&&1&&&&&
&&&111&&&&
&&11111&&&
&1111111&&
111111111&
&1111111&&
&&11111&&&
&&&111&&&&
&&&&1&&&&&
&&&&&&&&&&
%oja1njenje'
1 ra9unarskoj 3rafici postoje brojni al3oritmi za flood fillB sa vi4e ili manje efikasnosti. &o u rje4enju ovo3
zadatka nije se tra?ila posebna efikasnostB sve 4to se tra?ilo je korektno rje4enje. ,ato ovdje mo?emo
primijeniti rekurzivni al3oritam koji najo9i3lednije slijedi iz postavke problema. ekurzivni al3oritam
rje4avanja ovo3 problema je sljedei: za koordinate ABD:
ako je koordinata A ili D izvan opse3a matriceB ne radi ni4ta
u suprotnomB ako se na koordinatama :ABD; nalazi jedinicaB ne radi ni4ta
u suprotnom:
na koordinate :ABD; postavi jedinicu
zamijeni vrijednosti na koordinatama: :AC1BD;B :AH1BD;B :ABDC1;B :ABDH1;
Pri prevoenju ovo3 pseudokoda u E ili Pascal trebamo voditi ra9una da indeksi niza veli9ine & u ECu su >C
:&C1; a u Pascalu 1C&.
Pro3ramski kod :E;:
2inc!ud <stdio.%/
int matrica*"00+*"00+;
/* ?oramo proslijediti velicinu matrice "unkciji posto je ona ucitana u main%u */
0oid f!oodfi!!(int C, int I, int 0!icina)
{
/* 1ko su koordinate izvan opsega matrice, ne radimo nista !prekid
"unkcije# */
if (C<0 11 I<0 11 C/=0!icina 11 I/=0!icina) return;

/* 1ko se na koordinatama nalazi jedinica, ne radimo nista */
if (matrica*C+*I+ == ") return;

/* &ostavljamo 1 na koordinate */
matrica*C+*I+=";

/* @ekurzivno pozivamo "unkciju za tacke iznad, ispod, lijevo i desno */
f!oodfi!!(C'",I,0!icina);
f!oodfi!!(C+",I,0!icina);
f!oodfi!!(C,I'",0!icina);
f!oodfi!!(C,I+",0!icina);
}
int main()
..
{
int i,(,0!icina,C,I;
scanf("%d", &0!icina);

/* 0citavamo vrijednosti u matrici */
for (i=0; i<0!icina; i++) {
for ((=0; (<0!icina; (++) {
scanf("%d", &matrica*i+*(+);
}
}

/* 0citavamo polazne koordinate 4 i 9 */
scanf ("%d %d", &C, &I);

/* &oziv "unkcije */
f!oodfi!!(C,I,0!icina);

/* 2spis matrice */
for (i=0; i<0!icina; i++) {
for ((=0; (<0!icina; (++) {
printf("%d", matrica*i+*(+);
}
/* ovi red na kraju reda matrice */
printf("6n");
}

return 0;
}
.@
F. Sortiranje
/ortiranje je preureenje neko3 niza tako da su elementi poredani po veli9iniB bilo u rastuem ili u
opadajuem redoslijedu. %od brojeva obi9no je intuitivno jasno 4ta predstavlja sortiranje. %od tekstualnih
podataka :strin3ova; obi9no se podaci sortiraju po tzv. leksiko3rafskom odnosno abecednom poretku:
!!!
!!0
!!E...
!0!
!00...
0!!...
0!0...
,!!...
,,,
Pored to3a vi mo?ete sortirati podatke proizvoljno3 tipa :3eometrijska tijelaB u9enikeB predmete; po bilo
kojem kriteriju koji defini4ete :obimB povr4inaB visinaB ocjena;.
Postoji vi4e al3oritama za sortiranje koji se razlikuju prije sve3a po performansama u razli9itim situacijama.
&pr. neki al3oritmi imaju vrlo dobre performanse ako je niz ve u3lavnom sortiran :npr. za dodavanje
novo3 elementa u sortiran niz;B dok neki daju optimalne performanse kod niza elemenata 9ija je raspodjela
u skupu mo3uih vrijednosti slu9ajna. (eutimB al3oritme sortiranja razlikujemo i po njihovoj
kompleksnosti odnosno jednostavnosti razumijevanja.
&a ovom nivou takmi9enja odlu9ili smo se da vam prezentujemo osnovne al3oritme tzv. kvadrati9ne
kompleksnostiB odnosno kompleksnosti O:n
5
;B a to su: (ubble sortB *election sort i 4nsertion sort;.
1 nastavku imate pro3ramski kod ovih al3oritama sa poja4njenjima u formi komentara.
%ro/ra(9ki ko& 9a -oja1njenje('
899
9 =mplementcije b5bble, .election i in.ertion .ort.
98
4incl5de 0.tdio.h-
4define bool int
4define tr5e 1
4define fl.e &
899
9 H5bble .ort .ortir ni2 t6o .to 5 .36om prol25 6ro2 ni2
9 5poredj5je .5.jedne elemente i mijenj im mje.to 56oli6o ni.5
9 5 i.pr3nom odno.5. Ko 2nci d 56oli6o je potrebno .ortirti
9 ni2 5 r.t5cem redo.lijed5 elementi trebj5 2mijeniti po2icij5
9 56oli6o je onj . mnjim inde6.om 3eci od .3og .ljedbeni6.
9 Llgoritm 23r.3 . i23r.3njem 6d 5 prol25 6ro2 ni2 .e ne
9 i23r.i ni jedn i2mjen, .to 2nci d .5 .3i elementi 5 i.pr3nom
9 medj5.obnom odno.5, tj. d je ni2 .ortirn.
.2
98
void b5bble_.ort(int ni2!#, int len) %
88 "He.6oncn" petlj, ne 2nmo 5nprijed 6oji je
88 potrebni broj itercij 2 .ortirnje ni2.
for (;;) %
88 Trijbl 6oj prti d li je do.lo do
88 ne6e i2mjene 5 ni25 5 o3om prol25.
bool .+pped $ false;
for (int i $ &; i 0 len - 1; ++i) %
if (ni2!i# - ni2!i + 1#) %
88 .+p
int tmp $ ni2!i#;
ni2!i# $ ni2!i + 1#;
ni2!i + 1# $ tmp;
.+pped $ true;
)
)
if (:.+pped) break;
)
)
899
9 Selection .ort .ortir ni2 t6o .to pronl2i njmnji element
9 5 ni25 i .t3lj g n pr35 po2icij5. @tim, 5 o.tt65 ni2
9 pronl2i njmnji element i .t3lj g n .ljedec5 po2icij5.
9 J3 proced5r .e pon3lj .3e do6 .e odgo3rj5ci element ne
9 .t3i n 2dnj5 po2icij5 ni2.
98
void .election_.ort(int ni2!#, int len) %
88 i je po2icij 5 ni25 n 6oj5 treb .t3iti .ljedeci njmnji
88 element.
for (int i $ &; i 0 len; ++i) %
88 , 6ojem inde6.5 5 ni25 .e nl2i tren5tno njmnji
88 prondjeni element.
int min_inde1 $ i;
88 Pro3jer3j5 .e .mo elementi i2 inde6. i, ob2irom d je
88 dio ni2 !&, i - 1# 3ec .ortirn.
for (int j $ i + 1; j 0 len; ++j) %
if (ni2!j# 0 ni2!min_inde1#) %
min_inde1 $ j;
)
)
88 Qd je prondjen njmnji element .t3lj .e n odgo3rj5c5
88 po2icij5 5 ni25.
int tmp $ ni2!i#;
ni2!i# $ ni2!min_inde1#;
ni2!min_inde1# $ tmp;
)
)
899
9 =n.ertion .ort rdi t6o .to 5 .ortirni dio ni2
9 dodje element d odgo3rj5c5 po2icij5 pri cem5 .e
9 .3i elementi 3eci od njeg pomijerj5 prem de.no.
9 , pocet65 .mo pr3i element pripd .ortirnom dijel5
9 ni2.
.<
98
void in.ertion_.ort(int ni2!#, int len) %
for (int i $ 1; i 0 len; ++i) %
88 Sljedeci element 6oji .e dodje 5 .ortirni
88 dio ni2 !&, i - 1# je element n inde6.5 i.
int no3i $ ni2!i#;
int j;
for (j $ i - 1; j -$ &; --j) %
88 S3e elemente 3ece od element 6oji .e dodje pomijeriti
88 prem de.no.
if (ni2!j# - no3i) %
ni2!j + 1# $ ni2!j#;
) else %
88 =nde6. n 6oji treb .t3iti no3i element je
88 po.lije element ni2!j# ob2irom d je ni2!j# 0$ no3i
break;
)
)
ni2!j + 1# $ no3i;
)
)
int min() %
88 N52in ni2
int n;
.cnf("%d", 7n);
int ni2!1&&&#;
for (int i $ &; i 0 n; ++i) %
.cnf("%d", 7ni2!i#);
)
88 M5n6cijm 2 .ortirnje je potrebno pro.lijediti i d52in5 ni2.
88 b5bble_.ort(ni2, n);
88 .election_.ort(ni2, n);
in.ertion_.ort(ni2, n);
for (int i $ &; i 0 n; ++i) printf("%d ", ni2!i#);
printf("Sn");
return &;
)
Za&atak F.5. Ele(entarna ne-o/o&a
Te7ina' S
Tokom nedavnih vremenskih nepo3oda izmjerena je visina snije3a u 3radovima 0i= te je napravljen spisak
oblika M#me 3rada F visina snije3a u cmM. Potrebno je ispisati isti spisak u kojem su 3radovi poredani po
visini snije3aB tako da se na prvom mjestu nalazi 3rad sa najveom visinom snije3aB zatim dru3i po visiniB
trei itd. 1koliko je u dva 3rada izmjerena ista visina snije3aB potrebno je njihova imena ispisati abecednim
odnosno leksiko3rafskim poretkom.
Ulaz
&a prvoj liniji se nalazi prirodan broj n F broj 3radova :maksimalno 1>>;.
1 sljedeih n linija nalazi se ime 3rada :du?ine maksimalno 5> znakovaB bez razmaka;B zatim razmak te cijeli
.6
broj koji predstavlja visinu snije3a u tom 3radu.
Izlaz
#zlaz se sastoji od n linija isto3 oblika kao ulazB dakle naziv 3radaB razmak te visina snije3aB pri 9emu je izlaz
sortiran kako je opisano u zadatku.
%ri(jer ulaza'
.
/arajevo 1.>
(ostar <>
Tuzla 15>
,enica 11>
0ihac 1.>
%ri(jer izlaza'
0ihac 1.>
/arajevo 1.>
Tuzla 15>
,enica 11>
(ostar <>
%ro/ra(9ki ko& <$='
2inc!ud <stdio.%/
2inc!ud <string.%/
struct sni(g {
c%ar grad*,0+;
int 0isina;
};
int main() {
int n,i,(,maC&indC;
struct sni(g ni9*"00+,tmp;
/* 0laz podataka */
scanf("%d", &n);
for (i=0; i<n; i++) {
printf ("Trad %d: ",i);
scanf("%s %d", ni9*i+.grad, &ni9*i+.0isina);
}
/* &rimjenjujemo modi"ikovani selection sort u opadajucem redoslijedu */
for (i = 0; i < n; ++i) {
/* a kojem indeksu u nizu se nalazi trenutno najveci
pronadjeni element' */
maC&indC = i;
/* &rovjeravaju se samo elementi iza indeksa i, obzirom da je
dio niza ;0, i % 1< vec sortiran' */
@>
for (( = i + "; ( < n; ++() {
/* &rovjera visine snijega */
if (ni9*(+.0isina / ni9*maC&indC+.0isina) {
maC&indC = (;
}
/* 1ko je visina snijega ista, poredimo imena gradova
leksikogra"ski */
if (ni9*(+.0isina == ni9*maC&indC+.0isina) {
if (strcmp(ni9*i+.grad, ni9*maC&indC+.grad) < 0 ) {
maC&indC = (;
}
}
}
/* 5ada je pronadjen najveci element stavlja se na odgovarajucu
poziciju u nizu' */
tmp = ni9*i+;
ni9*i+ = ni9*maC&indC+;
ni9*maC&indC+ = tmp;
}
/* 2spis */
for (i=0; i<n; i++)
printf("%s %d6n", ni9*i+.grad, ni9*i+.0isina);
return 0;
}
@1
G. Efika9no 9te-enovanje
Za&atak G.5. Efika9no 9te-enovanje
Te7ina' N
Odrediti zadnjih @ cifara broja A
n
.
Ulaz
+edna linija sa dva cijela brojaB A i nB razdvojena jednim razmakom.
>]P A ]P 51828<7@82 i > ]P n ]P 51828<7@82
Izlaz
,adnjih @ cifara broja A
n
.
%ri(jer'
Ulaz
578. 578.
Izlaz
.1.@5.
%oja1njenje'
&ajprije je potrebno primijetiti da su o3rani9enja na veli9inu ulaznih podataka zadatka prevelika da bi se
zadatak rije4io naivnom metodom C ra9unanje stepena pomou funkcije -o;B a zatim uzimanje zadnjih @
cifara rezultata.
+edna metoda za efikasno stepenovanje brojeva je sljedea. &eka treba nai A
n
. &ajprije napi4emo broj n
kao sumu stepena dvojke
n P k1 H k5 H ... H km
/ada imamo da je:
A
n
P A
:k1 H k5 H ... H km;
P A
k1
\ A
k5
\ ... \ A
km
%oristei 9injenicu da je svaki od elemenata k
i
stepen dvojkeB A
ki
mo?emo izra9unati rekurzivnom
formulom:
A
ki
P :A
:ki / 5;
;
5
%oristei binarnu reprezentaciju eksponenta nB 3ornji proizvod mo?emo ra9unati na sljedei na9in. #dui
po bitima eksponenta s desna na lijevo :od najmanje zna9ajno3 bitaB do najzna9ajnije3 bita; ukoliko je dati
bit 1B potrebno je da u kona9ni proizvod ue faktor A
k
B 3dje je k P 5
i
B a i je pozicija bita koji se razmatra :za
najmanje zna9ajan bit i P >B itd...;.
)injenica da se tra?i zadnjih @ cifara zna9i da je potrebno nai rezultat A
n
po modulu 1>>>>>>.
@5
%ro/ra(9ki ko& <$='
899
9 Jdrediti 2dnjih E cifr broj 1Un.
98
4incl5de 0.tdio.h-
int po+er(int 1, int n) %
long long .ol $ 1;
88 Trijbl b ce pred.t3ljti f6tor 6oji 5l2i 5 proi23od.
88 @ njmnje 2ncjn bit to je 1U('U&) $ 1U1 $ 1
long long b $ 1;
while (n) %
if (n 7 1 $$ 1) %
88 Hit 6oji .e r2mtr je 1, p treb 6oncno rje.enje
88 pomno2iti odgo3rj5com 3rijedno.ti 1U6
.ol 9$ b;
88 Ie25ltt po po mod5l5 1&&&&&&
.ol %$ 1&&&&&&;
)
88 Hinr* .hift 5de.no e6.ponent -- r2mtr .e .ljedeci bit
n --$ 1;
88 @ tj bit f6tor 6oji bi trebo 5ci 5 proi23od (56oli6o je bit 1)
88 je 1U('96) $ 1U6 9 1U6, . ob2irom n gore n3eden5 re65r2i3n5 form5l5.
b 9$ b;
b %$ 1&&&&&&;
)
return .ol;
)
int min() %
int 1;
int n;
.cnf("%d %d", 71, 7n);
printf("%dSn", po+er(1, n));
return &;
)
@7
H. %ohle-ni </ree&I= al/orit(i
Za&atak H.5. Lo-ov
Te7ina' N
$opov se na4ao u piljari 3dje se nalazi vi4e razli9itih 3ajbi voa i povra. /vaka 3ajba ima poznatu te?inu u
k3 :G;B kao i vrijednost svako3 k3 namirnice iz te 3ajbe. $opov ne mo?e nositi vi4e od ( kilo3rama. &ije
obavezno uzeti cijelu 3ajbuB ve lopov mo?e uzeti samo neki dio voa ili povra iz nje.
Odrediti koliko najvi4e lopov mo?e zaraditi u datoj situaciji.
Ulaz'
cijeli broj n C broj 3ajbi > ]P 5>>>> ]P n
n parova cijelih brojeva C ukupna te?ina i vrijednost kilo3rama svake od 3ajbi
cijeli broj ( C maksimalna te?ina koju lopov moze ponijeti
Izlaz'
&ajvea zarada lopova pod datim uslovima.
%ri(jer'
Ulaz
.
1. 8
5 1
1 1
@ .
7 @
1.
Izlaz
25
%oja1njenje'
(o?e se primijetiti da e lopov najvi4e zaraditi ukoliko odabere 3ajbu koja ima najveu vrijednost po
jedinici te?ine i uzme najvei mo3ui broj kilo3rama to3 proizvoda. 1koliko je mo3ue uzeti cijelu 3ajbuB
onda prelazi na onu koja ima sljedeu najbolju vrijednost po jedinici te?ine. 1koliko ne mo?e uzeti cijelu
3ajbuB uzima najvei dio koji mo?e nositi i ra9una se od3ovarajua vrijednost.
,a svrhu implementacije je mo3ue prvo sortirati niz predmetaB teB zatimB redom uzimati elemente i
dodavati na ukupnu vrijednost.
Ovaj pristup rje4avanju problema se zove pohlepni :3reedD; al3oritam iz razlo3a 4to se u svakom koraku
bira ona vrijednost koja najvi4e poboljsava rje4enje tj. izbor ne zavisi ni od jedno3 od prethodnih izbora.
@8
%ro/ra(9ki ko& <$='
4incl5de 0.tdio.h-
4define bool int
4define tr5e 1
4define fl.e &
typedef struct Predmet %
int +eight;
int 3l5e;
) Predmet;
899
9 M5n6cij 3rc tr5e 56oli6o je 3rijedno.t pr3og predmet po jedinici te2ine
9 3ec od 3rijedno.ti dr5gog predmet po jedinici te2ine.
98
bool cmp(Predmet p1, Predmet p') %
return p1.3l5e - p'.3l5e;
)
void in.ertion_.ort(Predmet ni2!#, int len) %
for (int i $ 1; i 0 len; ++i) %
88 Sljedeci element 6oji .e dodje 5 .ortirni
88 dio ni2 !&, i - 1# je element n inde6.5 i.
Predmet no3i $ ni2!i#;
int j;
for (j $ i - 1; j -$ &; --j) %
88 S3e elemente 3ece od element 6oji .e dodje pomjeriti
88 prem de.no.
if (:cmp(ni2!j#, no3i)) %
ni2!j + 1# $ ni2!j#;
) else %
88 =nde6. n 6oji treb .t3iti no3i element je
88 po.lije element ni2!j# ob2irom d je ni2!j# 0$ no3i
break;
)
)
ni2!j + 1# $ no3i;
)
)
int min() %
int n;
.cnf("%d", 7n);
Predmet predmeti!1&&&&#;
for (int i $ &; i 0 n; ++i) %
.cnf("%d %d", 7predmeti!i#.+eight, 7predmeti!i#.3l5e);
)
int +eight;
.cnf("%d", 7+eight);
88 Sortir predmete po opdj5coj 3rijedno.ti po jedinici te2ine.
in.ertion_.ort(predmeti, n);
@.
int 3l5e $ &;
for (int i $ &; i 0 n 77 +eight :$ &; ++i) %
if (+eight -$ predmeti!i#.+eight) %
88 Vopo3 mo2e ponijeti cijel5 gjb5.
+eight -$ predmeti!i#.+eight;
3l5e +$ predmeti!i#.3l5e 9 predmeti!i#.+eight;
) else %
88 Vopo3 ne mo2e ponijeti cijel5 gjb5, odredj5je .e 3rijedno.t
88 onog dijel 6oji je mog5ce ponijeti.
3l5e +$ predmeti!i#.3l5e 9 +eight;
+eight $ &;
)
)
printf("%dSn", 3l5e);
return &;
)
@@
54. O9novna /eo(etrij9ka tijela <-ravou/aoni2i, kru7ni2e=
Za&atak 54.5. Majan9ko -roklet9tvo
Te7ina' S
&au9nici su posmatrajui nebo otkrili veliku koli9inu meteora koji idu ka ,emlji i otkrili su da e pasti na
jedan od najbitnijih 3radova na ,emlji i to na datum 51.15.5>15. 3odine. (aje su ipak bile upravuZ &au9nici
su otkrili ta9ne koordinate na koje e pasti meteoriB a va4 je zadatak da odredite koliku e ta9no 4tetu oni
napraviti.
Ulaz'
Prvi red ulaza e sadr?ati brojeve mB nB kB r :mBnBk ]1>>>B r]1>>>>; F koji redom predstavljaju broj kua
oblika pravou3aonikaB kvadrata i kru?nice :kvadratu i pravou3aoniku su strane paralelne odabranom
koordinatnom sistemu;. /ljedeih m redova e sadr?ati po 9etri broja: prvi i dru3i broj su A i D koordinate
donje lijeve ta9ke pravou3aonikaB dok su trei i 9etvrti broj koordinate 3ornje desne ta9ke pravou3aonika.
,atim slijedi n redova koji sadr?e tri broja: prvi i dru3i broj su A i D koordinate donje lijeve ta9ke kvadrata
dok trei broj predstavlja du?inu nje3ovih strana. &akon to3a slijedi k redova sa po tri broja: prvi i dru3i
broj su A i D koordinate centra kru3a dok trei broj predstavlja du?inu nje3ovo3 polupre9nika. &akon to3a
slijedi r linija sa po dva broja F A i D koordinatom na koju e pasti pojedini meteor. %oordinate svih ta9aka
su cjelobrojno3 tipaB du?ine stranica i polupre9nika ne moraju biti.
Izlaz'
1 jedini red izaza potrebno je ispisati koliko e ta9no kua o4tetiti meteori.
%ri(jer ulaza'
1 1 1 .
> > 8 5
. > .
18 1 7
7 1
2 8
6 7
. 11
17 5
%ri(jer izlaza'
>
%oja1njenje <Lo2iranje take u o9novni( /eo(etrij9ki( o*li2i(a' kru7ni2a, -ravou/aonik,
kva&rat='
- %ravou/aonik'
Pravou3aonici su u potpunosti odreeni koordinatama dvije naspramne ta9ke. &a slici su to !:A
!
BD
Y
; i
0:A
0
BD
0
; . #z tih koordinata mo?emo dobiti informacije o svim dru3im osobonama pravou3aonikaB kao 4to
su du?ine stranicaB koordinate dru3e dvije ta9keB povr4inaB obim itd.
@2
/a slike je jasno da je:
A
0
P

A
E
D
0
P

D
!
A
K
P

A
!
D
K
P

D
E
a P A
E
C A
!
b P D
E
C D
!
:ove formule va?e ukoliko su stranice pravou3aonika paralelne koordinatnim osamaB 4to je skoro uvijek i
slu9aj;
&eka imamo ta9ku *:A
*
B D
*
;. Ka li ona pripada pravou3aoniku !0EK odreujemo iz uslova: A
!
X A
* X
A
E
i
D
!
X D
*
X

D
E
.
1 pro3ramskom jeziku EB to iz3leda:
if( <.1-$ L.1 77 <.10$W.1 77 <.*-$L.* 77 <.* 0$ W.*)
%
88tc6 pripd pr3o5goni65 LHWN
)
el.e
%
88tc6 ne pripd pr3o5goni65
)
- Kva&rat
%ao 4to znamoB kvadrat predstavlja specijalni slu9aj pravou3aonika te 3a je mo3ue zadati na potpuno isti
na9in. Kru3i na9in na koji se zadaju kvadrati je pomou koodinate jedne ta9ke :u na4em slu9aju to je ta9ka
!; i du?ine jedne straniceB iz 9e3a mo?emo dobiti sve ostale podatke. Ovaj na9in zadavanja je jedino mo3u
ukoliko su stranice kvadrata paralelne koordinatnim osama :4to je skoro uvijek i slu9aj;B ina9e bismo morali
zadati jo4 jedan podatak o kvadratu.
A
0
P

A
!
H a
D
0
P

D
!
A
K
P

A
!
D
K
P

D
!
H a
A
E
P

A
!
H a
D
V
P

D
V
H a
#spitivanje pripadnosti ta9ke kvadratu se vr4i analo3no kao kod pravou3aonika.
@<
- Kru7ni2a
%ru?nica je u potpunosti odreen koordinatama centra i du?inom polupre9nika.
Odreivanje da li ta9ka pripada kru3u vr4imo ispitivanjem udaljenosti te ta9ke od centra kru3a. 1kolika je
ta udaljenost vea od polupre9nikaB ta9ka ne pripada kru3u. 1 suprotnomB pripada. /a slike vidimo da je
d
1
^ r te ta9ka ! ne pripada kru3uB dok je d
5
Xr i pripada. 1daljenost dvije ta9ke ra9unamo po formuli:
1 pro3ramskom jeziku EB od3ovarajui kod je:
d $ .;rt ( (L.1-S.1)9 (L.1-S.1) + (L.*-S.*)9 (L.*-S.*) );
if (d-r)
%
88 ne pripd
)
el.e
%
88pripd
)
%ro/ra(9ki ko& <$='
4incl5de 0.tdio.h-
4incl5de 0.tdlib.h-
4incl5de 0.tring.h-
4incl5de 0mth.h-
struct tc6
%
int 1;
int *;
);
struct pr3o5goni6
%
struct tc6 donj_lije3;
struct tc6 gornj_de.n;
);
int pripd_pr3o5goni65(struct tc6 t,struct pr3o5goni6 p)
@6
%
return (t.1-$p.donj_lije3.1 77 t.*-$p.donj_lije3.* 77t.10$p.gornj_de.n.1
77 t.*0$p.gornj_de.n.*);
)
struct 63drt
%
struct tc6 donj_lije3;
flot ;
);
int pripd_63drt5(struct tc6 t,struct 63drt 6)
%
return (t.1-$6.donj_lije3.1 77 t.* -$6.donj_lije3.* 77
t.10$6.donj_lije3.1+6. 77 t.* 0$ 6.donj_lije3.*+6.);
)
struct 6r5g
%
struct tc6 .;
flot r;
);
flot 5dljeno.t(struct tc6 L, struct tc6 H)
%
return .;rt ( (L.1-H.1)9 (L.1-H.1) + (L.*-H.*)9 (L.*-H.*) );
)
int pripd_6r5g5(struct tc6 t, struct 6r5g 6)
%
flot d $ 5dljeno.t(t,6..);
return :(d -6.r);
)
int min()
%
int m,n,6,r;
struct pr3o5goni6 pr3o5gonici!1&&&#;
struct 63drt 63drti!1&&&#;
struct 6r5g 6r5go3i!1&&&#;
struct tc6 tmp;
int
5ni.teni_pr3o5gonici!1&&&#,5ni.teni_63drti!1&&&#,5ni.teni_6r5go3i!1&&&#;
/* nizovi za pracenje da li je objekat vec unisten ' ne moze se dva puta
unistiti*/
mem.et(5ni.teni_pr3o5gonici,&,sizeof 5ni.teni_pr3o5gonici);
mem.et(5ni.teni_63drti,&,sizeof 5ni.teni_63drti);
mem.et(5ni.teni_6r5go3i,&,sizeof 5ni.teni_6r5go3i);
int rj$&;
int i,j;
.cnf("%d %d %d %d",7m,7n,76,7r);
2>
for(i$&;i0m;i++)
%
.cnf("%d %d %d
%d",7pr3o5gonici!i#.donj_lije3.1,7pr3o5gonici!i#.donj_lije3.*,7pr3o5goni
ci!i#.gornj_de.n.1,7pr3o5gonici!i#.gornj_de.n.*);
)
for(i$&;i0n;i++)
%
.cnf("%d %d
%f",763drti!i#.donj_lije3.1,763drti!i#.donj_lije3.*,763drti!i#.);
)
for(i$&;i06;i++)
%
.cnf("%d %d %f",76r5go3i!i#...1,76r5go3i!i#...*,76r5go3i!i#.r);
)
for(i$&;i0r;i++)
%
.cnf("%d %d",7tmp.1,7tmp.*);
for(j$&;j0m;j++)
%
if(pripd_pr3o5goni65(tmp,pr3o5gonici!j#) 77 :
5ni.teni_pr3o5gonici!j#)
%
5ni.teni_pr3o5gonici!j#$1;
rj++;
)
)
for(j$&;j0n;j++)
%
if(pripd_63drt5(tmp,63drti!j#) 77 :5ni.teni_63drti!j#)
%
5ni.teni_63drti!j#$1;
rj++;
)
)
for(j$&;j06;j++)
%
if(pripd_6r5g5(tmp,6r5go3i!j#) 77 :5ni.teni_6r5go3i!j#)
%
5ni.teni_6r5go3i!j# $ 1;
rj++;
)
)
)
printf("%d",rj);
return &;
)
21
Za&atak 54.3. O*uhvatanje taaka
Te7ina' S
Kat je niz ta9aka u 5K prostoru zadatih preko koordinata A i D i broj . &apisati pro3ram koji odreuje
koordinate centra kru?nice sa radijusom takve da pokriva 4to vei broj ta9aka.
Ulaz'
Prvi red ulaza e sadr?ati cijeli broj B zatim slijedi broj n ta9aka u nizu :maksimalno 1>>;B nakon 9e3a
slijedi niz od n parova cijelih brojeva koji predstavljaju i 5 koordinate ta9aka.
Izlaz'
Kva cijela broja koji predstavljaju koordinate centra kru?nice sa radijusom .
%ri(jer ulaza'
7
.
8 .
2 @
7 7
. 5
8 8
%ri(jer izlaza'
. 8
%oja1njenje'
Ovdje emo primijeniti metod iscrpne pretra3e :brute force; tako 4to emo definisati pravou3aonik koji
obuhvata sve ta9ke u nizu i zatim isprobati sve koordinate unutar to3 pravou3aonika kao potencijalni centar
kru?nice. (atematski se mo?e dokazati da niti jedna kru?nica sa centrom izvan to3 pravou3aonika ne mo?e
obuhvatati vi4e ta9aka od neke od kru?nica sa centrom unutar pravou3aonika.
25
*lika 6+ 0oja2njenje -rimjera ulaza i izlaza
1 primjeru ulaza tra?en je kru3 sa radijusom 7 koji obuhvata datih . ta9aka: :8B.;B :2B@;B :7B7;B :.B5;B :8B8;.
%ao 4to vidimo sa slike 8 ta9no rje4enje je :.B8; 4to je pro3ram i ispisao.
%ro/ra(9ki ko& <$='
4incl5de 0.tdio.h-
2inc!ud <mat%.%/
struct tac<a
{
int C;
int I;
};
struct <rug
{
struct tac<a s;
f!oat r;
};
f!oat uda!(nost(struct tac<a F, struct tac<a G)
{
return sPrt ( (F.C'G.C)D (F.C'G.C) + (F.I'G.I)D (F.I'G.I) );
}
int pripada&<rugu(struct tac<a t, struct <rug <)
{
f!oat d = uda!(nost(t,<.s);
return .(d /<.r);
}
int main()
{
int r,n,i,C,I,o)u%0acno,maC&o)u%0acno;
struct tac<a ni9*"00+,do!(&!i(0o,gor&dsno,cntar;
struct <rug <;
scanf("%d", &r);
scanf("%d", &n);
for (i=0; i<n; i++)
scanf("%d %d", &ni9*i+.C, &ni9*i+.I);
/* ajprije odredjujemo pravougaonik koji obuhvata sve tacke u nizu,
preko tacaka dolje(lijevo i gore(desno */
do!(&!i(0o=gor&dsno=ni9*0+;
for (i="; i<n; i++) {
if (do!(&!i(0o.C / ni9*i+.C) do!(&!i(0o.C = ni9*i+.C;
if (do!(&!i(0o.I / ni9*i+.I) do!(&!i(0o.I = ni9*i+.I;
if (gor&dsno.C < ni9*i+.C) gor&dsno.C = ni9*i+.C;
if (gor&dsno.I < ni9*i+.I) gor&dsno.I = ni9*i+.I;
}

/* 8ada prolazimo kroz sve cjelobrojne vrijednosti u tom pravougaoniku */
maC&o)u%0acno=0;
for (C=do!(&!i(0o.C; C<=gor&dsno.C; C++) {
27
for (I=do!(&!i(0o.I; I<=gor&dsno.I; I++) {
/* &rovjeravamo koliko tacaka je obuhvaceno kruznicom sa
centrom u 4,9 */
o)u%0acno=0;
<.s.C=C;
<.s.I=I;
<.r=r;
for (i=0; i<n; i++) {
if (pripada&<rugu(ni9*i+, <)) o)u%0acno++;
}
/* /a li je taj broj veci od do sada poznatog maksimuma=
*/
if (o)u%0acno/maC&o)u%0acno) {
maC&o)u%0acno = o)u%0acno;
/* &ostavljamo trazeni rezultat na 4,9 */
cntar.C = C;
cntar.I = I;
}
}
}
/* 2spis rezultata */
printf ("%d %d6n", cntar.C, cntar.I);
return 0;
}
28
55. !a& 9a 9trin/ovi(a
Za&atak 55.5. $enzura
Te7ina' S
&a 4kolskom forumu postoji spisak cenzurisanih rije9i koje se ne smiju pojaviti u porukama koje pi4u
u9enici. Pro3ram treba potra?iti svaku od rije9i na spisku u poruci iB ako se rije9 javlja u tekstu porukeB
zamijeniti je od3ovarajuim brojem zvjezdica.
Ulaz'
&a ulazu se najprije nalazi jedan cijeli broj n :maksimalno 1>>; koji predstavlja broj rije9i koje se cenzuri4u.
,atim slijede cenzurisane rije9i u zasebnim redovima :du?ina rije9i je maksimalno 5> znakovaB rije9i ne
sadr?e razmake;.
&a kraju se nalazi tekst koji treba cenzurisati :maksimalne du?ine 1>>> znakovaB mo7e sadr?avati razmake;.
Tekst se zavr4ava znakom za novi red.
Izlaz'
Kati tekst pri 9emu je svaka od cenzurisanih rije9i zamijenjena od3ovarajuim brojem zvjezdica.
%ri(jer ulaza'
7
cenzura
nema
direktor
1 ovom tekstu nema cenzure. (i ni ne znamo sta je cenzura. !ko ne vjerujeteB pitajte direktora.
%ri(jer izlaza'
1 ovom tekstu \\\\ cenzure. (i ni ne znamo sta je \\\\\\. !ko ne vjerujeteB pitajte \\\\\\\\a.
Za&atak 55.3. %ravilan jezik
Te7ina' SDN
1 dalekoj zemlji Prdimahovini 3ovori se prdimahovinski jezik koji ima vrlo jednostavna leksi9ka pravila:
C svaka rije9 sastoji se od jedno3 ili vi4e slo3ova
C svaki slo3 sastoji se od jedno3 su3lasnika i jedno3 samo3lasnika
C izuzetnoB rije9 mo?e po9injati samo3lasnikom nakon koje3 slijede re3ularni slo3ovi
C takoe postoje veznici a i o u.
&a osnovu ovih pravila napisati primitivan spellchecker za prdimahovinski jezik. /pellchecker treba ispisati
na izlazu sve nepravilne rije9i i to onim redoslijedom kojim se javljaju u ulaznom tekstu.
Ulaz'
Tekst koji treba provjeriti. Tekst je maksimalne du?ine 1>>> znakova i mo7e sadr?avati razmakeB takoe rije9i
u tekstu mo3u uklju9ivati i velika i mala slova. Tekst se zavr4ava znakom za novi red. /ve znakove u tekstu
koji nisu slova treba posmatrati kao 3rani9nike izmeu rije9i: npr. !baba8pipi je ispravan tekst jer sadr?i
2.
rije9i ababa i pipi razdvojene cifrom 8 koja nije slovo pa je prema tome 3rani9nik izmeju rije9i.
Izlaz'
/pisak nepravilnih rije9i u tekstuB pri 9emu je svaka rije9 ispisana u zasebnom redu.
%ri(jer ulaza'
!bababa cecece i dodod bababa. 0a abab cecece dodo. 'u3u3uCbebe dododo. !aba dede: a33e dudu
bibibi.
%ri(jer izlaza'
dodod
abab
!aba
a33e
%ro/ra(9ki ko& <$='
2inc!ud <stdio.%/
2inc!ud <std!i).%/
2inc!ud <string.%/
/* 8tandardna "unkcija za unos stringa' vel 3 velicina stringa*/
0oid unsi(c%arD string, int 0!)
{
int i=0;
do
{
Dstring++ = gtc%ar();
i++;
if (i==0!) break;
} while (D(string'") .= $6n$);
D(string'") = $60$;
}
c%ar u!a9*"00"+;
/*
sluzi za ispisivanje ulaznog stringa od indeksa i do indeksa j
*/
0oid ispisi(int i,int ()
{
while(i<('")
{
printf("%c",u!a9*i+);
i++;
}
printf("6n");
}
/*
ispituje da li je znak c slovo
*/
int s!o0o(c%ar c)
2@
{
return ((c/=$a$ && c<=$9$) 11 (c/=$F$ && c<=$U$));
}
/*
ispituje da li je znak c samoglasnik
*/
int samog!asni<(c%ar c)
{
return (c==$a$ 11 c==$F$ 11 c==$$ 11 c==$V$ 11 c==$i$ 11 c==$=$ 11 c==$o$ 11
c==$W$ 11 c==$u$ 11 c==$L$);
}
/*
ispituje da li je znak c veznik de"inisan u zadatku
*/
int 09ni<(c%ar c)
{
return (samog!asni<(c) && c.=$$ && c.=$V$);
}
/*
"unkcija analizira rijec, ispisuje je ukoliko nije pravilna, vraca kao rezultat
indeks od kojeg pocinje sljedeca rijec
*/
int ana!i9ira(&ri(c(int i)
{
int (=i,<=i;
/*
petlja koja odredjuje do kojeg indeksa ulaza je trenutna rijec
*/
while(s!o0o(u!a9*(+++));
/*
ukoliko je rijec duga jedan znak, ispituje da li je taj znak veznik
*/
if(.s!o0o(u!a9*i+"+))
{
if(.09ni<(u!a9*i+))
{
printf("%c6n",u!a9*i+);
return (;
}
}
/*
ukoliko je prvi znak samoglasnik, preskacemo ga
*/
if(samog!asni<(u!a9*i+))
{
<++;
}
/*
preostali broj znakova mora biti paran da bi rijec bila korektna
*/
if((('<'")%,.=0)
{
ispisi(i,();
22
return (;
}
/*
ispituje da li ostatak rijeci ima pravilnu strukturu
*/
for(;<<('";<+=,)
{
if(samog!asni<(u!a9*<+) 11 .samog!asni<(u!a9*<+"+))
{
ispisi(i,();
return (;
}
}
return (;
}
int main()
{
int i=0;
int !n&u!a9;
unsi(u!a9,"000);
!n&u!a9 = str!n(u!a9);
i=0;
while(i<!n&u!a9)
{
if(s!o0o(u!a9*i+))
i = ana!i9ira(&ri(c(i);
else i++;
}
return 0;
}
Za&atak 55.>. %rije(ni i9-it
Te7ina' S
&akon prijemno3 ispita na nekom fakultetu napravljena su dva spiska: kandidati koji su primljeni na
fakultet i kandidati koji nisu primljeni. !li neposredno prije objavljivanja spiska otkriveno je da je
napravljena 3re4kaZ &aime neki kandidati su se javili na oba spiska. &api4ite pro3ram koji e pomoi
osoblju fakulteta da popravi ovu 3re4ku tako 4to e ispisati imena svih takvih kandidata kako bi se
provjerilo da li su isti primljeni ili ne. edoslijed ispisanih imena treba biti isti kao u prvom spisku.
Ulaz'
Eijeli broj koji ozna9ava broj primljenih kandidata.
/pisak primljenih kandidata u obliku M#me PrezimeMB pri 9emu je svaki kandidat u zasebnom redu.
Eijeli broj koji ozna9ava broj odbijenih kandidata.
/pisak odbijenih kandidata u obliku M#me PrezimeMB pri 9emu je svaki kandidat u zasebnom redu.
1 rije9ima #me i Prezime ne mo3u se javiti razmaci. (aksimalna du?ina imena i prezimena je po 5>
2<
znakova.
Izlaz'
#mena i prezimena kandidata koji se nalaze na oba spiska u obliku M#me PrezimeMB pri 9emu je svaki
kandidat u zasebnom redu.
Za&atak 55.@. S-ell2he2ker
Te7ina' SDN
Ovaj zadatak je bio na Kantonalnom takmienju iz informatike 2007. godine
"jerovatno ste upoznati sa tzv. spell checker pro3ramima. /vaki od tih pro3rama sadr?i fajl sa odreenim
brojem rije9i koje zajedno 9ine rje9nik. /lu?i se tim skupom rije9iB pro3ram analizira dati tekst i u njemu
pronalazi rije9i koje se ne nalaze u nje3ovom rje9niku. &a taj na9in mo3ue je pronai rije9i koje nisu
pravilno spelovane.
"a4 zadatak je da napravite pro3ram koji e:
a; koristei dati rje9nik analizirati dati tekst u odreenom jeziku i nepoznate rije9i ispisati na ekran.
&akon to3a treba ispisati i broj nepoznatih rije9i.
b; za nepoznate rije9i poku4ati utvrditi ispravnu rije9 i ponuditi korisniku ispravku teksta
zamjenom po3re4no napisane rije9i sa odabranom rije9i. $ista mo3uih ispravnih rije9i je isti korijen
rije9i u odnosu na nepoznatu rije9. %orijen rije9i je du?ina rije9i minus jedan znak.
Ulaz'
&a ulazu se najprije nalazi cijeli broj & :maksimalno 1>>>; koji predstavlja broj rije9i u rje9niku.
,atim su date rije9iB po jedna u svakom redu :unutar rije9i se ne nalazi razmak;.
&akon to3a je dat tekst koji treba prekontrolisati u formi niza rije9i zaklju9no sa novim redom :tekst mo?e
sadr?avati znak razmak;.
Izlaz'
&a izlazu treba najprije ispisati broj rije9i koje nisu prepoznate u rje9nikuB a zatim u svakom redu ispisati
nepoznatu rije9B znak razmakB a zatim eventualnu zamjensku rije9 koja je pronaena u rje9niku :ili ako nije
pronaena rije9 ne treba ispisati ni4ta;. !ko u rje9niku postoji vi4e rije9i koje zadovoljavaju kriterij :sva
slova jednaka osim zadnje3;B treba kao zamjensku ponuditi onu koja je prva navedena u rje9niku.
26
53. )eliki *roj
,adaci na informati9koj olimpijadi 9esto zahtijevaju rad sa brojevima toliko velikim da se oni ne mo3u
pohraniti u tipove podataka koje podr?avaju pro3ramski jezici EB EHH i Pascal :barem ne precizno;. /to3a
se 9esto zahtijeva da razvijete posebnu pro3ramsku klasu ili biblioteku za rad sa ovakvim brojevimaB pri
9emu je broj predstavljen nizom :cifara;. (atemati9ke operacije nad ovakvim brojevima su takoe posebna
problematika.
Za&atak 53.5. Z*ir i -roizvo& &va velika *roja
Te7ina' N
Ovaj zadatak je bio na Kantonalnom takmienju iz informatike 2010. godine
&a ulazu se nalaze se dva cijela broja du?ine maksimalno 1>> cifara. Kru3im rije9imaB ovi brojevi mo3u biti
dosta vei od najvee3 broja koji se mo?e dr?ati u cjelobrojnom tipu podataka neko3 pro3ramsko3 jezika.
/vaki broj se nalazi u zasebnom redu.
&apisati pro3ram koji izra9unava i ispisuje sumu i proizvod ova dva broja. /uma i proizvod takoer trebaju
biti u zasebnim redovima.
Ulaz'
Kvije linije koje predstavljaju dva proizvoljno velika cijela broja.
Izlaz'
Kvije linije koje predstavljaju sumu i proizvod ova dva broja.
%ri(jer ulaza'
1>>>>>>>>>>>>>>>>>>>
5>>>>>>>>>>>>>>>>>>>
%ri(jer izlaza'
7>>>>>>>>>>>>>>>>>>>
5>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
%ro/ra(9ki ko& <$='
4incl5de 0.tdio.h-
/* 8ljedece "unkcije rade tacno samo za pozitivne brojeveA */
/* &omocna "unkcija za ispis velikog broja na ekran */
0oid ispisi8i9(int ni9*+, int 0!)
{
int i;
for (i=0; i<0!; i++)
printf("%d", ni9*i+);
printf("6n");
}
/* 6unkcija prima dva niza br1 i br), njihove velicine velbr1 i velbr), te
treci niz rez u koji treba upisati rezultat'
Braca broj elemenata u nizu rez'
<>
&ri tome br1 uvijek mora biti veci od br)A */
int sumaGro(0a(int )r"*+, int 0!)r", int )r,*+, int 0!)r,, int r9*+)
{
/* @acunanje zbira */
int 0!r9 = 0!)r"+";
int ra9!i<a&0!icina = 0!)r" ' 0!)r,;
int prnos = 0;
int i;
for (i = 0!)r"'"; i/=0; i'') {
r9*i+"+ = )r"*i+ + prnos;
if (i/=ra9!i<a&0!icina) r9*i+"+ += )r,*i'ra9!i<a&0!icina+;
prnos = r9*i+"+H"0;
r9*i+"+ = r9*i+"+%"0;
}
if (prnos==") r9u!tat*0+=";
else {
/* .risemo vodecu nulu iz niza !iako ne smeta# */
for (i=0; i<0!)r"; i++)
r9*i+=r9*i+"+;
0!r9'';
}
return 0!r9;
}
/* 6unkcija prima niz, velicinu niza vel i neki broj,
racuna proizvod niza brojem i upisuje u niz rez'
6unkcija vraca velicinu niza rez' */
int proi90od8i9aGro(m(int ni9*+, int 0!, int )ro(, int r9*+)
{
int 0!r9 = 0!+";
int prnos = 0;
int i;
for (i=0!; i/0; i'') {
r9*i+ = 0*i'"+D)ro( + prnos;
prnos = r9*i+H"0;
r9*i+ = r9*i+%"0;
}
if (prnos/0) r9*0+=prnos;
else {
/* .risemo vodecu nulu iz niza !iako ne smeta# */
for (i=0; i<0!; i++)
r9*i+=r9*i+"+;
0!r9'';
}
return 0!r9;
}
/* 6unkcija prima dva niza br1 i br), njihove velicine velbr1 i velbr), te
treci niz rez u koji treba upisati rezultat'
Braca broj elemenata u nizu rez' */
int proi90odGro(0a(int )r"*+, int 0!)r", int )r,*+, int 0!)r,, int r9*+)
{
int md(ur9u!tati*0!)r,+*0!)r"+0!)r,+;
<1
int i,(;
/* 2zracunavamo medjurezultate */
for (i=0; i<0!)r,; i++) {
/* ?nozimo br1 i%tim clanom niza br) i smjestamo u niz medjurezultata
*/
int du9ina = proi90odB<toraGro(m()r", 0!)r", )r,*i+,
md(ur9u!tati*i+);
/* &omjeramo medjurezultat za i mjesta udesno */
for ((=du9ina'"; (/=0; ('')
md(ur9u!tati*i+*(+i+ = md(ur9u!tati*i+*(+;
/* 0praznjeni prostor na pocetku popunjavamo nulama */
for ((=0; (<i; (++)
md(ur9u!tat*i+*(+ = 0;
}

/* uliramo niz rez */
for (i=0; i<0!)r,; i++)
r9*i+ = 0;
/* 8umiramo medjurezultate u niz rez */
int no0adu9ina = 0!)r,;
for (int i=0; i<0!)r,; i++) {
/* 8abiramo i%ti medjurezultat sa nizom rez i smjestamo u tmpniz */
int tmpni9*no0adu9ina+"+;
no0adu9ina = sumaGro(0a(r9, no0adu9ina, md(ur9u!tati*i+, 0!)r,,
tmpni9);
/* Bracamo iz niza tmpniz u niz rez */
for (int (=0; (<no0adu9ina; (++)
r9*(+ = tmpni9*(+;
}
return no0adu9ina;
}
int main()
{
/* izovi ci"ara */
int )r"*"00+, )r,*"00+, suma*,00+, proi90od*,00+;
/* .rojevi ci"ara u nizovima */
int 0!)r", 0!)r,, 0!suma, 0!proi90od;
int i;
/* .rojeve moramo citati znak po znak */
c%ar 9na<;
/* &etlja za citanje prvog broja */
0!)r"=0;
9na< = gtc%ar();
while (9na< .= $6n$) {
)r"*0!)r"+ = 9na< ' $0$;
0!)r"++;
<5
9na< = gtc%ar();
}
/* &etlja za citanje drugog broja */
0!)r,=0;
9na< = gtc%ar();
while (9na< .= $6n$) {
)r,*0!)r,+ = 9na< ' $0$;
0!)r,++;
9na< = gtc%ar();
}
/* 6unkcije za sumu i prozivod */
0!suma = sumaGro(0a()r", 0!)r", )r,, 0!)r,, suma);
0!proi90od = proi90odGro(0a()r", 0!)r", )r,, 0!)r,, proi90od);
/* 2spis sume i proizvoda */
ispisi8i9(suma, 0!suma);
ispisi8i9(proi90od, 0!proi90od);
return 0;
}
<7
5>. 8rafovi i 9ta*la
Za&atak 5>.5. %re9je&anje
Te7ina' N
+unak ove pri9e &.&. 9esto mora da putuje. %ao najudobniji vid transporta koristi isklju9ivo avionski.
Obzirom da je upoznat sa podatkom da se veina nesrea de4ava prilikom uzlijetanja i slijetanja on svoju
rutu uvijek bira isklju9ivo prema broju presjedanja koja mora da napravi. &jemu nije bitno koliko du3o e
putovatiB spreman je du?e biti u avionu da bi izbje3ao dodatna slijetanja i uzlijetanja. &i cijena nije bitnaB
tro4kove u svakom slu9aju snosi firma. Obzirom da sve putni9ke a3encije imaju softver koji nalazi najkrae
ili najjefitnije ruteB &.&. je prisiljen da uvijek svoju rutu bira ru9no. Pomozite mu i napi4ite pro3ram koji e
mu pomoi u izboru rute.
Ulazni -o&a2i
1 ulaznoj datoteci Ipresjedanje.inJ na prvoj liniji nalaze se dva cijela broja & :> ] & X 1>.>>>; i ( :> ] (
X 1>>.>>>;. 0roj & je ukupan broj 3radovaB dok je broj ( ukupan broj letova koji postoje izmeu ovih
3radova. 'radovi su numerisani brojevima od > do &C1. 1 svakoj od narednih ( linija nalaze se po dva
cijela broja a
i
i b
i
:> ] a
i
B b
i
] &; meusobno razdvojena razmakom. ,na9enje je da postoje letovi izmeu
3radova a
i
i b
i
i to u oba smjera. &a posljednjoj liniji ulazne datoteke nalaze se dva cijela broja A i D :> ] AB D
] &; meusobno razdvojena razmakom. &.&. ?eli da putuje iz 3rada A u 3rad D.
Izlazni -o&a2i
1 izlaznu dateteku Ipresjedanje.outJ trebate na prvoj i jedinoj liniji trebate ispisati jedan cio broj koji
predstavlja du?inu rute sa najmanjim brojem presjedanja izmeu od 3rada A do 3rada D. 1koliko ne postoji
tra?ena rutaB ispi4ite tekst ITrazena ruta ne postoji.J.
%ri(jer 5
presjedanje.in
D E
& 1
1 '
' "
" C
& '
1 "
& C
presjedanje.out
"
%ri(jer 3
presjedanje.in
C '
& 1
' "
& '
presjedanje.out
Kr2en r5t ne po.toji.
<8
!je1enje
&ajprirodniji na9in rje4avanja ovo3 i sli9nih problema je primjenom 3rafovaB odnosno al3oritama za
3rafove. &eformalnoB pod 3rafom smatramo 3eometrijsku strukturu koja se sastoji od skupine objekata
koji se nazivaju 9vorovi 3rafa i koji su meusobno povezani vezama koje se nazivaju 3rane 3rafa. 1 ovom
zadatku 9vorovi 3rafa bi bili 3radoviB a 3rane 3rafa bi bili letovi izmeu 3radova. Postoje usmjereni i
neusmjereni 3rafovi. %od usmjerenih 3rafova mo3ue je da postoji 3rana od 9vora a do 9vora bB a da
istovremeno ne postoji 3rana od 9vora b do 9vora a. Postoje 3rafovi kod kojih se uz svaku 3ranu ve?e i
odreeni broj koji se naziva te?ina te 3rane. Obzirom da nama nije od interesa du?ina niti cijena odreenih
letova koji bi se mo3li modelirati kao te?ine odreenih 3ranaB mi emo koristiti tzv. nete?inski 3raf. +edan
od na9ina predstavljanja 3rafova u memoriji je lista susjedstva. &ajprije sve 9vorove 3rafa numeri4emo
brojevima od > do &C1B 3dje je & ukupan broj 9vorova u 3rafu. 1 ovom zadatku ovakva numeracije je
osi3urana samom postavkom. /ada se uz svaki 9vor A ve?e niz cijelih brojeva izmeu > i &C1. /vaki element
to3 niza D
i
ozna9ava da postoji 3rana izmeu 9vora A i 9vora D
i
. &a primjerB sljedei skup 3lobalnih varijabli
u potpunosti opisuje 3raf koji emo koristiti u rje4enju ovo3 zadatka.
con.t int m1_n $ 1&&&&;
int li.t_.5.jed.t3!m1_n#!m1_n#;
int li.t_.5.jed.t3_d52in!m1_n# $ %&);
int n;
maAQn je maksimalni mo3ui broj 9vorova :dato postavkom zadatka;. %oristimo nizove i matrice 9ije su
dimenzije unaprijed odreene kako bismo izbje3li dinami9ku alokaciju memorije. n je broj 9vorova koji
stvarno postoje u 3rafu :n X maAQn;. listaQsusjedstva je matrica dimnezija maAQn_maAQn od koje se
ustvari koristi najvi4e n_n elemenata. /vaki od nizova listaQsusjedstvaRiS :> X i ] n; predstavlja niz 9vorova
koji su povezani sa 9vorom i. Ku?ina ovih nizova upisana je u nizu listaQsusjedstvaQduzinaB tako da je
listaQsusjedstvaQduzinaRiS du?ina niza listaQsusjedstvaRiS. 1 naj3orem slu9aju jedan 9vor mo?e imati 3ranu
do svih ostalih 9vorovima i do samo3 sobe :iako 3rana do samo3 sebe u ovom zadatku nema neko3 smisla;.
Prema tomeB nijedan od ovih nizova ne mo?e biti du?i od n elemenata. #z ovo3a je jasno za4to su
maksimalne dimenzije matrice listaQsusjedstva n_n odnosno maAQn_maAQn.
Kodavanje 3rane u 3raf je jednostavna operacija i sastoji se od dodavanja elemenata u listu susjedstva.
Obzirom da je postavka zadatka takva da namee kori4tenje neusmjereno3 3rafa :letovi su uvijek u oba
smjera;B to je prilikom dodavanja 3rane izmeu 9vorova a i b neophodno dati i 3ranu izmeu 9vorova b i a.
0oid doda(&granu(int a, int ))
{
!ista&sus(dst0a*a+*!ista&sus(dst0a&du9ina*a++ = );
++!ista&sus(dst0a&du9ina*a+;
!ista&sus(dst0a*)+*!ista&sus(dst0a&du9ina*)++ = a;
++!ista&sus(dst0a&du9ina*)+;
}
(eu osnovne al3oritme teorije 3rafova spadaju al3oritmi kretanja kroz 3raf. Postoje dva bazna al3oritma
za kretanje kroz 3raf: pretra3a 3rafa po 4irini :breadthCfirst searchB 0-/; i pretra3a 3rafa po dubini :depthC
first searchB K-/;. %od 0-/ pretra3eB kreemo od proizvoljno3 9vora 3rafaB koji ozna9imo sa >. /ve
nje3ove susjede ozna9imo sa 1. 1 sljedeoj iteracijiB kreemo od 9vorova koji su ozna9eni sa 1B njihove
susjede koji nisu bili ranije ozna9eni ozna9imo sa 5. Ovaj postupak nastavljamo dalje tako da u iCtoj iteraciji
sve susjede 9vorova ozna9enih sa i koji nisu bili ranije ozna9eni ozna9imo sa iH1. Postupak se prekida kada
dalje obilje?avanje vi4e nije mo3ue. Primijetimo da oznake dodijeljene pojedinim 9vorovima ujedno
<.
predstavljaju najkrae udaljenosti pojedinih 9vorova od startno3 9voraB tako da je ovaj postupak po3odan u
slu9aju da treba nai najkrai put od po9etno3 9vora do neko3 zadano3 9vora :za nete?inski 3raf;. /lijedi
jedna implementacija 0-/ pretra3e u pro3ramskom jeziku EHH. &apomenimo da postoje zna9ajno
efikasnije implementacije ali one uklju9uju upotrebu strukture podataka koja se naziva red :en3l. Lueue;.
int na(<raca&ruta(int pocta<, int <ra()
{
//iz u kojem su upisane oznake :vorova za .68 pretragu
int o9na<a*maC&n+;
//2nicijalno svi :vorovi imaju oznaku %1, tj' nisu ozna:eni
for (int i = 0; i < n; ++i)
o9na<a*i+ = '";
//Cvor od kojeg se po:inje .68 pretraga ima oznaku 0
o9na<a*pocta<+ = 0;
//Barijabla za oznaku koja se trenutno obraDuje
int trnutna&o9na<a = 0;
/*Barijabla koja signalizira da li je posjeEen barem jedan novi :vor u
*prethodnoj iteraciji' 2nicijalno je postavljena na true da bi se osigurao
*prvi ulazak u 7hile petlju*/
)oo! pos(cn&)arm&(dan&c0or = tru;
while (pos(cn&)arm&(dan&c0or)
{
pos(cn&)arm&(dan&c0or = fa!s;
/*alazimo :vorove :ija je trenutna oznaka ona koja se obraDuje u
*ovoj iteraciji*/
for (int trnutni&c0or = 0; trnutni&c0or < n; ++trnutni&c0or)
if (o9na<a*trnutni&c0or+ == trnutna&o9na<a)
/*8ve prethodno neposjeEene :vorove iz liste susjedstva ovog
*:vora ozna:avamo sa sljedeEom oznakom*/
for (int ( = 0; ( < !ista&sus(dst0a&du9ina*trnutni&c0or+; ++()
{
int sus(dni&c0or = !ista&sus(dst0a*trnutni&c0or+*(+;
if (o9na<a*sus(dni&c0or+ == '")
{
o9na<a*sus(dni&c0or+ = trnutna&o9na<a + ";
pos(cn&)arm&(dan&c0or = tru;
}
}
//0 narednoj iteraciji treba obraditi sljedeEu oznaku
++trnutna&o9na<a;
}
/*5ako je kod neteFinskih gra"ova oznaka u .68 pretrazi ustvari najkra:a
*udaljenost od po:etnog :vora vra:amo oznaku :vora kraj' 1ko je njegova
*oznaka %1, onda :vor nije bio nikako posjeEen, pa ne postoji ruta od
*:vora pocetak do :vora kraj*/
return o9na<a*<ra(+;
}
#mplementacija ostatka pro3rama koja slijedi sastoji se od u9itavanja podataka iz ulazne datoteke u
specificiranom formatuB poziva napisane 0-/ pretra3e i ispisa dobijenih rezultata u nevedenom formatu.
int main()
{
X=AVD u!a9na&datot<a = fopn("prs(dan(.in", "r");
X=AVD i9!a9na&datot<a = fopn("prs(dan(.out", "#");
<@
//0:itavanje podataka iz ulazne datoteke
int m;
fscanf(u!a9na&datot<a, "%d %d", &n, &m);
for (int i = 0; i < m; ++i)
{
int a, );
fscanf(u!a9na&datot<a, "%d %d", &a, &));
doda(&granu(a, ));
}
int C, I;
fscanf(u!a9na&datot<a, "%d %d", &C, &I);
//ajkra:a ruta se odreDuje primjenom .68 pretrage
int uda!(nost = na(<raca&ruta(C, I);
//2spis rezultata u izlaznu datoteku
if (uda!(nost == '")
fprintf(i9!a9na&datot<a, "Qra9na ruta n posto(i.6n");
else
fprintf(i9!a9na&datot<a, "%d6n", uda!(nost);
fc!os(u!a9na&datot<a);
fc!os(i9!a9na&datot<a);
return 0;
}
Za&atak 5>.3. :IBAMK
Te7ina' N
1slijed obimnih snije?nih padavina 0#=!(%Cov pozivni centar je bio zatrpan pozivima. &aj9e4e pitanje
je bilo da li su prohodni putevi izmeu dva 3rada. "a4 zadatak je da napi4ete pro3ram koji e pomoi
operaterima u pozivnom centru da brzo i jednostavno od3ovore na takve upite.
Ulazni -o&a2i
1 ulaznoj datoteci Ibihamk.inJ na prvoj liniji nalazi se dva cijela broja # :0 ] # 1.000; i , :0 ] ,
100.000;. 0roj # je ukupan broj 3radovaB dok je broj , ukupan puteva koje 0#=!(% ima u svojoj bazi. 1
svakoj od narednih , linija nalaze se po dva naziva 3radova a
i
i b
i
meusobno razdvojena razmakom
izmeu kojih postoji put. (o?ete smatrati da se nazivi 3radova sastoje isklju9ivo od malih i velikih slova i
znakova I_J koji se koriste onda kada bi se ina9e koristio razmak u nazivu 3rada F npr. Banja_Luka.
&aziv niti jedno3 3rada nee biti du?i od 7> karaktera. /lijedi najvi4e 1>.>>> linija. /vaka linija je u jednom
od sljedea tri formata:
IN Prvi_grad Drugi_gradJ C Ozna9ava da put izmeu 3radova PrviQ3rad i Kru3iQ3rad
vi4e nije prohodan uslijed snije?nih padavinaU
IP Prvi_grad Drugi_gradJ C Ozna9ava da je put izmeu 3radova PrviQ3rad i Kru3iQ3rad
o9i4en i opet prohodanU
I? Prvi_grad Drugi_gradJ C Predstavlja upit da li je put izmeu 3radova PrviQ3rad i
Kru3iQ3rad prohodanU
IXJ C &aredba za prekid rada pro3rama.
Ove podatke trebate obraivati sekvencijalnoB odnosno od3ovor na upit da li je put izmeu dva 3rada
prohodan treba dati samo na osnovu podataka koji su u datoteci nalaze prije samo3 upita.
Izlazni -o&a2i'
1 izlaznu dateteku Ibihamk.outJ trebate ispisati po jednu liniju za svaki postavljeni upit iz ulazne
<2
datotekeB a koja predstavlja od3ovor na od3ovarajui upit iz ulazne datoteke. 1koliko je put prohodanB
treba ispisati tekst u obliku IPut izmedju gradova Prvi_grad i Drugi_grad je
prohodan.J. !nalo3no ukoliko put nije prohodanB treba ispisati tekst u obliku IPut izmedju
gradova Prvi_grad i Drugi_grad nije prohodan.J.
%ri(jer'
bihamk.in
E E
Srje3o Qi.elj6
Srje3o Ti.o6o
Ti.o6o Q6nj
Q6nj @enic
Qi.elj6 @enic
@enic Kr3ni6
X Srje3o Kr3ni6
, Ti.o6o Q6nj
X Srje3o Q6nj
, Qi.elj6 @enic
X Srje3o Kr3ni6
P Ti.o6o Q6nj
X Kr3ni6 Srje3o
P
bihamk.out
P5t i2medj5 grdo3 Srje3o i Kr3ni6 je prohodn.
P5t i2medj5 grdo3 Srje3o i Q6nj je prohodn.
P5t i2medj5 grdo3 Srje3o i Kr3ni6 nije prohodn.
P5t i2medj5 grdo3 Kr3ni6 i Srje3o je prohodn.
!je1enje
Prirodan na9in modeliranja ovo3 problema je kori4tenjem 3rafova. +edan od na9ina predstavljanja 3rafova u
memoriji je (atri2a 9u9je&9tva. &ajprije sve 9vorove 3rafa numeri4imo brojevima od 0 do #%1B 3dje je #
ukupan broj 9vorova u 3rafu. )vorovi u ovom zadatku ozna9eni su nizovima karaktera :strin3ovima;.
/lijedi implementacija funkcije koja osi3urava jednozna9no preslikavanje naziva 3radova na brojeve od 0 do
#%1.
int numrisi&grad(c%ar na9i0&grada*+)
{
/*8tati:ke varijable !:uvaju vrijednost izmeDu poziva "unckije# kojima
*memoriGemo preslikavanje*/
static c%ar numraci(a&grado0a*maC&n+*3"+;
static c%ar numrisano&grado0a = 0;
//&rvo pretraFimo listu veE numerisanih gradova'
int i;
for (i = 0; i < numrisano&grado0a; ++i)
if (strcmp(na9i0&grada, numraci(a&grado0a*i+) == 0)
/*0koliko grad sa traFenim nazivom postoji varijabla i Ee imati
*vrijednost indeksa niza gdje je smjeGten naziv numerisanog niza*/
break;
/*0koliko grad sa traFenim nazivom ne postoji, varijabla i Ee imati
*vrijednost ukupnog broja do tada memorisanih gradova !nakon Gto se zavrGe
*sve iteracije gornje "or petlje*/
if (i == numrisano&grado0a)
{
//0koliko grad prije nije zapamEen, uradimo to sada
<<
strcpI(numraci(a&grado0a*i+, na9i0&grada);
++numrisano&grado0a;
}
/*2ndeks niza gdje je memorisan naziv grada predstavlja jedinstveni cijeli
*broj na koji se taj naziv preslikava*/
return i;
}
(atrica susjedstva & je matrica koja se sastoji od jedinica i nula dimenzije NN. !ko je element a
ij
matrice
& jedinicaB tada postoji 3rana od 9vora i do 9vora j. /uprotnoB ako je element a
ij
matrice & nulaB tada ne
postoji 3rana od 9vora i do 9vora j. /kup sljedeih 3lobalnih varijabli je dovoljan za potpuni opis kori4teno3
3rafa.
con.t int m1_n $ 1&&&;
int n;
bool mtric_.5.jed.t3!m1_n#!m1_n#;
Prednost predstavljanja 3rafa matricom susjedstva u odnosu na listu susjedstva o3leda se u3lavnom u
efikasnom uklanjanju ve postojeih 3rana i efikasnom provjerom da li postoji 3rana izmeu dva 9vora.
Ova prva osobina daje matrici susjedstva prednost za ovaj zadatak zbo3 potrebe da se odreene 3rane 3rafa
bri4u :kada od3ovarajui put postane neprohodan;. /a dru3e straneB iz liste susjedstva mo?e se efikasnije
dobiti lista svih 9vorova sa kojim odreeni 9vor dijeli 3ranuB 4to listu susjedstva 9ini efikasnijim izborom za
:izmeu ostalo3; al3oritme kretanja kroz 3raf. Ovo listi susjedstva takoer daje prednost za ovaj zadatak
zbo3 potrebe kori4tenja neko3 od al3oritama za kretanja kroz 3raf da bi se provjerilo da mo3ue putovati
izmeu dva 3rada. Optimalan izbor strukture za predstavljanje 3rafa u memoriji bi uklju9ivao kombinaciju
liste susjedstva sa dodatnom oznakom da li je odreeni put izmeu dva 3rada prohodan. #pakB zbo3
jednostavnosti i za potrebe ilustracije kori4tenja matrice susjedstva u ovom rje4enju je kori4tena matrice
susjedstva kao na9in predstavljanja 3rafova u memoriji.
Kodavanje 3rane u 3raf i brisanje 3rane iz 3rafa su sada vrlo jednostavne operacije. /lijede njihove
implementacije. &apomenimo da opet koristimo neusmjereni 3raf.
//6unkcija za dodavanje grane u neusmjereni gra"
0oid doda(&granu(int a, int ))
{
matrica&sus(dst0a*a+*)+ = tru;
matrica&sus(dst0a*)+*a+ = tru;
}
//6unkcija za brisanje grane iz neusmjerenog gra"a
0oid o)risi&granu(int a, int ))
{
matrica&sus(dst0a*a+*)+ = fa!s;
matrica&sus(dst0a*)+*a+ = fa!s;
}
!l3oritmi kretanja kroz 3raf se mo3u koristiti da bi se provjerilo da li postoji na9in da se doe od 9vora a
do 9vora b. %od "S -retra/e kreemo od proizvoljno3 9vora 3rafaB koji ozna9avamo sa >. Od to3 9vora
se kreemo dalje ka proizvoljnom 9voruB koji ozna9avamo oznakom 1. 1 svakom korakuB trudimo se da
nastavljamo dalje prema bilo kojem neozna9enom 9voruB pri 9emu svaki 9vor u koji smo do4li obilje?avamo
sa oznakom koja je za jedinicu vea od oznake 9vora iz koje3 smo krenuli. Postupak nastavljamo sve dok ne
<6
doemo do 9vora iz koje3 dalje ne vodi niti jedna 3rana ka nekom neozna9enom 9voru. 1 tom slu9ajuB
vraamo se nazad du? puta kojim smo do4li do prvo3 9vora iz koje3 postoji 3rana koja vodi ka nekom
neozna9enom 9voru. Tada nastavljamo du? te 3raneB dok ponovo ne doemo do 9vora iz koje3 nije
mo3ue dalje kretanje prema nekom neozna9enom 9voru. Postupak se ponavlja dok ne iscrpimo svaku
dalju mo3unost kretanja. &ajkra9a implementacija K-/ pretra3e je rekurzivna. 1 ovom zadatku oznaka
9vorova kao rezultat K-/ pretra3e nije od posebno3 interesa pa emo samo koristi jedan 3lobalni niz koji
ozna9ava da li je 9vor posjeen ili nije.
bool df._po.jecen_c3or!m1_n#;
ekurzivna implementacija K-/ pretra3e bazirana je na 9injenici da se za vrijeme K-/ pretra3e uvijek
poku4ava posjetiti neki novi 9vor koji nije prethodno posjeen :a to ustvari zna9i pokrenuti novu K-/
pretra3u u 9voru koji ?elimo posjetiti;B dok povratak nazad nastupa tek onda kada vi4e nemamo izboraB
odnosno kada nema novih neposjeenih 9vorova do kojih vodi neka 3rana iz trenutno3 9vora. Povratak
nazad osi3uran je otpetljavanjem rekurzije.
0oid dfs(int c0or)
{
dfs&pos(cn&c0or*c0or+ = tru;
for (int i = 0; i < n; ++i)
if (matrica&sus(dst0a*c0or+*i+ && .dfs&pos(cn&c0or*i+)
dfs(i);
}
/ada se provjera da li se kretanjem kroz 3raf mo?e doi od jedno3 do dru3o3 9vora ustvari svodi na
pokretanje K-/ pretra3e u jednom 9voru i provjeri da li je prilikom te pretra3e posjeen dru3i 9vor.
)oo! po09ani&c0oro0i(int pr0i&c0or, int drugi&c0or)
{
for (int i = 0; i < n; ++i)
dfs&pos(cn&c0or*i+ = fa!s;
dfs(pr0i&c0or);
return dfs&pos(cn&c0or*drugi&c0or+;
}
#mplementacija ostatka pro3rama koja slijedi sastoji se od u9itavanja podataka iz ulazne datoteke u
specificiranom formatu i nihovo3 tuma9enjaB kori4tenja obja4njenih funkcija i ispisa dobijenih rezultata u
navedenom formatu.
int main()
{
X=AVD u!a9na&datot<a = fopn(")i%am<.in", "r");
X=AVD i9!a9na&datot<a = fopn(")i%am<.out", "#") ;
int m;
fscanf(u!a9na&datot<a, "%d %d", &n, &m);
for (int i = 0; i < m; ++i)
{
c%ar a*3"+, )*3"+;
fscanf(u!a9na&datot<a, "%s %s", a, ));
doda(&granu(numrisi&grad(a), numrisi&grad()));
}
while (tru)
6>
{
c%ar <omanda*,+, a*3"+, )*3"+;
fscanf(u!a9na&datot<a, "%s", <omanda);
if (<omanda*0+ == $@$)
break;
fscanf(u!a9na&datot<a, "%s %s", a, ));
if (<omanda*0+ == $7$)
doda(&granu(numrisi&grad(a), numrisi&grad()));
else if (<omanda*0+ == $8$)
o)risi&granu(numrisi&grad(a), numrisi&grad()));
else if (po09ani&c0oro0i(numrisi&grad(a), numrisi&grad())))
fprintf(i9!a9na&datot<a,
"7ut i9md(u grado0a %s i %s ( pro%odan.6n", a, ));
else
fprintf(i9!a9na&datot<a,
"7ut i9md(u grado0a %s i %s ni( pro%odan.6n", a, ));
}
fc!os(u!a9na&datot<a);
fc!os(i9!a9na&datot<a);
return 0;
}
Za&atak 5>.>. No(enklatura
Te7ina' N
0iolo4ka klasifikacija je na9in na koji biolozi 3rupiraju i kate3oriziraju izumrle i ?ivue vrste i or3anizme.
(oderna klasifikacija vu9e korijene iz sistema Earolusa $innaeusaB koji je 3rupisao vrste prema njihovim
zajedni9kim fizi9kim osobinama. &akon $innaeusaB ove skupine su doraene kako bi se dovele u bli?u vezu
s KarGinovim na9elom o zajedni9kom pretku. Tako seB na primjerB 9ovjek klasificira na sljedei na9in:
)r9ta razre&a
kla9ifika2ije
!azre&
kla9ifika2ije
Earstvo !nimalia
Pleme Ehordata
%lasa (ammalia
ed Primates
Porodica =ominidae
Potporodica =ominini
od =omo
"rsta /apiens
0inomna nomeklatura je naziv za sistem imenovanja vrsti ?ivih bia u kojem se svakoj vrsti daje naziv koji
se sastoji od dva dijela :imena roda i imena vrste;. ije9i ne moraju nu?no biti latinsko3 porijekla ali se daju
imajui u vidu 3ramati9ka pravila latinsko3 jezika. Tako jeB na primjerB naziv za 9ovjeka 3omo sa-iens.
61
%onvencijom je utvreno da je prvo slovo imena roda veliko slovoB dok je prvo slovo imena vrste malo
slovo.
"a4 zadatak je da napravite jednostavni pro3ram za klasifikaciju ?ivih bia. /tablo klasifikacije je mo3ue
jednostavno definisati skupom ureenih parova rije9i na na9in da je prva rije9 vi4i razred klasifikacije a
dru3a rije9 ni?i razred klasifikacije koji pripada prethodnom. TakoB na primjerB djelomi9no definisano stablo
klasifikacije neophodno za klasifikaciju 9ovjeka bi bilo odreeno ureenim parovima rije9i :!nimaliaB
Ehordata;B :EhordataB (ammalia;B :(ammaliaB Primates;B :PrimatesB =ominidae;B :=ominidaeB =ominini;B
:=omininiB =omo;B :=omoB /apiens;.
Ulazni -o&a2i
&a prvoj liniji ulazne datotetke Inomenklatura.inJ nalazi se cio broj & :> ] & 1>>.>>>;. 1 narednih &
linija ove datoteke nalaze se po dvije rije9i odvojene razmakom. /ve rije9i imaju veliko po9etno slovo i
ostala mala slova i ne sastoje se od vi4e od 7> slova. /vaki od ovih redova opisuje jednu vezu u stablu
klasifikacije na na9in kako je to obja4njeno ranije. (o?ete smatrati da e se redovi u daoteteci pojavljivati u
onom redoslijedu koji 3arantuje da e se vi4i razred klasifikacije uvijek pojaviti prije ni?e3. 1 onom slu9aju
kada se odreeni razred klasifikacije pojavi prvi putB mo?ete smatrati da je u pitanju carstvoB odnosno da je
taj razred klasifikacije novi korijen stabla klasifikacije. (o3ue je da bude vi4e od jedno3 korjena.
1 sljedeoj liniji ulazne datoteke nalazi se se broj ( :> ] ( ] 1>.>>>;. 1 narednih ( linija ove datoteke
nalaze se vrste za koje je potrebno izvr4iti klasifikaciju. Prva rije9 je ime rodaB dru3a rije9 je ime vrsteB dok
su preostale rije9i naziv vrste na na4em jeziku. &aziv na na4em jeziku :koji se mo?e sastojati od malih i
velikih slova i razmaka; nee biti du?i od 7> karaktera ukupno. Prva i trea rije9 imaju po9etno veliko slovo
dok su sva ostala slova mala.
Izlazni -o&a2i
1 svaku od ( linija izlazne datoteke Inomenklatura.outJ treba ispisati po jednu od tra?enih klasifikacija u
onom redoslijedu u kojem su navedene u ulaznoj datoteci. Prvo treba ispisati naziv na na4em jezikuB zatim
jednu dvota9ku iza koje slijedi jedan razmakB a zatim treba pobrojati nazive svako3 razreda klasifikacije
kojem pripada ta vrsta po9ev4i od najvi4e3 redom do najni?e3 meusobno razdvojene razmacima. 1koliko
navedena vrsta nije u stablu klasifikacijeB iza dvota9ke i razmaka treba ispisati tekst Iklasifikacija ne postojiJ.
%ri(jer
nomenklatura.in
1&
Plnte Lngio.perm.
Lngio.perm. <5dicot.
<5dicot. Io.id.
Io.id. Io.le.
Io.le. Io.cee
Io.cee Al5.
Al5. Nome.tic
Io.cee P*r5.
P*r5. Womm5ni.
P*r5. O..5rien.i.
C
Al5. dome.tic Yb56
P*r5. comm5ni. <3rop.6 6r5.6
P*r5. 5..5rien.i. Sibir.6 6r5.6
Al5. .ie3er.ii Ni3lj jb56
nomenklatura.out
Yb56: Plnte Lngio.perm. <5dicot. Io.id. Io.le. Io.cee Al5. Nome.tic
65
<3rop.6 6r5.6: Plnte Lngio.perm. <5dicot. Io.id. Io.le. Io.cee P*r5.
Womm5ni.
Sibir.6 6r5.6: Plnte Lngio.perm. <5dicot. Io.id. Io.le. Io.cee P*r5.
O..5rien.i.
Ni3lj jb56: 6l.ifi6cij ne po.toji
!je1enje
/tablo je struktura podataka koja modelira hijerarhijsku strukturu stabla ili drveta. 1 osnovi to je specijalan
slu9aj usmjereno3 3rafa kod koje3 ne postoje ciklusi
5
i svaki 9vor ima ta9no jedno3 roditelja
7
osim jedno3
9vora koji nema roditelja i naziva se korjenom stabla. #z ovo3a se namee na9in za jednostavnu
implementaciju drveta. %oristimo strukturu podataka koja sadr?i informacije koje 9vor po prirodi
problema treba da sadr?iB informaciju o tome koji je nje3ov roditelj ili informaciju da nema roditeljaB
odnosno da je korijen drveta. /ve 9vorove smje4tamo u nizB tako da je informacija o roditelju ustvari indeks
9vora koji je roditelj ili C1 ukoliko 9vor nema roditelja. 1 ovom zadatku svaki 9vor stabla ja ustvari jedan
razred klasifikacijeB pa je po3odno koristiti sljedeu strukturu za predstavljanje jedno3 9vora u memoriji
.tr5ct W3or
%
int roditelj;
chr n2i3!"&#;
);
&apomenimo da postoje implementacije stabla koje se baziraju na upotrebi pokaziva9a i dinami9ke
alokacije memorije. Ove implementacije su efikasnije sa aspekta iskori4tenja memorije onda kada unaprijed
nije poznata veli9ina stabla.
Operacije nad stablom koje e nam biti potrebne za rje4enje zadatka su umetanje novog vora u stablo is-od
odre8enog roditeljaB -retraga vorova stabla -o nazivu i kretanje -o stablu od trenutnog vora do korjena stabla. !l3oritam
koji rje4ava postavljeni zadatak koristei ove operacije nad stablom je sljedei:
1. 19itaj vi4i i ni?i razred klasifikacije sa trenutne linije iz datoteke.
5. Pronai vi4i razred u stablu po imenu.
7. !ko razred nije pronaenB dodaj novi korijen stabla sa nazivom vi4e3 razreda.
8. Kodaj novi 9vor u stablo sa nazivom ni?e3 razreda i 9vorom 3dje je vi4i razred pronaen kao
roditeljom.
.. "rati se nazad na korak 1 sve dok se ne unese & linija iz datoteke.
@. 19itaj ime rodaB ime vrste i naziv na na4em jeziku sa trenutne linije iz datoteke.
2. Pronai 9vor 9iji je naziv jednak nazivu vrste i 9iji roditelj ima naziv koji je jednak nazivu roda.
<. %re9ui se uz stabloB tako da se svaki put prelazi na roditelja trenutno3 9vora sve do korjena stabla
ispisati nazive svih 9vorova koji se na ovaj na9in posjeteB ali u obrnuton redoslijedu od redoslijeda
posjeivanja.
Opi4imo jo4 kako realizovati navedene operacije nad stablom. &iz u kojem su smje4teni 9vorovi kao i
varijabla koja 9uva podatak o tome koliko je trenutno 9vorova u stablu su 3lobalne varijeble zbo3
jednostavnosti implementacije. Obzirom da u datoteci mo?e biti najvi4e 1>>.>>> linija to zna9i da broj
5 1 3rafu ne postoji ciklus ako polazei od proizvoljno3 9vora slijedei bilo koju ivicu proizvoljan broj putaB nije se mo3ue
vratiti ponovo u isti 9vor.
7 &eka postoji usmjerena ivica izmeu 9vora a i 9vora b. Tada se 9vor a naziva ro&iteljo( 9vora bB a 9vor b se naziva &jeteto(
9vora a.
67
razli9itih 9vorova ne mo?e biti vei od 5>>.>>> :u slu9aju kada su sve rije9i razli9ite;.
int tren5tno_c3oro3 $ &;
W3or c3oro3i!'&&&&&#;
Operacija dodavanja 9vora u stablo je jednostavna. &a kraj niza se doda novi 9vor i povea se broj 9vorova
koji su trenutno u stablu. Operacija pretra3e 9vorova u stablu takoer nije komplikovana. +ednostavno se
prolaskom kroz niz tra?i onaj 9vor 9iji je naziv jednak tra?enom nazivu i vra9a se indeks mjesta u nizu 3dje
se on nalazi ili C1 ukoliko takav 9vor nije pronaen. /lijede implementacije ovih funkcija.
//6unckija za dodavanje :vora u stablo sa odreDenim nazivom ispod roditelja
0oid doda(&c0or(int rodit!(, c%ar na9i0*+)
{
c0oro0i*trnutno&c0oro0a+.rodit!( = rodit!(;
/*8tringove !odnosno nizove karaktera# treba dodjeljivati koristeEi
*"unckiju strcp9 a ne operatorom H3H*/
strcpI(c0oro0i*trnutno&c0oro0a+.na9i0, na9i0);
++trnutno&c0oro0a;
}
//6unckija koja vraEa indeks u nizu :vora sa odreDenim nazivom
int pronad(i&c0or(c%ar na9i0*+)
{
for (int i = 0; i < trnutno&c0oro0a; ++i)
/*8tringove !odnosno nizove karaktera# treba porediti koristeEi
*"unckiju strcmp a ne operatorom H33H'*/
if (strcmp(c0oro0i*i+.na9i0, na9i0) == 0)
return i;
//0koliko :vor nije pronaDen vra:amo %1
return '";
}
Operacije kretanja kroz stablo je ne4to kompleksnija. &jena najednostavnija realizacija je rekurzivna. /lijedi
konkretna implementacija sa ispisom tra?ene klasifikacije.
//6unckija koja ispisuje klasi"ikaciju za :vor sa odreDenim indeksom
0oid ispisi&<!asifi<aci(u&id(int id)
{
if (c0oro0i*id+.rodit!( .= '")
ispisi&<!asifi<aci(u&id(c0oro0i*id+.rodit!();
fprintf(i9!a9na&datot<a, " %s", c0oro0i*id+.na9i0);
}
/*6unckija koja ispisuje klasi"ikaciju za :vor sa odreDenim nazivom i
*odreDenim nazivom svog roditelja*/
0oid ispisi&<!asifi<aci(u(c%ar na9i0&rod*+, c%ar na9i0&0rsta*+)
{
//&rvo vrGimo sekvencijalnu pretragu niza traFeEi :vor sa navedenim uslovima
)oo! pronad(n = fa!s;
for (int i = 0; i < trnutno&c0oro0a && .pronad(n; ++i)
if (c0oro0i*i+.rodit!( .= '"
&& strcmp(c0oro0i*i+.na9i0, na9i0&0rsta) == 0
&& strcmp(c0oro0i*c0oro0i*i+.rodit!(+.na9i0, na9i0&rod) == 0)
{
//1ko je :vor pronaDen, vrGimo ispis klasi"ikacije
ispisi&<!asifi<aci(u&id(i);
pronad(n = tru;
68
}
//1ko je :vor nije pronaDen, ispiGemo odgovarajuEu poruku
if (.pronad(n)
fprintf(i9!a9na&datot<a, " <!asifi<aci(a ni( pronad(na.");
fprintf(i9!a9na&datot<a, "6n");
}
Ova funkcija poziva samu sebe u onim slu9ajevima kada postoji roditeljB a zatim ispisuje naziv trenutno3
9vora. Polazei od 9vora koji se nalazi na odreenom mjestu u nizu funkcija e se rekurzivno pozvati nad
nje3ovim roditeljom. Taj novi poziv funkcije e uzrokovati novi rekurzivni pozivB i tako dalje sve do
trenutka kada trenutni 9vor postane korijen stabla odnosno kada vi4e ne postoji roditelj 9vora. Tada e se
ispisati naziv krojena stablaB a zatim uslijed otpetljavanja rekurzije ispisat e se i nazivi ostalih 9vorova koji
su posjeeni i to u suprotnom redoslijedu od ono3 u kojem su posjeeni. Ka je bilo tra?eno da se posti3ne
ispis u redoslijedu koji od3ovara redoslijedu posjete 9vorovaB to bi se posti3lo tako 4to bi se ispis vr4io prije
:eventualno3; rekurzivno3 poziva funckije.
/lijedi i implementacija ostatka pro3rama koji vr4i operacije nad ulaznom i izlaznom datotekom i
implementira ranije opisani al3oritam.
int main()
{
X=AVD u!a9na&datot<a = fopn("nomn<!atura.in", "r");
i9!a9na&datot<a = fopn("nomn<!atura.out", "#");
int n;
fscanf(u!a9na&datot<a, "%d", &n);
for (int i = 0; i < n; ++i)
{
c%ar na9i0&rodit!(*30+, na9i0&di(t*30+;
fscanf(u!a9na&datot<a, "%s %s", na9i0&rodit!(, na9i0&di(t);
int rodit!( = pronad(i&c0or(na9i0&rodit!();
if (rodit!( == '")
{
doda(&c0or('", na9i0&rodit!();
rodit!( = trnutno&c0oro0a ' ";
}
doda(&c0or(rodit!(, na9i0&di(t);
}
int <;
fscanf(u!a9na&datot<a, "%d", &<);
for (int i = 0; i < <; ++i)
{
c%ar na9i0&rod*30+, na9i0&0rsta*30+, na9i0*3"+;
fscanf(u!a9na&datot<a, "%s %s ", na9i0&rod, na9i0&0rsta, na9i0);
/*aziv vrste u ulaznoj datoteci je sa po:etnim malim slovom pa ga
*konvertujemo u odgovarajuEe veliko slovo jer su :vorovi u stablu
*klasi"ikacije svi sa po:etnim velikim slovom*/
na9i0&0rsta*0+ = touppr(na9i0&0rsta*0+);
fgts(na9i0, 3", u!a9na&datot<a);
/*"gets Ee unijeti i karakter HInH koji je oznaka kraja reda a nije
*dio naziva na naGem jeziku*/
na9i0*str!n(na9i0)'"+ = $60$;
fprintf(i9!a9na&datot<a, "%s:", na9i0);
ispisi&<!asifi<aci(u(na9i0&rod, na9i0&0rsta);
}
fc!os(u!a9na&datot<a);
fc!os(i9!a9na&datot<a);
return 0;
6.
}
Za&atak 5>.@. ar(a
Te7ina' I
#a-omena+ Odlukom komisije' na kantonalnom takmienju iz informatike 2012. godine ne9e biti uvr2tena oblast :najkra9i
-ut:. 4-ak' radi kom-letnosti ove zbirke' dajemo i jedan zadatak iz ove oblasti koji je bio dat na kantonalnom takmienju
2007. godine.
-armer posjeduje livadu na kojoj su posaene kru4ke. -arma je dimenzija &A& :1 ] & ] 1>; i na svakom
polju te farme je posaeno stablo kru4ke. -armer je zasadio . razli9itih sorti kru4akaB tako da svaka daje
razli9it broj plodova dnevno. Prva sorta daje 1 plod dnevnoB dru3a 5 ploda dnevnoB trea daje 7 ploda
dnevnoB 9etvrta 8 ploda dnevno i peta sorta daje . plodova dnevno. ,adatak je da napravite put farmera iz
polja naj3ornje lijeve kru4ke do polja najdonje desne kru4ke pri kojem e farmer sakupiti najvei broj
plodova kru4aka. -armer se mo?e kretati samo u smjeru ju3a :dolje; i istoka :desno;.
Ulaz'
Prva linija ulaza sadr?i dimenziju polja &. Ostale linije predstavljaju redove to3 polja koji sadr?e sortu
kru4aka :1C.;.
Izlaz'
1 prvoj liniji treba da sadr?i maksimalan broj skupljenih kru4akaB a u dru3oj put kojim je farmer i4ao da bi
odabrao taj broj kru4aka. 1koliko farmer treba da ide desno oznaka je a ukoliko treba da ide prema dolje
oznaka je K.
6@
Literatura
1. =aris `upiB &lgoritmi i strukture -odatakaB *lektrotehni9ki fakultet 1niverziteta u /arajevuB /arajevo
5>1>.
5. aeljko +uriB ;iskretna matematika za studente te<niki< naukaB *lektrotehni9ki fakultet 1niverziteta u
/arajevuB /arajevo 5>11.
7. aeljko +uriB =e<nike -rogramiranjaB skripta.
62

You might also like