You are on page 1of 3

Zadatak 6.1.

Hanojske kule
Težina: N
Postoji legenda da se negdje u Indiji nalazi hram 1 i u njemu tri velika stuba oko kojih su ovješena 64 velika
zlatna diska. Hinduski svećenici vrijedno premještaju diskove sa jednog stuba na drugi, ispunjavajući
drevno proročanstvo da će smak svijeta nastupiti onda kada svi diskovi budu premješteni sa prvog stuba na
drugi (koristeći treći kao pomoćni). Trik je u tome da je svaki disk različite veličine i da se veći disk nikada
ne smije nalaziti na manjem (jer bi u tom slučaju propao).
Ako pretpostavimo da svećeniku treba jedna sekunda da premjesti disk, kada će nastupiti smak svijeta?
Ovaj broj je poznat i iznosi 264-1 sekundi. Generalno, za n diskova potrebno je 2n-1 poteza da bi se igra
riješila.
Napišite program koji ispisuje sve poteze potrebne za rješavanje igre za zadati broj n diskova.

Ulaz
Prirodan broj n: broj diskova.

Izlaz
U svakom redu opisan je jedan korak u igri.
Tri stuba su označena slovima A, B i C, a diskovi su označeni brojevima 1, 2, ... n tako da je disk 1 najmanji
a disk n najveći.
Jedan potez je opisan brojem koji odgovara disku, nakon čega slijede dva slova koja odgovaraju stubu sa
kojeg je disk premješten i stubu na koji je premješten.
Npr. 8CB znači da je disk 8 prenesen sa stuba C na stub B.

Primjer ulaza:
3

Primjer izlaza:
1AC
2AB
1CB
3AC
1BA
2BC
1AC

Pojašnjenje:
Najprije probajte riješiti ovu interesantnu igru na papiru i to sa nekim manjim brojem diskova, recimo 4.
Ako razmišljate na ispravan način, trebali biste nadoći na opšti princip rješavanja zadatka za n diskova. Taj
princip glasi ovako:
Da bismo pomjerili n diskova sa stuba A na stub C, potrebno je pratiti sljedeće korake (pogledajte sliku 3):
• korak 1: pomjerimo (n-1) diskova sa stuba A na pomoćni stub B, koristeći C kao pomoćni stub;
• korak 2: pošto je sada na dnu stuba A ostao najveći disk, premjestimo ga direktno na stub C;

1 U drugoj varijanti legende hram se nalazi u Hanoju, Vijetnam, pa je pod tim imenom zadatak poznatiji.

54
• korak 3: sada pomjerimo (n-1) diskova sa stuba B na stub C koristeći stub A kao pomoćni.
Ovo rješenje problema je rekurzivno, odnosno, rješenje problema za n smo opisali preko rješenja za n-1 koje
smo iskoristili u koracima 1 i 3.
Ovaj opis nam omogućuje da napišemo funkciju prebaci koja prebacuje n diskova sa stuba x na stub y
koristeći stub z kao pomoćni. U slučaju da je broj diskova n=1, treba samo ispisati na ekranu slova x i y. Na
ovaj način smo osigurali da se ova rekurzivna funkcija terminira.
Programski jezik C:
void prebaci(int n, char sa_stuba, char na_stub, char pomocni_stub)
{
/* Prebacujemo (n-1) diskova sa polaznog stuba na pomocni stub, koristeci
odredisni stub kao pomocni.
Ako je n=1 ovaj korak ne moramo raditi. */
if (n>1) prebaci(n-1, sa_stuba, pomocni_stub, na_stub);

/* Najveci disk n je ostao na dnu, njega mozemo direktno prebaciti. */


printf(“%d%c%c\n”, n, sa_stuba, na_stub);

/* Sada mozemo prebaciti (n-1) diskova sa pomocnog stuba na odredisni */


if (n>1) prebaci(n-1, pomocni_stub, na_stub, sa_stuba);
}

