Sunteți pe pagina 1din 46

MINISTERUL EDUCAIEI

AL REPUBLICII MOLDOVA

MHCTEPCTBO IIPOCBEEH
PECJIK MO





















Olimpiada Republican la Informatic
Ediia 2011


























Chiinu 2011
2


Olimpiada Republican la Informatic. Ediia 2011.
Lucrarea conine problemele propuse la Olimpiada Republican la Informatic a
elevilor, ediia 2011. Pentru fiecare problem sunt descrise algoritmul i soluia respectiv n
limbajul de programare PASCAL.
Materialele Olimpiadei pot fi de un real folos la studierea Informaticii att elevilor, ct
i profesorilor de Informatic.





La elaborarea ediiei au contribuit:

Ion Bolun, profesor universitar, Academia de Studii Economice a Moldovei
Anatol Gremalschi, profesor universitar, Institutul de Politici Publice
Iurie Mocanu, ef de direcie, Ministerul Educaiei
Viorel Afteni, consultant superior, Ministerul Educaiei
Nicolai Falico, lector superior, Universitatea Tehnica a Moldovei
Dumitru Codreanu, doctorand, Universitatea Bucureti
Dumitru Ciubati, director, TenerLab SRL
Bogdna Denis, asistent, Universitatea Tehnic, Iai
Constantin Dolghier, inginer, ICS Micrologic Design Automation SRL

3




Cuprins

Cuvnt de salut ............................................................................................................................ 4
Clasele 79 ................................................................................................................................... 6
Anagrame ............................................................................................................................................ 7
Bilete ................................................................................................................................................. 10
Hrubele de la Cricova ........................................................................................................................ 12
Jocul .................................................................................................................................................. 16
Ptratul numrului binar ................................................................................................................... 18
Turnuri ............................................................................................................................................... 20
Punctajul competitorilor ................................................................................................................... 23
Complexitatea problemelor .............................................................................................................. 23
Clasele 1012 ............................................................................................................................. 24
Comoara ............................................................................................................................................ 25
Bilete ................................................................................................................................................. 29
Hrubele de la Cricova ........................................................................................................................ 31
Jocul .................................................................................................................................................. 35
Rdcina numrului binar ................................................................................................................. 38
Turnuri ............................................................................................................................................... 41
Punctajul competitorilor ................................................................................................................... 44
Complexitatea problemelor .............................................................................................................. 44
Lista premianilor ....................................................................................................................... 45

4
Cuvnt de salut

Dragi elevi i stimai profesori,
care v druii acestui domeniu de vrf
al tiinei i tehnologiei moderne pe nume
Informatica,
Orice competiie este o experien pentru participani. Cu ct mai nalt este rating-
ul competiiei, cu att mai bogat i fructuoas este experiena obinut.
Olimpiada Republican la Informatic ntrunete cei mai buni elevi n domeniu
din republic i are ca scop att ncurajarea i susinerea interesului elevilor ctre
informatic, ct i evaluarea gradului de pregtire a lor n domeniu, elucidarea
lacunelor n instruire i definirea unor ci de mbuntire continu a acesteia. Ea
permite, de asemenea, stabilirea de noi cunotine ntre elevi i profesori, dar i
reevaluarea valorilor. Rezultatele acesteia sunt folosite la selectarea candidailor
pentru echipa de elevi ce vor participa la competiii internaionale n informatic.
Printre olimpiadele republicane ale elevilor, cea la Informatic are, totui, un rol
aparte, determinat de rolul deosebit al informaticii n societatea modern.
Informaia a devenit, n ultimele decenii, un neofactor de producie mult mai
important, deseori, dect materiile prime i energia: Cine deine informaia
stpnete situaia. Informatica, la rndul su, faciliteaz considerabil
valorificarea eficient a informaiilor deja cunoscute i, de asemenea, procesele de
obinere a unor noi informaii.
Calculatoarele cea mai complex oper a raiunii umane, fortific considerabil,
uneori greu de imaginat, capacitile intelectuale umane. Astfel, n timpul
parcurgerii de ctre o raz de lumin n vid a distanei de un singur milimetru,
supercalculatorul Tianhe-1A al Universitii NUDT (China) execut cca. 15000
instruciuni. Efectul aplicrii unor asemenea capaciti de procesare a informaiei
este considerabil. Se rezolv probleme care era imposibil de rezolvat, crete
semnificativ productivitatea i se mbuntete considerabil calitatea muncii.
Avantajele folosirii mijloacelor informatice au condus la implementarea lor tot
mai larg. Sectorul informaticii a devenit un sector strategic de susinere a creterii
economice i de prosperare a societii. Cercetri recente arat c pn la 30-50%
din creterea economic a unei ri se datoreaz sectorului Tehnologiilor
informaionale i de telecomunicaii.
Anume impactul benefic considerabil al informaticii asupra societii a condus la
concluzia despre evoluia spre societatea informaional-societatea cunoaterii. Pai
concrei n edificarea Societii informaionale sunt ntreprini i n Republica
Moldova. De exemplu, agenii economici care activeaz n domeniul TI se bucur
de anumite faciliti fiscale. Solicitarea informaticienilor pe piaa muncii este att
de nalt c chiar i n perioade de criz economic n multe ri se simte un
deficit de specialiti n domeniu.
Dac tinerii sunt viitorul societii, atunci tinerilor informaticieni le revine rolul de
avangard n edificarea societii viitorului societii informaionale. Ne
mndrim cu acest rol deosebit de important al informaticii n societate, dar i
responsabilitatea ce ne revine este pe msur. Pentru a face fa sarcinilor
5
respective, trebuie s ne pregtim bine din timp, orientat i sistematic. Conform
raportului grupului Bangemann ctre Consiliul Europei: rile, care nu vor
ntreprinde msuri radicale orientate la edificarea intens a societii
informaionale, vor rmne economic n urm pentru totdeauna. Nu trebuie s ne
liniteasc, n aceast privin, legea vaselor comunicante n era Internet-ului.
Iar n avangard ntotdeauna se afl cei mai buni. De ei depinde, n primul rn,
bunstarea zilei de mine pentru toi. Cu alte cuvinte, mine voi, tinerii
informaticieni de azi, vei fi aceea de care va depinde substanial prosperarea
acestei palme de pmnt Republica Moldova. Sarcinile sunt diverse i fiecare
din noi la fel. Astzi unul din noi gsete o soluie original, iar mine un altul i
n rezultat avem de ctigat cu toii.
Lumea aparine celor capabili i energici. n primii cinci, din cei mai bogai
oameni ai lumii la ora actual, trei sunt din domeniul informaticii i
telecomunicaiilor: pe primul loc este Carlos Slim telecomunicaii, pe al doilea
William (Bill) Gates (fondator al companiei Microsoft) informatic i pe al
cincilea - Larry Ellison (fondator al companiei Oracle) informatic. Exist i
multe alte exemple demne de urmat.
Din 2007 la 17 mai se srbtorete Ziua Mondial a Telecomunicaiilor i
Societii Informaionale. Felicitri clduroase tuturor cu aceast srbtoare este
srbtoarea noastr a informaticienilor, i sperm ca cele dou zile de competiii
n informatic ce urmeaz v vor mobiliza la noi realizri n domeniu.
n numele Consiliului Olimpic la Informatic,

Ion Bolun
Profesor universitar, ASEM


6

Clasele 79



Denumirea
problemei
Numrul de
puncte alocat
problemei
Denumirea
fiierului surs
Denumirea
fiierului de
intrare
Denumirea
fiierului de
ieire
Anagrame 100
ANA.PAS
ANA.C
ANA.CPP
ANA.IN ANA.OUT
Bilete 100
BILETE.PAS
BILETE.C
BILETE.CPP
BILETE.IN BILETE.OUT
Hrubele de la
Cricova
100
HRUBE.PAS
HRUBE.C
HRUBE.CPP
HRUBE.IN HRUBE.OUT
Jocul 100
JOCUL.PAS
JOCUL.C
JOCUL.CPP
JOCUL.IN JOCUL.OUT
Ptratul
numrului binar
100
PATRAT.PAS
PATRAT.C
PATRAT.CPP
PATRAT.IN PATRAT.OUT
Turnuri 100
TURNURI.PAS
TURNURI.C
TURNURI.CPP
TURNURI.IN TURNURI.OUT
Total 600 - - -


7
Anagrame

