You are on page 1of 2

Strukture podataka i algoritmi

Popravni drugi kolokvij - 5. ožujka 2021. godine

ZADATAK 4.
(8 bodova)

Rješenje. (3 + 5 bodova)
(a) Pohlepni pristup za Marka:
– Marko u svakom potezu, kada bira nepraznu vrećicu s početka ili s kraja niza, odabere onu u
kojoj se nalazi više bombona.

Primjer kada taj pristup ne osigurava Marku pobjedu:


– promotrimo upravo niz iz zadatka:
Br. poteza Povučen potez Skupio Marko Skupio Mirko Preostali dio niza
0 0 4 6 2 3
1. Marko bira 1. vrećicu 4 0 6 2 3
2. Mirko bira 2. vrećicu 4 6 2 3
3. Marko bira 4. vrećicu 4+3=7 6 2
4. Mirko bira 3. vrećicu 7 6+2=8
⇒ Marko nije pobijedio pohlepnim pristupom u ovoj igri :(

(b) (Podsjetnik: broj n i polje niz[] zadani su globalno.)

Prvo jedna pomoćna funkcija koja prima: dva indeksa (početni i završni za neprazni dio niza niz[]),
te koliko je do sad skupio Marko, a koliko Mirko. Uvijek se gleda tako da je na redu Marko (koji ima
dvije opcije: birati prvi ili zadnji preostali), a zatim (ako može) je odmah i Mirko na redu. Rekurzivni
pozivi: gleda se može li pobijediti Marko nakon odredenog mogućeg poteza (birao je prvu nepraznu ili
zadnju nepraznu vrećicu).

int pobjedaMarka(int pocetni, int zavrsni, int skupioMarko, int skupioMirko) {


if(pocetni > zavrsni) // nema mogućnosti za potez => pogledaj koliko su skupili
return (skupioMarko > skupioMirko) ? 1 : -1;
if(pocetni == zavrsni) // još samo jedna neprazna vrećica - to Marko uzme
return (skupioMarko + niz[pocetni] > skupioMirko) ? 1 : -1;
// inače (pocetni < zavrsni):
// Marko može uzeti niz[pocetni] ili niz[zavrsni] bombona, a onda
// Mirko odmah uzme svoje bombone s početka preostalog nepraznog dijela niza
skupioMarko += niz[pocetni];
pocetni++; //jer uzeli sve bombone iz vrećice s početka
skupioMirko += niz[pocetni];
pocetni++;
if(pobjedaMarka(pocetni, zavrsni, skupioMarko, skupioMirko) == 1)
return 1; // ako tako Marko može pobijediti

1
// inače, Marko treba probati tako da uzme zadnji
// no prvo vratimo da stvari budu kao prije neuspjelog poteza Marka
--pocetni; skupioMirko -= niz[pocetni];
--pocetni; skupioMarko -= niz[pocetni];
// dakle, sad Marko pokuša uzeti s kraja (a Mirko naravno s početka)
skupioMarko += niz[zavrsni];
--zavrsni; // jer uzeli sve bombone iz posljednje neprazne vrećice
skupioMirko += niz[pocetni]; // Mirko i dalje uzima s početka
pocetni++;
if(pobjedaMarka(pocetni, zavrsni, skupioMarko, skupioMirko) == 1)
return 1; // ako tako Marko može pobijediti
return -1; // jer Marko ni na jedan način ne može pobijediti
}

Sad to pozovemo s cijelim nizom na početku (od indeksa 1 do indeksa n), te su Marko i Mirko početno
skupili po 0 bombona.

int pobijediMarko(){
int skupioMarko = 0, skupioMirko = 0;
return pobjedaMarka(1,n,skupioMarko,skupioMirko);
}

(Komentar: U gornjem tijelu funkcije pobijediMarko() može i samo ovo: return pobjedaMarka(1,n,0,0);
Gore je onako napisano kako bi bilo jasnije što se dogada :)

You might also like