Pascal:
procedure prebaci(n : integer, sa_stuba, na_stub, pomocni_stub : char);
begin
{ Prebacujemo (n-1) diskova sa polaznog stuba na pomocni stub, koristeci
odredisni stub kao pomocni.
Ako je n=1 ovaj korak ne moramo raditi. }
if n>1 then prebaci(n-1, sa_stuba, pomocni_stub, na_stub);

{ Najveci disk n je ostao na dnu, njega mozemo direktno prebaciti. }


writeln(n, sa_stuba, na_stub);

{ Sada mozemo prebaciti (n-1) diskova sa pomocnog stuba na odredisni }


if n>1 prebaci(n-1, pomocni_stub, na_stub, sa_stuba);
end;

Preostaje još da napišemo glavni program koji poziva ovu funkciju.


Programski kod (C):
#include <stdio.h>

/* Funkcija prebaci obavlja sav bitan posao u ovom programu */


void prebaci(int n, char sa_stuba, char na_stub, char pomocni_stub)
{
/* Prebacujemo (n-1) diskova sa polaznog stuba na pomocni stub, koristeci
odredisni stub kao pomocni.
Ako je n=1 ovaj korak ne moramo raditi. */
if (n>1) prebaci(n-1, sa_stuba, pomocni_stub, na_stub);

/* Najveci disk n je ostao na dnu, njega mozemo direktno prebaciti. */


printf("%d%c%c\n", n, sa_stuba, na_stub);

55
/* Sada mozemo prebaciti (n-1) diskova sa pomocnog stuba na odredisni */
if (n>1) prebaci(n-1, pomocni_stub, na_stub, sa_stuba);
}

int main()
{
int n;
scanf("%d", &n);
prebaci(n, 'A', 'C', 'B');
return 0;
}

Programski kod (Pascal):


program Hanojske_kule;
var
broj_diskova : integer;

{ Procedura prebaci obavlja sav bitan posao u ovom programu }


procedure prebaci(n : integer, sa_stuba, na_stub, pomocni_stub : char);
begin
{ Prebacujemo (n-1) diskova sa polaznog stuba na pomocni stub, koristeci
odredisni stub kao pomocni.
Ako je n=1 ovaj korak ne moramo raditi. }
if n>1 then prebaci(n-1, sa_stuba, pomocni_stub, na_stub);

{ Najveci disk n je ostao na dnu, njega mozemo direktno prebaciti. }


writeln(n, sa_stuba, na_stub);

{ Sada mozemo prebaciti (n-1) diskova sa pomocnog stuba na odredisni }


if n>1 prebaci(n-1, pomocni_stub, na_stub, sa_stuba);
end;

begin
readln(broj_diskova);
prebaci(broj_diskova, 'A', 'C', 'B');
end.

Zadatak 6.2. Flood fill


Težina: N
Ovaj zadatak je bio na Kantonalnom takmičenju iz informatike 2010. godine
Bitmapa je tabela (matrica) sastavljena od nula i jedinica, koja može predstavljati recimo neku crno-bijelu
sliku. Napravite program koji učitava kvadratnu bitmapu (dimenzija NxN) i koordinate jedne tačke u toj
bitmapi.
Ako je na datim koordinatama vrijednost 1 program ne radi ništa. Ali ako se tu nalazi 0, program treba
zamijeniti vrijednost jedinicom, a zatim zamijeniti i sve susjedne tačke sve dok se ne dođe do ruba matrice
ili do znaka 1. Drugim riječima, program treba da se ponaša kao “flood fill” (punjenje) u grafičkim
aplikacijama: treba da popuni dio matrice sastavljen od nula omeđen rubovima matrice i jedinicama.
Prilikom popunjavanja kroz se matricu kreće samo u smjerovima gore, dolje, lijevo i desno, ali ne i po
dijagonali.

56

You might also like