Se consider mulimea irurilor de caractere } ..., , , {
2 1 n
s s s S = . Prin definiie, muimea
S este o mulime fra anagrame, dac n ea nu exist nici o pereche } , {
j i
s s de iruri, unul din
care poate fi obinut din cellat prin operaii de anagramare.
Amintim, c anagramarea este un procedeu literar, ce const n schimbarea ordinii
literelor ntr-un cuvnt. De exemplu, n antichitate, numele regelui Ptolemaios, prin
anagramare, a fost transformat n Apomelitos (care provine din miere). Cuvintele obinute
prin anagramare se numesc anagrame.
Sarcin. Elaborai un program care, cunoscnd mulimea } ..., , , {
2 1 n
s s s S = , calculeaz
numrul m de iruri din cea mai mare submulime fr anagrame a mulimii S.
Date de intrare. Prima linie a fiierului text ANA.IN conine numrul ntreg n. Fiecare
din urmtoarele n linii ale fiierului de intrare conine cte un ir de caractere. Linia 1 + i a
fiierului de intrare conine irul s
i
.
Date de ieire. Fiierului text ANA.OUT va conine pe o singur linie numrul ntreg m.
Exemplu.
ANA.IN ANA.OUT
6
AnaAreMere
MereAreAna
IonAreMere
AreIonMere
SiCeDacaIonAreMere
IonAreMulteMere
4


Restricii. 000 10 1 s s n . irurile de caractere din mulimea S sunt formate din literele
mari i mici ale alfabetului latin. Fiecare ir conine cel mult 250 de caractere. Timpul de
execuie nu va depi 0,5 secunde. Programul va folosi cel mult 32 Megaoctei de memorie
operativ. Fiierul surs va avea denumirea ANA.PAS, ANA.C sau ANA.CPP.


Rezolvare

Mai nti vom ncerca sa rezolvm aceast problem prin metoda forei brute sau, prin
alte cuvinte, prin metoda trierii.
Vom elabora n acest scop urmtoarele subprograme:
Function SuntAnagrame(A, B : string) : boolean funcia returneaz
TRUE dac irurile de caractere A i B sunt anagrame i FALSE n caz contrar. Valorile acestei
funcii pot fi calculate, verificnd dac frecvenele de apariie a fiecrui caracter n ambele
iruri sunt egale.
Function EsteFaraAnagrame(C : set of string) : boolean funcia
repurneaz TRUE dac mulimea C de iruri de caractere este fr anagrame i FALSE n caz
contrar. Valorile acestei funcii pot fi calculate formnd toate perechile posibile de iruri
) , ( B A , C Ae i C Be , apelnd pentru fecare pereche funcia EsteFaraAnagrame.
1. Un posibil algoritm, bazat pe metoda trierii, va avea urmtoarea structur:
2. Formm o submulime nevid C a mulimii de iruri S.
3. Cu agutorul apelului EsteFaraAnagrame(C) verificm dac submulimea
8
respectiv este fr anagrame. Dac valoarea returnat de funcia
EsteFaraAnagrame este TRUE, memorm numrul de elemente ale mulimii C.
4. n continuare formm o nou submulime C a mulimii S .a.m.d. pn vor fi
examinate toate submulimile posibile.
ntruct numrul de submulimi nevide ale mulimii S este
n
2 , complexitatea temporal
a unui astfel de algoritm va fi ) 2 (
n
O . Evident, pentru 20 > n , programul bazat pe metoda
trierii nu se va ncadra n timpul indicat n restriciile problemei.
Prin urmare, competitorii care au mers pe aceast cale, au avut anse s obin puncte
doar n cazul testelor cu valori mici ale lui n.
Complexitatea temporal a algoritmului poate fi ns redus, dac, n loc de trierea
tuturor submulimilor lui S, vom construi doar submulimea ce conine cel mai mare numr de
cuvinte fr anagrame. O astfel de mulime poate fi construit dup cum urmeaz:
1. Sortam caracterele din fiecare ir al mulimii S n ordine alfabetic. Evident, dup
sortare, irurile care sunt anagrame devin egale ntre ele.
2. Sortm irurile din mulimea S n ordine lexicografic. Dup sortare, n mulimea
ordonat S, irurile egale vor ocupa poziii consecutive.
3. Excludem din S submulimile de iruri ce coincid, lsnd n S doar cte un ir din
submulimile excluse. Evident, excluderea propriu-zis nici nu este necesara, este
suficient s numrm doar irurile ce difer.
Complexitatea temporal a unui astfel de algoritm depinde de metodele de sortare
utilizate. n cazul metodei bulelor, complexitatea sortrii caracterelor din fiecare ir al
mulimii S este ) (
2
nm O , unde m este numrul maximal de caractere ntr-un ir, iar
complexitatea sortrii irurilor este ) (
2
n O . ntruct cu creterea lui m i n valorile ) (
2
nm O
cresc cu mult mai ncet dect valorile ) 2 (
n
O , ansele c vor trece mai multe teste cresc.
Totui, pentru 250 = m i 000 10 = n , valoarea
8 2
10 25 , 6 ~ nm este prea aproape de
viteza de procesare a calculatoarelor moderne.
Prin urmare, pentru a fi siguri c programul se va ncadra n restriciile temporale,
trebuie utilizat o metod rapid de sortare, de exemplu, QuickSort, MergeSort sau HeapSort,
care sunt descrise n literatur. Complexitatea unor astfel de metode de sortare este
) log ( n n O , fapt ce ne garanteaz respectarea restriciilor problemei.
n programul ce urmeaz, irurile de caractere sunt stocate n memoria dinamic, iar
sortarea lor se face prin metoda QuickSort.

Program Anagrame;

type TSiruri = Array[1..10000] of String;

var n : Integer;
siruri : TSiruri;
i, count : Integer;
f, g : Text;

procedure Swap(var a, b : string);
var temp : string;
begin
temp := a;
a := b;
b := temp;
end;

procedure Sort(var s : String);
{ sorteaza caracterele unui sir de caracter prin numarare }
9
var i, k : Integer;
c : Char;
l : integer;
hist: Array[char] of ShortInt;
begin
{ numara caracterele }
FillChar(hist, sizeof(hist), 0);
for i := 1 to Length(s) do Inc(hist[s[i]]);
l := 1;
for c := char(0) to char(250) do
for k := 1 to hist[c] do
begin s[l]:=c; Inc(l); end;
end; { Sort }

function Partition(var v : TSiruri; left, right : Integer) : Integer;
{ partitionarea pentru procedeul QuickSort:
Aduce elementele mai mici ca valoarea pivotului pe pozitiile 1..p, si
returneaza acea valoare p }
var pv : String;
p, i : Integer;
begin
pv := v[right];
p := left;
for i := left to right - 1 do
if v[i] < pv then begin
Swap(v[i], v[p]);
Inc(p);
end;
Swap(v[p], v[right]);
Partition := p;
end; { Partition }

procedure QuickSort(var v : TSiruri; left, right : integer);
var pivotIndex : Integer;
begin
if left >= right then exit;
pivotIndex := Partition(v, left, right);
QuickSort(v, left, pivotIndex -1);
QuickSort(v, pivotIndex + 1, right);
end; { QuickSort }

begin
{ Citeste Datele }
Assign(f, 'ana.in');
Reset(f);
Readln(f, n);
for i := 1 to n do Readln(f, siruri[i]);
Close(f);
{ sorteaza caracterele sirurilor }
for i := 1 to n do Sort(Siruri[i]);
{ sorteaza lexicografic sirurile de caractere }
QuickSort(Siruri, 1, n);
{ numara cate sunt diferite }
count := 1;
for i:= 2 to n do
if Siruri[i] <> Siruri[i-1] then Inc(count);
{ Scrie raspunsul }
Assign(g, 'ana.out');
Rewrite(g);
Writeln(g, count);
Close(g);
end.

10
Bilete

Biletele din transportul public din marele orae sunt numerotate. De
obicei, un numr de bilet este format din ase cifre zecimale.
Unii elevi i studeni consider c n cazul n care suma primelor trei cifre
din componena numrului de bilet este egal cu suma ultimelor trei cifre,
biletul respectiv aduce noroc sau, prin alte cuvinte, este un bilet fericit.
De exemplu, biletul cu numrul 032050 este fericit, iar cel cu numrul
283357 nu.
Sarcin. Elaborai un program care, cunoscnd numrul de bilet, determin dac biletul
respectiv este fericit.
Date de intrare. Prima linie a fiierului text BILETE.IN conine numrul ntreg n
numrul total de bilete supuse examinrii. Fiecare din urmtoarele n linii ale fiierului de
intrare conine cte un numr de bilet, format din ase cifre zecimale.
Date de ieire. Prima linie a fiierului text BILETE.OUT va conine numrul ntreg n.
Fiecare din urmtoarele n linii ale fiierului de ieire va conine cuvntul DA dac biletul din
linia respectiv a fiierului de intrare este fericit din i NU n caz contrar.
Exemplu.
BILETE.IN BILETE.OUT
3
032050
283375
121301
3
DA
NU
DA

Restricii. 1000 1 s s n . Timpul de execuie nu va depi 0,5 secunde. Programul va
folosi cel mult 32 Megaoctei de memorie operativ. Fiierul surs va avea denumirea
BILETE.PAS, BILETE.C sau BILETE.CPP.


Rezolvare

Vom nota prin c
1
, c
2
, c
3
, c
4
, c
5
, c
6
cifrele numrului de bilet. De exemplu, n cazul
numrului de bilet 360710 avem 3
1
= c , 6
2
= c , 0
3
= c , 7
4
= c , 1
5
= c , 0
6
= c .
Cifrele numrului de bilet pot fi calculate n ordinea c
6
, c
5
, c
4
, c
3
, c
2
, c
1
prin mpriri
succesive a numrului de bilet i a cturilor obinute la baza 10 a sistemului zecimal de
numeraie, reinnd resturile mpririlor.
Evident, un bilet este fericit atunci cnd ). ( ) (
6 5 4 3 2 1
c c c c c c + + = + +

Program Bilete;
{ Clasele 07-09 }
var Intrare, Iesire : text;
n : longint; { numarul de bilete in fisierul de intrare }
Numar : longint; { numarul de bilet }
c1, c2, c3, c4, c5, c6 : integer; { cifrele numarului de bilet }
i : longint;
begin
assign(Intrare, 'BILETE.IN');
reset(Intrare);
assign(Iesire, 'BILETE.OUT');
rewrite(Iesire);
11
readln(Intrare, n);
writeln(Iesire, n);
for i:=1 to n do
begin
readln(Intrare, Numar);
c6:=Numar mod 10; Numar:=Numar div 10;
c5:=Numar mod 10; Numar:=Numar div 10;
c4:=Numar mod 10; Numar:=Numar div 10;
c3:=Numar mod 10; Numar:=Numar div 10;
c2:=Numar mod 10; Numar:=Numar div 10;
c1:=Numar mod 10;
if (c1+c2+c3)=(c4+c5+c6) then writeln(Iesire, 'DA')
else writeln(Iesire, 'NU');
end; { for }
close(Intrare);
close(Iesire);
end.
12
Hrubele de la Cricova

Dup o vizit la renumitele hrube
*
de la Cricova, un informatician a construit un robot
care lucreaz ntr-un cmp divizat n ptrele (vezi desenul). Ptrelele haurate reprezint
obstacolele, iar cele nehaurate spaiile libere.
Ptrelele de pe perimetrul planului, cu excepia
celor de intrare sau ieire, snt haurate prin definiie.
Robotul poate executa doar instruciunile SUS,
JOS, DREAPTA, STANGA, conform crora el se
deplaseaz n unul din ptrele vecine. Dac n
ptratul vecin este un obstacol, de exemplu, un
perete sau un butoi, are loc un accident i robotul
iese din funciune.
n form numeric planul hrubelor este redat
prin tabloul A cu n linii i m coloane. Elementele
] , [ j i A ale acestui tablou au urmtoarea semnificaie: 0 spaiu liber; 1 obstacol; 2
intrarea n hrube; 3 ieirea din hrube. Iniial, robotul se afl n ptrelul pentru care
2 ] , [ = j i A .
Sarcin. Elaborai un program, care, cunoscnd planul hrubelor, deplaseaz robotul prin
ncperile subterane, de la intrarea n hrube la ieire. Colecia de vinuri fiind foarte bogat, nu
se cere vizitarea obligatorie a tuturor ncperilor subterane.
Date de intrare. Fiierul text HRUBE.IN conine pe prima linie numerele ntregi n, m
separate prin spaiu. Pe fiecare din urmtoarele n linii se conin cte m numere ntregi ] , [ j i A ,
separate prin spaiu.
Date de ieire. Fiierul text HRUBE.OUT va conine pe fiecare linie cte una din
instruciunile SUS, JOS, DREAPTA, STANGA, scrise n ordinea executrii lor de ctre robot.
Dac problema admite mai multe soluii, n fiierul de ieire se va scrie doar una, oricare din
ele.

Exemplu:

HRUBE.IN HRUBE.OUT
7 9
1 1 1 1 1 1 1 1 1
1 0 0 1 0 0 0 0 1
1 0 1 0 0 1 0 1 1
1 0 0 0 1 0 0 0 1
1 0 1 0 1 0 1 0 1
1 0 0 0 0 0 1 0 1
1 2 1 1 1 1 1 3 1
SUS
DREAPTA
DREAPTA
DREAPTA
DREAPTA
SUS
SUS
DREAPTA
DREAPTA
JOS
JOS
JOS


Restricii. 100 , 5 s s m n . Timpul de execuie nu va depi 0,5 secunde. Fiierul surs
se va numi HRUBE.PAS, HRUBE.C sau HRUBE.CPP.

*
Hrub ncpere sau galerie subteran care servete la depozitarea produselor alimentare. n hrubele de la
Cricova pe parcursul a mai multor decenii sunt depozitate cele mai bune vinuri din Republica Moldova.
13

Rezolvare

Vom denumi perete orice succesiune de laturi adiacente de ptrele, fiecare din care
separ un ptrel nehaurat (spaiu liber) de unul haurat (obstacol). Conform condiiilor
problemei, ntotdeauna exist un perete, care se ncepe la intrare i se termin la ieire.
Prin urmare, pentru a gsi ieirea, este suficient s deplasm robotul de-a lungul unuia i
aceluiai perete, de exemplu, celuia din mna dreapt a robotului. Evident, n procesul
deplasrii, robotul nu trebuie s se ndeprteze de peretele respectiv sau, prin alte cuvinte, el
trebuie s in permanent mna dreapt pe perete.
Pentru a simula procesul de deplasare a robotului, introducem n studiu urmtoarele
variabile:
y x, coordonatele curente ale robotului;
D direcia n care este orientat robotul (vom nota aceste direcii prin NORD, SUD,
EST, VEST);
C instruciunea pe care trebuie s o execute robotul.
Coordonatele urmtorului ptrel liber n care trebuie s treac robotul se determin,
analiznd direcia n care el este orientat i starea ptrelelor adiacente.
De exemplu, presupunem c robotul este orientat n direcia NORD = D .
Analizm mai nti ptrelul ) 1 , ( + y x din mna dreapt a robotului. Dac acest
ptrel este nehaurat, robotul trece n el i i schimb orientarea: DREAPTA := C ;
1 : + = y y ; EST := D .
Dac ptrelul din mna dreapt a robotului este haurat, analizm
ptrelul ) , 1 ( y x din faa robotului. Dac acest ptrel este nehaurat, robotul trece n el
fr ai schimba orientarea: SUS := C , 1 : = x x .
Daca ambele ptrele, i cel din mna dreapt, i cel din faa robotului sunt
haurate, analizm ptrelul ) 1 , ( y x din mna stng a robotului. Dac acest ptrel
este nehaurat, robotul trece n el i ii schimb orientarea: STANGA := C ; 1 : = y y ;
VEST := D .
n sfrit, dac ptrelele din mna dreapt, din fa i din mna stng a
robotului sunt haurate, robotul doar se ntoarce napoi, cu faa ctre ptrelul din care a
venit: SUD := D .
ntr-un mod similar se analizeaz i cazurile n care robotul este orientat spre SUD, EST
sau VEST.

Program Hrube;
{ Clasele 07-09 }
const nmax=100; mmax=100;
type Directie = (NORD, SUD, EST, VEST);

var A : array[1..nmax, 1..mmax] of integer;
n, m : integer; { dimensiunile campului }
p, q : integer; { coordonatele intrarii }
r, s : integer; { coordonatele iesirii }
DI : Directie; { orientarea initiala a robotului }
Iesire : text;

procedure Citeste;
{ Citeste datele de intrare }
var i, j : integer;
Intrare : text;
begin
assign(Intrare, 'HRUBE.IN');
14
reset(Intrare);
readln(Intrare, n, m);
for i:=1 to n do
begin
for j:=1 to m do
begin
read(Intrare, A[i, j]);
if A[i, j]=2 then begin p:=i; q:=j; A[i, j]:=0; end;
if A[i, j]=3 then begin r:=i; s:=j; A[i, j]:=0; end;
end; { for }
readln(Intrare);
end; { for }
close(Intrare);
if q=1 then DI:=EST;
if q=m then DI:=VEST;
if p=1 then DI:=SUD;
if p=n then DI:=NORD;
end; { Citeste }

procedure Mergi(x, y : integer; D : Directie);
label 1;
begin
repeat
if D=NORD then
begin
if A[x, y+1]=0 then
begin writeln(Iesire, 'DREAPTA'); y:=y+1; D:=EST; goto 1; end;
if A[x-1, y]=0 then
begin writeln(Iesire, 'SUS'); x:=x-1; D:=NORD; goto 1; end;
if A[x, y-1]=0 then
begin writeln(Iesire, 'STANGA'); y:=y-1; D:=VEST; goto 1; end;
D:=SUD; goto 1;
end; { Nord }
if D=SUD then
begin
if A[x, y-1]=0 then
begin writeln(Iesire, 'STANGA'); y:=y-1; D:=VEST; goto 1; end;
if A[x+1, y]=0 then
begin writeln(Iesire, 'JOS'); x:=x+1; D:=SUD; goto 1; end;
if A[x, y+1]=0 then
begin writeln(Iesire, 'DREAPTA'); y:=y+1; D:=EST; goto 1; end;
D:=NORD; goto 1;
end; { SUD }
if D=EST then
begin
if A[x+1, y]=0 then
begin writeln(Iesire, 'JOS'); x:=x+1; D:=SUD; goto 1; end;
if A[x, y+1]=0 then
begin writeln(Iesire, 'DREAPTA'); y:=y+1; D:=EST; goto 1; end;
if A[x-1, y]=0 then
begin writeln(Iesire, 'SUS'); x:=x-1; D:=NORD; goto 1; end;
D:=VEST; goto 1;
end; { EST }
if D=VEST then
begin
if A[x-1, y]=0 then
begin writeln(Iesire, 'SUS'); x:=x-1; D:=NORD; goto 1; end;
if A[x, y-1]=0 then
begin writeln(Iesire, 'STANGA'); y:=y-1; D:=VEST; goto 1; end;
if A[x+1, y]=0 then
begin writeln(Iesire, 'JOS'); x:=x+1; D:=SUD; goto 1; end;
D:=EST; goto 1;
end; { VEST }
1:
15
until ((x=r) and (y=s));
end; { Mergi }

begin
Citeste;
assign(Iesire, 'HRUBE.OUT');
rewrite(Iesire);
Mergi(p, q, DI);
close(Iesire);
end.

Pentru a evalua complexitatea temporal a algoritmului, vom porni de la faptul c
numrul de ptrele ale cmpului de lucru a robotului nu depete valoarea nm. Prin
urmare, numrul de repetri ale instruciunilor din ciclul repeat ... until al procedurii
MERGI este de ordinul nm.
Conform restriciilor problemei, 100 , 5 s s m n . Evident,
4
10 = nm , mrime cu mult mai
mic dect capacitatea de prelucrare a calculatoarelor personale din laboratorul de
informatic.

16
Jocul
Se consider un cmp de joc, format din n rnduri i m coloane (vezi desenul). La
interseciile de rnduri i coloane se formeaz csue. Fiecare csu este definit prin
coordonatele sale: numrul de rnd x i numrul de coloan y.

1 2 3 4 5
1

2

3

4

5



6

Juctorul arunc un zar, care cade la ntmplare n una din csue. n general,
coordonatele acestei csue nu sunt cunoscute apriori, ns ele pot fi aflate explornd cmpul
de joc.
De exemplu, n cazul cmpului de joc de pe desen, zarul se afl n csua cu
coordonatele 5 = x i 3 = y .
Sarcin. Elaborai un program care, cunoscnd situaia de pe cmpul de joc, afl
coordonatele csuei n care se afl zarul.
Date de intrare. Fiierul text JOCUL.IN conine pe prima linie numerele ntregi n i m,
separate prin spaiu. Fiecare din urmtoarele n linii ale fiierului de intrare conine cte un ir
de caractere, format din exact m cifre binare {0, 1}. Dac zarul se afl n csua cu
coordonatele x, y, atunci cifra binar din poziia y a liniei 1 + x a fiierului de intrare are
valoarea 1. n caz contrar, cifra binar respectiv are valoarea 0.
Date de ieire. Fisierul text JOCUL.OUT va conine pe o singur linie dou numere
ntregi, separate prin spaiu: coordonatele x, y ale csuei n care se afl zarul.
Exemplu. Pentru desenul din enunul problemei, fiierele de intrare i ieire sunt:
JOCUL.IN JOCUL.OUT
6 5
00000
00000
00000
00000
00100
00000
5 3

Restricii. 1000 , 1 s s m n . Timpul de execuie nu va depi 1,0 secunde. Programul va
folosi cel mult 32 Megaoctei de memorie operativ. Fiierul surs va avea denumirea
JOCUL.PAS, JOCUL.C sau JOCUL.CPP.

17

Rezolvare
Vom explora fiierul de intrare caracter cu caracter. Evident, explorarea fiierului de
intrare poate fi terminat imediat cum a fost citit cifra binar cu valoarea 1.

Program Jocul;
{ Clasele 07-09 }
label 1;
var Intrare, Iesire : text;
n, m : longint;
x, y : longint;
c : char;
begin
assign(Intrare, 'JOCUL.IN');
reset(Intrare);
readln(Intrare, n, m);
for x:=1 to n do
begin
for y:=1 to m do
begin
read(Intrare, c);
if c='1' then goto 1;
end; { for }
readln(Intrare);
end; { for }
1:
close(Intrare);
assign(Iesire, 'JOCUL.OUT');
rewrite(Iesire);
writeln(Iesire, x, ' ', y);
close(Iesire);
end.
18
Ptratul numrului binar

Se consider un numr binar natural x, format din n cifre binare {0, 1}. De exemplu,
numrul binar 1001 = x este format din 4 = n cifre binare.
Sarcin. Elaborai un program care calculeaz numrul binar y,
2
x y = .
Date de intrare. Fiierului text PATRAT.IN conine pe o singur linie numrul binar x.
Date de ieire. Fiierului text PATRAT.OUT va conine pe o singur linie numrul binar
y, scris fr zerouri nesemnificative.
Exemplu.
PATRAT.IN PATRAT.OUT
1001 1010001

Restricii. 120 1 s s n . Timpul de execuie nu va depi 0,5 secunde. Programul va
folosi cel mult 32 Megaoctei de memorie operativ. Fiierul surs va avea denumirea
PATRAT.PAS, PATRAT.C sau PATRAT.CPP.


Rezolvare

Vom memora numrul binar x ntr-un ir de caractere. Ptratul acestui numr l vom
calcula implementnd algoritmul de nmulire a dou numere binare n coloni.

Program PatratulNumaruluiBinar;
{ Clasele 07-09 }

var A, B : string;

procedure Citeste(var X : string);
{ Citeste X din fisierul de intrare }
var Intrare : text;
begin
assign(Intrare, 'PATRAT.IN');
reset(Intrare);
readln(Intrare, X);
close(Intrare);
end; { Citeste }

procedure Scrie(X : string);
{ Scrie X in fisierul de iesire }
var Iesire : text;
begin
assign(Iesire, 'PATRAT.OUT');
rewrite(Iesire);
writeln(Iesire, X);
close(Iesire);
end; { Scrie }

procedure AdunaCifreBinare(a, b, c : char; var s, t : char);
{ Aduna cifrele binare a, b, c }
{ Returneaza suma s si transportul t }
begin
if (a='0') and (b='0') and (c='0') then begin t:='0'; s:='0' end;
if (a='0') and (b='0') and (c='1') then begin t:='0'; s:='1' end;
if (a='0') and (b='1') and (c='0') then begin t:='0'; s:='1' end;
19
if (a='0') and (b='1') and (c='1') then begin t:='1'; s:='0' end;
if (a='1') and (b='0') and (c='0') then begin t:='0'; s:='1' end;
if (a='1') and (b='0') and (c='1') then begin t:='1'; s:='0' end;
if (a='1') and (b='1') and (c='0') then begin t:='1'; s:='0' end;
if (a='1') and (b='1') and (c='1') then begin t:='1'; s:='1' end;
end; { AdunaCifre }

procedure AliniazaNumereBinare(var X, Y : string);
{ Aduce numerele X, Y la acelasi numar de cifre binare }
label 1;
var n, m, i : integer;
begin
n:=length(X);
m:=length(Y);
if n=m then goto 1;
if n<m then for i:=1 to m-n do X:='0'+X
else for i:=1 to n-m do Y:='0'+Y;
1: end; { AliniazaNumereBinare }

procedure AdunaNumereBinare(X, Y : string; var Z : string);
{ Calculleaza Z:=X+Y }
var t : char; { transportul }
i : integer;
begin
AliniazaNumereBinare(X, Y);
Z:='0';
AliniazaNumereBinare(X, Z);
t:='0';
for i:=length(X) downto 1 do
AdunaCifreBinare(t, X[i], Y[i], Z[i], t);
if t='1' then Z:='1'+Z;
end; { AdunaNumereBinare }

procedure RidicaLaPatrat(X : string; var Z : string);
{ Calculeaza Z:=X*X }
var Y : string;
i : integer;
begin
Y:=X;
Z:='0';
for i:=length(X) downto 1 do
begin
if X[i]='1' then AdunaNumereBinare(Y, Z, Z);
Y:=Y+'0'; { Deplaseaza numarul Y la stanga }
end; { for }
end; { RidicaLaPatrat }

begin
Citeste(A);
RidicaLaPatrat(A, B);
Scrie(B);
end.
20
Turnuri
Se consider trei tije notate prin 1, 2 i 3 i n discuri perforate de dimensiuni diferite
(vezi desenul). Iniial toate discurile sunt pe tija 1, fiind aranjate n ordinea descresctoare a
diametrelor, considernd sensul de la baz la vrf.

Sarcin. Elaborai un program care mut toate discurile de pe tija 1 pe tija 3, folosind
tija 2 ca tij de manevr i respectnd urmtoarele reguli:
la fiecare pas se mut un singur disc;
orice disc poate fi aezat doar peste un disc cu diametrul mai mare.
Date de intrare. Fiierul text TURNURI.IN conine pe o singur linie numrul ntreg n
numrul de discuri de pe tija 1.
Date de ieire. Fiierul text TURNURI.OUT va conine pe fiecare linie cte dou numere
ntregi i i j, separate prin spaiu. Fiecare linie a fiierului de ieire descrie cte o mutare de
disc: i indic tija de pe care se ia discul, iar j tija pe care se pune discul. Mutrile apar n
fiierul de ieire n ordinea efecturii lor.
Exemplu. Pentru 3 = n , fiierele de intrare i ieire sunt:
TURNURI.IN TURNURI.OUT
3 1 3
1 2
3 2
1 3
2 1
2 3
1 3

Restricii. 20 1 s s n . Nu se admit mutri n care j i = . Timpul de execuie nu va
depi 1,0 secunde. Programul va folosi cel mult 32 Megaoctei de memorie operativ.
Fiierul surs va avea denumirea TURNURI.PAS, TURNURI.C sau TURNURI.CPP.
21
Rezolvare
Pentru a rezolva aceast problem vom folosi o procedur recursiv, pe care o vom
denumi-o MutaDiscurile. Evident, aceast procedura trebuie s aib un antet de forma:
procedure MutaDiscurile(n, TI, TF, TM : integer);
unde n este numrul de discuri, TI tija iniial, TF tija final, iar TM tija de manevr.
n cazul unui singur disc, adic 1 = n , aceast procedur trebuie, pur i simplu, s mute
discul de pe tija TI pe tija TF.
n cazurile cu mai multe discuri, adic 1 > n , reducem problema cu n discuri la cea cu
) 1 ( n discuri:
1. Apelm procedura MutaDiscurile pentru a muta 1 n discuri de pe tija TI pe tija
TM, folosind ca tija de manevr tija TF.

2. Mutm discul rmas de pe tija TI pe tija TF.

3. Apelm procedura MutaDiscurile pentru a muta discurile de pe tija TM pe tija TF,
folosind ca tij de manevr tija TI.


22
Prezentm n continuare programul ce implementeaz procedura MutaDiscurile.

program Turnuri;
{ Clasele 07-09 }
var n : integer;
Intrare, Iesire : text;

procedure MutaDiscurile(n, TI, TF, TM : integer);
begin
if n=1 then writeln (Iesire, TI, ' ', TF)
else
begin
MutaDiscurile(n-1, TI, TM, TF);
writeln (Iesire, TI, ' ', TF);
MutaDiscurile(n-1, TM, TF, TI);
end; { else }
end; { MutaDiscurile }

begin
assign(Intrare, 'TURNURI.IN');
reset(Intrare);
readln(Intrare, n);
close(Intrare);
assign(Iesire, 'TURNURI.OUT');
rewrite(Iesire);
MutaDiscurile(n, 1, 3, 2);
Close(Iesire);
end.

Prin msurri directe de putem convinge c timpul de execuie a programului Turnuri
corespunde restriciilor problemei.

23
Punctajul competitorilor

Punctajul competitorilor, Clasele 07-09
0
50
100
150
200
250
300
350
400
450
500
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47
Competitorii


Complexitatea problemelor

Punctajul mediu pe problema, Clasele 07-09
37
28
9
7 7
1
0
5
10
15
20
25
30
35
40
Bilete Jocul Patrat Hrube Anagrame Turnuri
24

Clasele 1012


Denumirea
problemei
Numrul de
puncte alocat
problemei
Denumirea
fiierului surs
Denumirea
fiierului de
intrare
Denumirea
fiierului de
ieire
Comoara 100
COMOARA.PAS
COMOARA.C
COMOARA.CPP
COMOARA.IN COMOARA.OUT
Bilete 100
BILETE.PAS
BILETE.C
BILETE.CPP
BILETE.IN BILETE.OUT
Hrubele de la
Cricova
100
HRUBE.PAS
HRUBE.C
HRUBE.CPP
HRUBE.IN HRUBE.OUT
Jocul 100
JOCUL.PAS
JOCUL.C
JOCUL.CPP
JOCUL.IN
Rdcina
numrului binar
100
RAD.PAS
RAD.C
RAD.CPP
RAD.IN RAD.OUT
Turnuri 100
TURNURI.PAS
TURNURI.C
TURNURI.CPP
TURNURI.IN TURNURI.OUT
Total 600 - - -


25
Comoara

Vntorii de comori au descoperit n una din ncperile nchise ale unui castel medieval
n lingouri de aur de dimensiuni distincte. Fiecare lingou i, n i , , 3 , 2 , 1 = , reprezint un
paralelipiped dreptunghiular cu dimensiunile
i i i
z y x . Pentru a scoate lingourile la lumina
zilei, vntorii de comori trebuie s perforeze ntr-un zid de piatr unul sau mai multe orificii
dreptunghiulare, care nu au puncte de tangen. Un lingou poate fi scos printr-un orificiu
dreptunghiular doar atunci cnd limea i nlimea orificiului sunt egale sau mai mari ca
limea i nlimea uneia din feele dreptunghiulare ale paralelipipedului. Evident, lingoul
poate fi rotit in orice fel.
Pentru ai uura munca, vntorii de comori doresc ca suma ariilor orificiilor ce trebuie
perforate s fie ct mai mic.
Sarcin. Elaborai un program care, cunoscnd dimensiunile lingourilor de aur,
calculeaz valoarea minim S a sumei ariilor orificiilor de perforat, ce vor fi suficiente pentru
a scoate toate lingourile.
Date de intrare. Fiierul text COMOARA.IN conine pe prima linie numrul ntreg n.
Fiecare din urmtoarele n linii ale fiierului de intrare conine cte trei numere ntregi,
separate prin spaiu. Linia 1 + i a fiierului de intrare conine dimensiunile x
i
, y
i
i z
i
ale
lingoului i.
Date de ieire. Fiierul text COMOARA.OUT va conine pe o singur linie numrul ntreg
S valoarea minim a sumei ariilor orificiilor de perforat.
Exemplu.
COMOARA.IN COMOARA.OUT
3
1 4 4
5 3 2
1 2 2
8


Restricii. 5000 1 s s n ; 10000 , , 1 s s
i i i
z y x . Timpul de execuie nu va depi 3,0
secunde. Programul va folosi cel mult 32 Megaoctei de memorie operativ. Fiierul surs va
avea denumirea COMOARA.PAS, COMOARA.C sau COMOARA.CPP.


Rezolvare

Mai nti vom meniona, c n cazul unui singur lingou i, dimensiunile dreptunghiului
de cea mai mic arie se determin n mod trivial, selectnd din valorile
i i i
z y x , , doar dou,
cele mai mici din ele. n continuare, pentru fiecare lingou i vom nota astfel de dimensiuni prin
i i
y x , i le vom aranja n ordine descresctoare, adic
i i
y x > .
Valoarea minim a sumei ariilor orificiilor de perforat poate fi calculat prin metoda
programrii dinamice dup cum urmeaz:
1. Conform dimensiunilor x, sortam lingourile n ordine cresctoare. Dac exist dou
sau mai multe lingouri cu aceiai dimensiune x, sortm astfel de lingouri n ordine cresctoare
conform dimensiunii y.
2. Eliminm din studiu lingourile mici, care ncap integral in alte lingouri, mai mari.
n acest scop, parcurgem lingourile deja sortate i, la fiecare pas i, eliminam toate lingourile
26
precedente j, pentru care
i j
x x s i
i j
y y s . Se poate observa c dup eliminare, pentru
lingourile ramase se respect inegalitile
i i
x x <
1
i
i i
y y >
1
.
3. Fie n numrul curent de lingouri rmase. Introducem n studiu irul ) 0 ( F , ) 1 ( F , ...,
) (i F , ..., ) (n F , n care ) (i F este aria minima a orificiilor ce trebuie perforate pentru a scoate
primele i lingouri n ordinea stabilit la pasul 2. Valorile acestui ir pot fi calculate conform
urmtoarelor formule recurente:
0 ) 0 ( = F ;
} ..., , 1 ) 1 ( min{ ) ( i j x y j F i F
i j
= + = , n i ..., , 2 , 1 = .

Program Comoara;
const MAXN = 5000;
MAXXY = 10000;
type TLingou = record
x, y : longint;
end;
var n : longint;
L : array[1..MAXN] of TLingou;
F : array[0..MAXN] of longint;

procedure Citeste;
{ Citeste datele de intrare }
{ Selecteaza cele doua, mai mici, dimensiuni ale lingoului }
{ Ordoneaza dimensiunile selectate in ordine descrescatoare }
var Intrare : text;
x, y, z : longint; { dimensinule lingoului curent }
i : longint;
r : longint;
begin
assign(Intrare, 'COMOARA.IN');
reset(Intrare);
readln(Intrare, n);
for i:=1 to n do
begin
readln(Intrare, x, y, z);
if ((z>=x) and (z>=y)) then begin L[i].x:=x; L[i].y:=y end;
if ((y>=x) and (y>=z)) then begin L[i].x:=x; L[i].y:=z end;
if ((x>=y) and (x>=z)) then begin L[i].x:=y; L[i].y:=z end;
if (L[i].x<L[i].y) then
begin
r:=L[i].x; L[i].x:=L[i].y; L[i].y:=r;
end; { then }
end; { for }
close(Intrare);
end; { Citeste }

procedure Scrie;
var Iesire : text;
begin
assign(Iesire, 'COMOARA.OUT');
rewrite(Iesire);
writeln(Iesire, F[n]);
close(Iesire);
end;{ Scrie }

function MaiMic(i, j : longint) : boolean;
{ Compara lingourile i si j }
begin
if (L[i].x<>L[j].x) then MaiMic:=(L[i].x<L[j].x)
27
else MaiMic:=(L[i].y<L[j].y);
end; { MaiMic }

Procedure SorteazaLingourile;
var i : longint;
aux : TLingou;
ok : boolean;
begin
ok := true;
while ok do
begin
ok := false;
for i:=1 to n-1 do
if MaiMic(i+1, i) then
begin
aux:=L[i];
L[i]:=L[i+1];
L[i+1]:=aux;
ok:=true;
end; { for }
end; { while }
end; { SortareaLingourilor }

procedure EliminaLingourileMici;
var i, j : longint;
begin
j:=1;
for i:=2 to n do
begin
while (j>0) and (L[j].x<=L[i].x) and (L[j].y<=L[i].y)
do j:=j-1;
j:=j+1;
L[j]:=L[i];
end; { for }
n:=j;
end; { EliminaLingourileMici }

procedure CalculeazaAria;
var i, j, min, cost : longint;
begin
F[0]:=0;
for i:=1 to n do
begin
min:=MAXXY*MAXXY+1;
for j:=1 to i do
begin
cost:=F[j-1]+L[j].y*L[i].x;
if (cost<min) then min:=cost;
end;
F[i]:=min;
end;
end; { CalculeazaAria }

begin
Citeste;
SorteazaLingourile;
EliminaLingourileMici;
CalculeazaAria;
Scrie;
end.

Timpul cerut de procedurile programului Comoara poate fi estimat analiznd textele
respective:
28
SorteazaLingourile A ~
2
14 ) ( n n T ;
EliminaLingourileMici A ~ n n T 8 ) ( ;
CalculeazaAria A ~
2
12 ) ( n n T ,
unde A este timpul necesar pentru efectuarea unei operaii elementare. Amintim, c n cazul
calculatoarelor din laboratorul de informatic,
9
10

~ A secunde.
Prin urmare, timpul cerut de programul Comoara va fi A ~
2
26 ) ( n n T . Pentru cel mai
greu caz, 5000 = n i 65 , 0 ) 5000 ( ~ T secunde, mrime comparabil cu cea indicat n
restriciile problemei.
ntruct metoda de evaluare a timpului cerut de programul Comoara este una
orientativ, pentru a fi siguri c programul se ncadreaz n timpul cerut de restriciile
problemei, ar fi bine s elaborm un test cu 5000 = n de lingouri i s efectum msurri
directe.
Genernd n mod aleator 5000 de paralelipipede cu dimensiuni ce se ncadreaz n
intervalul indicat n restriciile problemei, ne putem convinge c timpul de execuie a
programului Comoara nu depete valoarea de 3,0 secunde.
29
Bilete

Biletele de trolebuz din marele orae sunt numerotate. De obicei, un
numr de bilet este format din 6 cifre zecimale.
Unii elevi i studeni consider c n cazul n care suma primelor trei cifre
din componena numrului de bilet este egal cu suma ultimelor trei cifre,
biletul respectiv aduce noroc sau, prin alte cuvinte, este un bilet fericit.
De exemplu, biletul cu numrul 032050 este fericit, iar cel cu numrul
283375 nu.
n general, la nceput de rut, taxatorul primete o bobin de bilete numerotate
consecutiv i semneaz un borderou n care este indicat numrul primului bilet m i numrul
total de bilete n din bobina respectiv.
Apare ntrebarea, cte bilete fericite conine bobina taxatorului.
Sarcin. Elaborai un program care, cunoscnd numrul primului bilet m i numrul
total de bilete n din bobina taxatorului, calculeaz numrul de bilete fericite k din ea.
Date de intrare. Fiierul text BILETE.IN conine pe o singur linie numerele ntregi m
i n, separate prin spaiu.
Date de ieire. Fiierul text BILETE.OUT va conine pe o singur linie numrul ntreg
k.
Exemplu.
BILETE.IN BILETE.OUT
332206 10 2

Restricii. 999999 000000 s s m ; ) 1 999999 ( + s m n . Timpul de execuie nu va
depi 1,0 secunde. Programul va folosi cel mult 32 Megaoctei de memorie operativ.
Fiierul surs va avea denumirea BILETE.PAS, BILETE.C sau BILETE.CPP.


Rezolvare

Vom nota prin i numrul biletului curent, iar prin c
1
, c
2
, c
3
, c
4
, c
5
, c
6
cifrele din
componena acestui numr. De exemplu, n cazul numrului de bilet i = 360710 avem 3
1
= c ,
6
2
= c , 0
3
= c , 7
4
= c , 1
5
= c , 0
6
= c .
Cifrele numrului de bilet i pot fi calculate n ordinea c
6
, c
5
, c
4
, c
3
, c
2
, c
1
prin mpriri
succesive a numrului de bilet i a cturilor obinute la baza 10 a sistemului zecimal de
numeraie, reinnd resturile mpririlor.
Evident, un bilet este fericit atunci cnd ). ( ) (
6 5 4 3 2 1
c c c c c c + + = + +
Pentru a calcula numrul de bilete fericite din bobin, este suficient s examinm
toate valorile lui i din intervalul m (numrul primului bilet din bobin) 1 + n m (numrul
ultimului bilet din bobin.

Program Bilete;
{ Clasele 10-12 }
var m : longint; { numarul primului bilet din bobina }
n : longint; { numarul total de bilete in bobina }
k : longint; { numarul biletelor fericite din bobina }

30
procedure Citeste;
var Intrare : text;
begin
assign(Intrare, 'BILETE.IN');
reset(Intrare);
readln(Intrare, m, n);
close(Intrare);
end; { Citeste }

procedure Scrie;
var iesire : text;
begin
assign(Iesire, 'BILETE.OUT');
rewrite(Iesire);
writeln(Iesire, k);
close(Iesire);
end; { Scrie }

procedure Cifre(i : longint; var c1, c2, c3, c4, c5, c6 : integer);
{ returneaza cifrele c1, c2, ..., c6 ale numarului de bilet i }
begin
c6:=i mod 10; i:=i div 10;
c5:=i mod 10; i:=i div 10;
c4:=i mod 10; i:=i div 10;
c3:=i mod 10; i:=i div 10;
c2:=i mod 10; i:=i div 10;
c1:=i mod 10;
end; { Cifre }

procedure Calculeaza;
{ calculeaza numarul de bilete fericite }
var
u : longint; { numarul ultimului bilet din bobina }
i : longint; { numarul biletului curent }
c1, c2, c3, c4, c5, c6 : integer; { cifrele biletului curent }
begin
u:=m+n-1;
k:=0;
for i:=m to u do
begin
Cifre(i, c1, c2, c3, c4, c5, c6);
if (c1+c2+c3)=(c4+c5+c6) then k:=k+1;
end; { for }
end; { Calculeaza }

begin
Citeste;
Calculeaza;
Scrie;
end.

Din analiza textului procedurilor Cifra i Calculeaza se observ c timpul cerut de
algoritm este de ordinul A ~ n n T 20 ) ( , unde A este timpul necesar pentru efectuarea unei
operaii elementare. Conform restriciilor problemei, ) 1 999999 ( + s m n i
999999 000000 s s m . Evident,
7
10 s n i, pentru cel mai greu caz,
8 7
10 2 ) 10 ( A ~ T .
ntruct pentru calculatoarele din laboratorul de informatic
9
10

~ A secunde, pentru cazul


cel mai greu 2 , 0 ~ T secunde, mrime ce nu ncalc restriciile problemei.

31
Hrubele de la Cricova

Dup o vizit la renumitele hrube
*
de la Cricova, un informatician a construit un robot
care lucreaz ntr-un cmp divizat n ptrele (vezi desenul). Ptrelele haurate reprezint
obstacolele, iar cele nehaurate spaiile libere.
Ptrelele de pe perimetrul planului, cu excepia
celor de intrare sau ieire, snt haurate prin definiie.
Robotul poate executa doar instruciunile SUS,
JOS, DREAPTA, STANGA, conform crora el se
deplaseaz n unul din ptrele vecine. Dac n
ptratul vecin este un obstacol, de exemplu, un
perete sau un butoi, are loc un accident i robotul
iese din funciune.
n form numeric planul hrubelor este redat
prin tabloul A cu n linii i m coloane. Elementele
] , [ j i A ale acestui tablou au urmtoarea semnificaie: 0 spaiu liber; 1 obstacol; 2
intrarea n hrube; 3 ieirea din hrube. Iniial, robotul se afl n ptrelul pentru care
2 ] , [ = j i A .
Sarcin. Elaborai un program, care, cunoscnd planul hrubelor, deplaseaz robotul prin
ncperile subterane, de la intrarea n hrube la ieire, utiliznd un numr ct mai mic de
instruciuni. Colecia de vinuri fiind foarte bogat, nu se cere vizitarea obligatorie a tuturor
ncperilor subterane.
Date de intrare. Fiierul text HRUBE.IN conine pe prima linie numerele ntregi n, m,
separate prin spaiu. Pe fiecare din urmtoarele n linii se conin cte m numere ntregi ] , [ j i A ,
separate prin spaiu.
Date de ieire. Fiierul text HRUBE.OUT va conine pe prima linie un numr ntreg L
numrul minim de instruciuni, necesare pentru deplasarea robotului de la intrare la ieire.
Fiecare din urmtoarele L linii ale fiierului de ieire va conine cte una din instruciunile
SUS, JOS, DREAPTA, STANGA, scrise n ordinea executrii lor de ctre robot. Dac problema
admite mai multe soluii, n fiierul de ieire se va scrie doar una, oricare din ele.

Exemplu:

HRUBE.IN HRUBE.OUT
7 9
1 1 1 1 1 1 1 1 1
1 0 0 1 0 0 0 0 1
1 0 1 0 0 1 0 1 1
1 0 0 0 1 0 0 0 1
1 0 1 0 1 0 1 0 1
1 0 0 0 0 0 1 0 1
1 2 1 1 1 1 1 3 1
12
SUS
DREAPTA
DREAPTA
DREAPTA
DREAPTA
SUS
SUS
DREAPTA
DREAPTA
JOS
JOS
JOS


*
Hrub ncpere sau galerie subteran care servete la depozitarea produselor alimentare. n hrubele de la
Cricova pe parcursul a mai multor decenii sunt depozitate cele mai bune vinuri din Republica Moldova.
32
Restricii. 100 , 5 s s m n . Timpul de execuie nu va depi 3 secunde. Programul va
folosi cel mult 32 Megaoctei de memorie operativ. Fiierul surs se va numi HRUBE.PAS,
HRUBE.C sau HRUBE.CPP.


Rezolvare

Pentru a gsi unul din cele mai scurte drumuri ce leag intrarea cu ieirea, vom propaga
prin hrube o und numeric, care pornete din ptrelul de intrare.
Iniial, nscriem n ptrelul de intrare valoarea undei numerice 0 = u i marcm acest
ptrel ca fiind unul ocupat.
Presupunem, c la un anumit pas, unda numeric a ajuns n anumite ptrele i are deja
valoarea curent u.
Urmtorul pas const n identificarea ptrelelor n care este nscris valoarea u i
nscrierea n ptrelele vecine, care sunt libere, a valorii 1 + u .
n continuare, stabilim 1 : + = u u , efectum urmtorul pas .a.m.d., pn cnd unda
numeric ajunge n ptrelul de ieire.
Evident, valoarea undei numerice u, care este nscris n ptrelul de ieire, reprezint
numrul minim de instruciuni L, necesare pentru a deplasa robotul de la intrare la ieire.
Pentru a afla instruciunile propriu-zise, care deplaseaz robotul pe cel mai scurt drum,
ne vom mica imaginar de la ieire la intrare, n sens contrar direciei de propagare a undei
numerice.
Iniial, stabilim ca punct de plecare ptrelul de ieire i valoarea curent a undei
numerice L u = .
Presupunem, c la un anumit pas s-a ajuns la ptrelul n care este nscris valoarea
numeric u.
Urmtorul pas const n identificarea oricruia din ptrelele vecine, n care este
nscris valoarea 1 u . n funcie de poziie relativ a unuia astfel de ptrel, memorm n
secvena de instruciuni una din instruciunile SUS, JOS, STANGA, DREAPTA i trecem n
ptrelul respectiv.
n continuare, stabilim 1 : = u u .a.m.d., pn se ajunge n ptrelul de intrare.
n programul ce urmeaz, pentru a nu confunda valorile undei numerice cu valorile
iniiale 1, 2 i 3 din fiierul de intrare, n ptrelele ce reprezint obstacole se nscrie valoarea
-1.

Program Hrube;
{ Clasele 10-12 }
const nmax=100; mmax=100;
Lmax=(nmax * mmax) div 2;
Ocupat=-1;

var A : array[1..nmax, 1..mmax] of integer;
n, m : integer; { dimensiunile campului }
p, q : integer; { coordonatele intrarii }
r, s : integer; { coordonatele iesirii }
L : integer; { lungimea secventei de instructiuni }
C : array[1..Lmax] of string[7]; { secventa de instructiuni }

procedure Citeste;
var i, j : integer;
Intrare : text;
begin
assign(Intrare, 'HRUBE.IN');
reset(Intrare);
33
readln(Intrare, n, m);
for i:=1 to n do
begin
for j:=1 to m do
begin
read(Intrare, A[i, j]);
if A[i, j]=2 then begin p:=i; q:=j; A[i, j]:=0; end;
if A[i, j]=3 then begin r:=i; s:=j; A[i, j]:=0; end;
if A[i, j]=1 then A[i, j]:=Ocupat;
end; { for }
readln(Intrare);
end; { for }
close(Intrare);
end; { Citeste }

procedure Scrie;
var i : integer;
Iesire : text;
begin
assign(Iesire, 'HRUBE.OUT');
rewrite(Iesire);
writeln(Iesire, L);
for i:=1 to L do
writeln(Iesire, C[i]);
close(Iesire);
end; { Scrie }

procedure UndaNumerica;
{ Propagarea undei numerice }
var i, j : integer;
u : integer; { unda numerica }
begin
u:=1;
if p=1 then A[2, q]:=1;
if p=n then A[n-1, q]:=1;
if q=1 then A[p, 2]:=1;
if q=m then A[p, m-1]:=1;
A[p, q]:=Ocupat; { blocam intrarea }
while A[r, s]=0 do
begin
for i:=1 to n do
for j:=1 to m do
begin
if A[i, j]=u then
begin
if A[i-1, j]=0 then A[i-1, j]:=u+1; { Nord }
if A[i+1, j]=0 then A[i+1, j]:=u+1; { Sud }
if A[i, j-1]=0 then A[i, j-1]:=u+1; { Est }
if A[i, j+1]=0 then A[i, j+1]:=u+1; { Vest }
end; { then }
end; { for }
u:=u+1;
end; { while }
L:=u;
A[p, q]:=0; { deblocam intrarea }
end; { UndaNumerica }

procedure Drumul;
{ Scrie in C instructiunile ce deplaseaza robotul }
label 1;
var i, j : integer;
u : integer;
begin
if r=1 then begin C[L]:='SUS'; i:=2; j:=s; end;
34
if r=n then begin C[L]:='JOS'; i:=n-1; j:=s; end;
if s=1 then begin C[L]:='STANGA'; i:=r; j:=2; end;
if s=m then begin C[L]:='DREAPTA'; i:=r; j:=m-1; end;
u:=L-1;
while not ((i=p) and (j=q)) do
begin
if A[i-1, j]=u-1 then begin C[u]:='JOS'; i:=i-1; goto 1; end;
if A[i+1, j]=u-1 then begin C[u]:='SUS'; i:=i+1; goto 1; end;
if A[i, j-1]=u-1 then begin C[u]:='DREAPTA'; j:=j-1; goto 1; end;
if A[i, j+1]=u-1 then begin C[u]:='STANGA'; j:=j+1; goto 1; end;
1: u:=u-1;
end; { while }
end; { Drumul }

begin
Citeste;
UndaNumerica;
Drumul;
Scrie;
end.

Timpul cerut de procedurile programului Hrube poate fi estimat analiznd textele
respective:
UndaNumeric A ~ Lnm m n T 26 ) , ( ;
Drumul A ~ L m n T 11 ) , ( ,
unde A este timpul necesar pentru efectuarea unei operaii elementare, iar L lungimea
drumului.
ntruct, nm L < , timpul cerut de programul Hrube va fi A ~
2 2
26 ) , ( m n m n T .
Amintim, c n cazul calculatoarelor din laboratorul de informatic,
9
10

~ A secunde.
Pentru cel mai greu caz, 100 = = m n i 6 , 2 ) 100 , 100 ( ~ T secunde, mrime comparabil
cu cea indicat n restriciile problemei.
ntruct metoda de evaluare a timpului cerut de programul Hrube este una orientativ,
pentru a fi siguri c programul se ncadreaz n timpul cerut de restriciile problemei, ar fi
bine s elaborm un test cu 100 = = m n i s efectum msurri directe.
Genernd n mod aleator un plan de hrube cu 100 = = m n , ne putem convinge c
timpul de execuie a programului Hrube nu depete valoarea de 3,0 secunde.

35
Jocul

Se consider un cmp de joc, format din n rnduri i m coloane (vezi desenul). La
interseciile de rnduri i coloane se formeaz csue. Fiecare csu este definit prin
coordonatele sale: numrul de rnd x i numrul de coloan y.
Juctorul arunc un zar, care cade la ntmplare n
una din csue. n general, coordonatele acestei csue nu sunt
cunoscute apriori, ns ele pot fi aflate apelnd, ori de cte ori
este nevoie, funcia boolean EsteInZona.
n Pascal antetul acestei funcii are forma:
function EsteInZona(i,j,k,l: longint):
Boolean;
iar n C/C++:
bool EsteInZona(long i, long j, long k, long l)
unde parametrii i, j, k, l definesc o zon dreptunghiular a cmpului de joc, i fiind numrul
rndului de sus al zonei, j numrul rndului de jos al zonei, k numrul coloanei din
stnga a zonei, iar l numrul coloanei din dreapta a zonei.
Funcia EsteInZona returneaz valoarea true dac zarul se afl n una din csuele ce
aparine zonei respective i false n caz contrar.
De exemplu, n cazul cmpului de joc de pe desen, apelul EsteInZona(3, 6, 2, 4)
returneaz valoarea true, iar apelul EsteInZona(1, 4, 2, 4) returneaz valoarea
false.
Sarcin. Elaborai un program care afl coordonatele x, y ale csuei n care se afl
zarul, cu condiia ca numrul de apeluri q ale funciei EsteInZona s fie ct mai mic posibil.
Date de intrare. Fisierul text JOCUL.IN conine pe o singur linie numerele ntregi n i
m separate prin spaiu.
Date de ieire. Fiier de ieire nu exist. Pentru a comunica evaluatorului coordonatele
x, y ale csuei n care se afl zarul, executai apelul de procedur Raspuns(x, y), unde x i
y sunt variabile de tipul longint n Pascal sau long in C/C++.
Not. Funcia EsteInZona i procedura Raspuns nu trebuie definite n programul
vostru. ns, pentru a putea folosi aceste subprograme fr a avea descrierea lor, pur i simplu
includei la nceputul programului vostru urmtoarea linie:
n Pascal:
uses Campul;
n C/C++:
#include campul.h C/C++
Exemplu. Pentru desenul din enunul problemei, fiierele de intrare i ieire sunt:

1 2 3 4 5
1

2

3

4

5



6


36
JOCUL.IN
6 5
Restricii.
6
10 1 s s m n, . Timpul de execuie nu va depi 0,2 secunde. Programul va folosi
cel mult 32 Megaoctei de memorie operativ. Fiierul surs va avea denumirea JOCUL.PAS,
JOCUL.C sau JOCUL.CPP.


Rezolvare
Vom trata cmpul de joc ca o surs de informaie, mesajele posibile ale creia au forma
(x, y), unde x i y sunt coordonate de csu. Evident, numrul total al mesajelor posibile este
egal cu numrul de csue
nm
.
Cantitatea de informaie ntr-un mesaj al acestei surse se determin conform formulei
cunoscute din manualul colar de Informatic:

m + n = nm = I
2 2 2
log log log (bii).

Este cunoscut faptul, c cantitatea de informaie I reprezint numrul minim de ntrebri
ce trebuie formulate pentru a identifica un mesaj concret al sursei de informai, n cazul nostru
pentru a identifica csua n care se afl zarul. ntrebrile propriu-zise se formuleaz prin
metoda dihotonomiei, mprind consecutiv zona de cutare n jumtate.
Prin urmare, pentru a afla rndul x, n una din csuele cruia se afl zarul, mai nti
vom efectua apelul funciei EsteInZona pentru jumtatea de sus a cmpului de joc i,
ulterior, n dependen de rspunsul primit, vom apela din nou aceast funcie pentru o
jumtate din zona nou de cutare .a.m.d.
ntr-un mod similar, pentru a afla coloana y, n una din csuele cruia se afl zarul, mai
nti vom efectua apelul funciei EsteInZona pentru jumtatea din stnga a cmpului de joc
i, ulterior, n dependen de rspunsul primit, vom apela din nou aceast funcie pentru o
jumtate din zona nou de cutare .a.m.d.

Program Jocul;
uses Campul;
{ Clasele 10-12 }
var n, m, x, y, q : longint;
procedure Citeste;
var Intrare : text;
begin
assign(Intrare, 'JOCUL.IN');
reset(Intrare);
readln(Intrare, n, m);
close(Intrare);
end; { Citeste }
procedure Scrie;
var Iesire : text;
begin
assign(Iesire, 'JOCUL.OUT');
rewrite(Iesire);
writeln(Iesire, x, ' ', y, ' ', q);
close(Iesire);
end; { Scrie }
procedure Cauta;
var i, j, k, l, c : longint;
37
begin
q:=0;
{ cautam randul in care se afla zarul }
i:=1; j:=n;
while i<>j do
begin
q:=q+1;
c:=i+((j-i) div 2); { divizam zona pe orizontala };
if EsteInZona(i, c, 1, m) then j:=c else i:=c+1;
end;
x:=i;
{ cautam coloana in care se afla zarul }
k:=1; l:=m;
while k<>l do
begin
q:=q+1;
c:=k+((l-k) div 2); { divizam zona pe verticala }
if EsteInZona(1, n, k, c) then l:=c else k:=c+1;
end;
y:=k;
end; { Cauta }
begin
Citeste;
Cauta;
Scrie;
end.

n condiiile problemei,
1 n, m 10
6
. Prin urmare, numrul de apeluri ale funciei
EsteInZon este egal cu cel mult 60 30 30 log log log
2 2 2
= + m + n = nm ~ , mrime cu mult
mai mic dect capacitatea de prelucrare a calculatoarelor moderne.

38
Rdcina numrului binar

Se consider numrul binar natural x, format n cifre binare {0, 1}, care este, de fapt,
ptratul unui alt numr binar natural y. De exemplu, numrul binar 1010001 = x este format
din 7 = n cifre binare i este ptratul numrului binar 1001 = y .
Sarcin. Elaborai un program care calculeaz numrul binar y, x y = .
Date de intrare. Fiierului text RAD.IN conine pe o singur linie numrul binar x.
Date de ieire. Fiierului text RAD.OUT va conine pe o singur linie numrul binar y,
scris fr zerouri nesemnificative.
Exemplu.
RAD.IN RAD.OUT
1010001 1001

Restricii. 250 1 s s n . Timpul de execuie nu va depi 1,5 secunde. Programul va
folosi cel mult 32 Megaoctei de memorie operativ. Fiierul surs va avea denumirea
RAD.PAS, RAD.C sau RAD.CPP.


Rezolvare

Vom memora numrul binar x ntr-un ir de caractere. Evident, numrul de cifre m ale
numrului binar x y = este de dou ori mai mic dect numrul de cifre n ale numrului x
sau, mai exact:

) 2 ( ) 2 ( mod div n n m + = .

Evident, prima cifr din stnga a numrului binar y are valoarea 1. Prin urmare, iniial
stabilim 0 ... 100 = y , n total m cifre binare.
Vom preciza valorile celorlalte ) 1 ( m cifre binare ale numrului y cifra cu cifra, de la
stnga la dreapta.
Presupunem, ca am calculat deja primele i cifre binare ale numrului y. Pentru a calcula
urmtoarea cifra binar ) 1 ( + i , i atribuim ei valoarea 1 i ridicm numrul y astfel obinut la
ptrat. n continuare, sunt posibile urmtoarele cazuri:
1) x y <
2
trecem la calculul urmtoarei cifrei binare ) 2 ( + i ;
2) x y =
2
calculele se ncheie;
3) x y >
2
restabilim valoarea cifrei ) 1 ( + i n 0 i trecem la calculul urmtoarei cifre
binare ) 2 ( + i .
n programul ce urmeaz, ptratul numrului binar y este calculat cu ajutorul
algoritmului de nmulire n coloni.

Program RadacinalNumaruluiBinar;
{ Clasele 10-12 }
var A, B : string;

procedure Citeste(var X : string);
{ Citeste X din fisierul de intrare }
var Intrare : text;
39
begin
assign(Intrare, 'RAD.IN');
reset(Intrare);
readln(Intrare, X);
close(Intrare);
end; { Citeste }

procedure Scrie(X : string);
{ Scrie X in fisierul de iesire }
var Iesire : text;
begin
assign(Iesire, 'RAD.OUT');
rewrite(Iesire);
writeln(Iesire, X);
close(Iesire);
end; { Scrie }

procedure AdunaCifreBinare(a, b, c : char; var s, t : char);
{ Aduna cifrele binare a, b, c }
{ Returneaza suma s si transportul t }
begin
if (a='0') and (b='0') and (c='0') then begin t:='0'; s:='0' end;
if (a='0') and (b='0') and (c='1') then begin t:='0'; s:='1' end;
if (a='0') and (b='1') and (c='0') then begin t:='0'; s:='1' end;
if (a='0') and (b='1') and (c='1') then begin t:='1'; s:='0' end;
if (a='1') and (b='0') and (c='0') then begin t:='0'; s:='1' end;
if (a='1') and (b='0') and (c='1') then begin t:='1'; s:='0' end;
if (a='1') and (b='1') and (c='0') then begin t:='1'; s:='0' end;
if (a='1') and (b='1') and (c='1') then begin t:='1'; s:='1' end;
end; { AdunaCifre }

procedure AliniazaNumereBinare(var X, Y : string);
{ Aduce numerele X, Y la acelasi numar de cifre binare }
label 1;
var n, m, i : integer;
begin
n:=length(X);
m:=length(Y);
if n=m then goto 1;
if n<m then for i:=1 to m-n do X:='0'+X
else for i:=1 to n-m do Y:='0'+Y;
1: end; { AliniazaNumereBinare }

procedure AdunaNumereBinare(X, Y : string; var Z : string);
{ Calculleaza Z:=X+Y }
var t : char; { transportul }
i : integer;
begin
AliniazaNumereBinare(X, Y);
Z:='0';
AliniazaNumereBinare(X, Z);
t:='0';
for i:=length(X) downto 1 do
AdunaCifreBinare(t, X[i], Y[i], Z[i], t);
if t='1' then Z:='1'+Z;
end; { AdunaNumereBinare }

procedure RidicaLaPatrat(X : string; var Z : string);
{ Calculeaza Z:=X*X }
var Y : string;
i : integer;
begin
Y:=X;
Z:='0';
40
for i:=length(X) downto 1 do
begin
if X[i]='1' then AdunaNumereBinare(Y, Z, Z);
Y:=Y+'0'; { Deplaseaza numarul Y la stanga }
end; { for }
end; { RidicaLaPatrat }

function SuntEgale(X, Y : string) : boolean;
{ Returneaza TRUE daca X>Y si FALSE in caz contrar }
begin
AliniazaNumereBinare(X, Y);
SuntEgale := (X=Y);
end; { SuntEgale }

function EsteMaiMare(X, Y : string) : boolean;
{ Returneaza TRUE dac X>Y si FALSE in caz contrar }
var i : integer;
begin
AliniazaNumereBinare(X, Y);
EsteMaiMare := (X>Y);
end; { EsteMaiMare }

procedure ExtrageRadacina(X : string; var Y : string);
{ Calculeaza Y:=Radical(X) }
label 2;
var n, m, i : integer;
Z : string;
begin
n:=length(X);
m:=(n div 2)+(n mod 2);
Y:='1';
for i:=2 to m do Y:=Y+'0';
RidicaLaPatrat(Y, Z);
if SuntEgale(Z, X) then goto 2;
for i:=2 to m do
begin
Y[i]:='1';
RidicaLaPatrat(Y, Z);
if SuntEgale(Z, X) then goto 2;
if EsteMaiMare(Z, X) then Y[i]:='0';
end; { for }
2: end; { ExtrageRadacina }

begin
Citeste(A);
ExtrageRadacina(A, B);
Scrie(B);
end.

Din analiza textului programului RadacinalNumaruluiBinar rezult c complexitatea
temporal a algoritmului este ) (
3
n O . Conform restriciilor problemei, 250 s n . Prin urmare,
timpul cerut de algoritm va fi proporional cu
8
10 , mrime mai mic dect capacitatea de
prelucrare a calculatoarelor personale din laboratoarele de informatic.

41
Turnuri
Se consider trei tije notate prin 1, 2 i 3 i n discuri perforate de dimensiuni diferite
(vezi desenul). Iniial toate discurile sunt pe tija 1, fiind aranjate n ordinea descresctoare a
diametrelor, considernd sensul de la baz la vrf.

Sarcin. Elaborai un program care mut toate discurile de pe tija 1 pe tija 3, folosind
tija 2 ca tij de manevr i respectnd urmtoarele reguli:
la fiecare pas se mut un singur disc;
orice disc poate fi aezat doar peste un disc cu diametrul mai mare.
Date de intrare. Fiierul text TURNURI.IN conine pe o singur linie numrul ntreg n
numrul de discuri de pe tija 1.
Date de ieire. Fiierul text TURNURI.OUT va conine pe fiecare linie cte dou numere
ntregi i i j, separate prin spaiu. Fiecare linie a fiierului de ieire descrie cte o mutare de
disc: i indic tija de pe care se ia discul, iar j tija pe care se pune discul. Mutrile apar n
fiierul de ieire n ordinea efecturii lor.
Exemplu. Pentru 3 = n , fiierele de intrare i ieire sunt:
TURNURI.IN TURNURI.OUT
3 1 3
1 2
3 2
1 3
2 1
2 3
1 3

Restricii. 20 1 s s n . Nu se admit mutri n care j i = . Timpul de execuie nu va
depi 1,0 secunde. Programul va folosi cel mult 32 Megaoctei de memorie operativ.
Fiierul surs va avea denumirea TURNURI.PAS, TURNURI.C sau TURNURI.CPP.
42
Rezolvare
Pentru a rezolva aceast problem vom folosi o procedur recursiv, pe care o vom
denumi-o MutaDiscurile. Evident, aceast procedura trebuie s aib un antet de forma:
procedure MutaDiscurile(n, TI, TF, TM : integer);
unde n este numrul de discuri, TI tija iniial, TF tija final, iar TM tija de manevr.
n cazul unui singur disc, adic 1 = n , aceast procedur trebuie, pur i simplu, s mute
discul de pe tija TI pe tija TF.
n cazurile cu mai multe discuri, adic 1 > n , reducem problema cu n discuri la cea cu
) 1 ( n discuri:
4. Apelm procedura MutaDiscurile pentru a muta 1 n discuri de pe tija TI pe tija
TM, folosind ca tija de manevr tija TF.

5. Mutm discul rmas de pe tija TI pe tija TF.

6. Apelm procedura MutaDiscurile pentru a muta discurile de pe tija TM pe tija TF,
folosind ca tij de manevr tija TI.


43
Prezentm n continuare programul ce implementeaz procedura MutaDiscurile.

program Turnuri;
{ Clasele 10-12 }
var n : integer;
Intrare, Iesire : text;

procedure MutaDiscurile(n, TI, TF, TM : integer);
begin
if n=1 then writeln (Iesire, TI, ' ', TF)
else
begin
MutaDiscurile(n-1, TI, TM, TF);
writeln (Iesire, TI, ' ', TF);
MutaDiscurile(n-1, TM, TF, TI);
end; { else }
end; { MutaDiscurile }

begin
assign(Intrare, 'TURNURI.IN');
reset(Intrare);
readln(Intrare, n);
close(Intrare);
assign(Iesire, 'TURNURI.OUT');
rewrite(Iesire);
MutaDiscurile(n, 1, 3, 2);
Close(Iesire);
end.

Prin msurri directe de putem convinge c pentru 20 = n timpul de execuie a
programului Turnuri nu depete valoarea indicat n restriciile problemei.


44
Punctajul competitorilor

Punctajul competittorilor, Clasele 10-12
0
100
200
300
400
500
600
1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 86 91 96 101 106 111 116
Competitorii


Complexitatea problemelor

Punctajul mediu pe problema, Clasele 10-12
48
18
16
16
15
7
0
10
20
30
40
50
60
Bilete Turnuri Radacina Hrube Jocul Comoara



Lista premianilor

Locul Elevul Clasa Municipiul/Raionul Institutia Profesorul Conducatorul echipei
1 Climan Ion 12 Chiinu Liceul Republican cu Profil Real Butenco Inna Minzelevschi Igor
1 Indricean Mihai 11 Chiinu Liceul Teoretic "Orizont" (fil. Durlesti) Corlat Sergiu Golubev Svetlana
1 Chiciuc Nicu 10 Chiinu Liceul Teoretic Spiru Haret Schico Svetlana Golubev Svetlana
1 Savva Dumitru 8 Chiinu Liceul Teoretic "Orizont" (fil. Durlesti) Corlat Sergiu Golubev Svetlana
2 Grigoroi Alexandru 12 Chiinu Liceul Teoretic "Orizont" (fil. Durlesti) Corlat Sergiu Golubev Svetlana
2 Cerneanu Cristian 11 Chiinu Liceul Teoretic "Orizont" (fil. Durlesti) Corlat Sergiu Golubev Svetlana
2 Ciuntu Victor 9 Chiinu Liceul Teoretic "Prometeu-Prim" Adam Ecaterina Golubev Svetlana
2 Ivanov Andrei 11 Chiinu Liceul Teoretic "Orizont" (fil. Durlesti) Corlat Sergiu Golubev Svetlana
2 Dru Gheorghe 9 Chiinu Liceul Teoretic "Prometeu-Prim" Adam Ecaterina Golubev Svetlana
2 Umbatov Ahmed 10 Chiinu Liceul Teoretic "V. Lupu" Movleanova Galina Golubev Svetlana
2 Moraru Nicolai 10 Drochia Liceul Teoretic "M. Eminescu" Chistruga Gheorghe Barsan Valentin
2 Pojoga Vasile 11 Chiinu Liceul Acedemiei de tiine a Moldovei Raisa Miron Raisa Miron
3 Moroi Andrian 12 Soroca Liceul Teoretic "C. Stere" Ba Vasile Gnga Sergiu
3 Neagaru Daniel 12 Chiinu Liceul Acedemiei de tiine a Moldovei Raisa Miron Raisa Miron
3 Bicec Iuliu 12 Hnceti Liceul Teoretic "M. Sadoveanu" Brnz Valentina Pojoga Maria
3 Nedelciuc Silviu 12 Bli Liceul Teoretic "M. Eminescu" Curbet Gheorghe Brsan Valentin
3 Griza Daniel 8 Chiinu Liceul Teoretic "Orizont" (fil. Durlesti) Corlat Sergiu Golubev Svetlana
3 Toloac Ion 11 Chiinu Liceul Teoretic Mircea Eliade Anton Ghenadie Golubev Svetlana
3 Preguza Mihai 11 Clrai Liceul Teoretic "M. Sadoveanu" Gavrili Alexei Gavrili Alexei
3 Srbu Roman 10 Streni Liceul Teoretic "I. Vatamanu" irdea lIdia irdea lIdia
3 Luncau Victor 11 Nisporeni Liceul Teoretic "Boris Cazacu" Brodicico Valeriu Brodicico Valeriu
3 Bezdrighin Marcel 7 Chiinu Liceul Teoretic "Prometeu-Prim" Dragan Galina Golubev Svetlana
3 Martnin Alexandru 10 Tiraspol Liceul Teoretic Tiraspol agoian Tamara Arma Marina
46
Locul Elevul Clasa Municipiul/Raionul Institutia Profesorul Conducatorul echipei
3 apoval Nicolae 9 Chiinu Liceul Teoretic "Orizont" (fil. Durlesti) Corlat Sergiu Golubev Svetlana
Mentiune Spnu Dorin 11 Fleti Liceul Teoretic "M. Eminescu" Mitric Lilian Beior Natalia
Mentiune Bolboceanu Mariana 12 Leova Liceul Teoretic "C. Sptaru" Cernea Natalia Carafizi Aliona
Mentiune Dolgolev Filip 9 Tiraspol Liceul Teoretic Tiraspol agoian Tamara Arma Marina
Mentiune Adascliei Cristian 9 Drochia Liceul Teoretic "M. Eminescu" Chistruga Gheorghe Chistruga Gheorghe
Mentiune Cataraga Victor 12 Nisporeni Liceul Teoretic "Boris Cazacu" Brodicico Valeriu Brodicico Valeriu
Mentiune Marievschi Alexandru 9 Ungheni Liceul Teoretic "A. Mateevici", Prlia Ciuperc Romeo Protasova Lucreia
Mentiune Trandafil Nicolai 11 U.T.A.G. Liceul Teoretic "B. Ianacoglo" Copceac Arfanos Maria Chilimicenco Serghei
Mentiune Balan Denis 8 Streni Liceul Teoretic. "I. Vatamanu" Gaidu Maria irdea lIdia
Mentiune Antohi Radu 12 Chiinu Liceul Teoretic "Orizont" (fil. Durlesti) Corlat Sergiu Golubev Svetlana
Mentiune Romanciuc Alexandru 12 Chiinu Liceul Teoretic "V. Alecsandri" Vanovscaia Vera Golubev Svetlana
Mentiune Mogoreanu Anatolie 11 Chiinu Liceul Teoretic "Titu Maiorescu" Vd Serghei Golubev Svetlana
Mentiune Gorpinevici Vlad 7 Chiinu Liceul Teoretic "Iulia Hadeu" urcanu Ludmila Golubev Svetlana