Sunteți pe pagina 1din 50

Olimpiada republican

la Informatic

Ediia 2004

Ziua 1
Clasele 7 - 9

Dreptunghiuri
Se consider n dreptunghiuri D1, D2, ..., Di, ..., Dn care au laturile paralele cu axele de
coordonate, iar coordonatele vrfurilor snt numere naturale. Fiecare dreptunghi Di,
i = 1, 2, 3, ..., n , este definit prin tuplul (ai , bi , ci , d i ) , unde ai, bi snt coordonatele colului
stnga-jos, iar ci, di coordonatele colului dreapta-sus (fig. 1).
Elaborai un program care determin aria S a figurii obinute prin reuniunea celor n
dreptunghiuri.

Fig. 1

Date de intrare. Fiierul text DREPT.IN conine pe prima linie numrul natural n.
Fiecare din urmtoarele n linii ale fiierului de intrare conine cte patru numere naturale
separate prin spaiu. Linia i + 1 a fiierului de intrare conine numerele naturale ai, bi, ci, di.
Date de ieire. Fiierul text DREPT.OUT va conine pe o singur linie numrul natural
S.
Exemplu.
DREPT.IN
2
1 1 5 5
4 3 7 4

DREPT.OUT
18

Restricii. 0 ai , bi , ci , d i 500 , i = 1, 2, 3, ..., n ; 1 n 50 . Timpul de execuie nu


va depi o secund. Fiierul surs va avea denumirea DREPT.PAS, DREPT.C sau
DREPT.CPP.

Rezolvare
Conform restriciilor din enunul problemei, toate dreptunghiurile D1, D2, ..., Dn se afl
n interiorul dreptunghiului (0, 0, 1000, 1000). ntruct coordonatele vrfurilor acestor
dreptunghiuri snt numere naturale, putem introduce n studiu un rastru (fig. 2), liniile cruia
formeaz microzonele:
(0, 0, 1, 1); (1, 0, 2, 1), ..., ( j , k , j + 1, k + 1) , ..., (499, 499, 500, 500).

Fig. 2

Din fig. 2 se observ, c aria figurii formate prin reuniunea dreptunghiurilor D1, D2, ...,
Dn poate fi calculat prin verificarea apartenenei fiecreia din microzonele ( j , k , j + 1, k + 1)
la cel puin unul din dreptunghiurile n studiu. Evident, microzona ( j , k , j + 1, k + 1) aparine
dreptunghiului (ai , bi , ci , d i ) atunci i numai atunci cnd se respect urmtoarele condiii:
j ai ; j + 1 ci ; k bi ; k + 1 d i .
n programul ce urmeaz apartenena microzonei ( j , k , j + 1, k + 1) la cel puin unul din
dreptunghiurile D1, D2, ..., Dn se verific cu ajutorul funciei Apartine.
Program Dreptunghiuri;
{ Clasele 7-9 }
var n : integer;
A, B, C, D : array[1..50] of integer;
S : longint;
Intrare, Iesire : text;
procedure Citire;
{ Citirea datelor din fisierul de intrare }
var i : integer;
begin
assign(Intrare, 'DREPT.IN');
reset(Intrare);

readln(Intrare, n);
for i:=1 to n do
readln(Intrare, A[i], B[i], C[i], D[i]);
close(Intrare);
end; { Citire }
procedure Scrie;
{ Scrierea datelor in fisierul de iesire }
begin
assign(Iesire, 'DREPT.OUT');
rewrite(Iesire);
writeln(Iesire, S);
close(Iesire);
end; { Scrie }
function Apartine(j, k : integer) : boolean;
{ Verifica apartenenta microzonei (j, k, j+1, k+1) }
{ la cel putin unul din dreptunghiurile D[1] .. D[n] }
var i : integer;
q : boolean;
begin
q:=false;
for i:=1 to n do
if ((j>=A[i]) and ((j+1)<=C[i]) and (k>=B[i]) and ((k+1)<=D[i]))
then q:=true;
Apartine:=q;
end; { Apartine }
procedure Aria;
{ Calculeaza aria S }
var j, k : integer;
begin
S:=0;
for j:=0 to 499 do
for k:=0 to 499 do
if Apartine(j, k) then S:=S+1;
end; { Aria }
begin
Citire;
Aria;
Scrie;
end.

Din analiza textului procedurii Aria se observ c funcia Apartine va fi apelat de


500 500 = 2,5 10 5 ori. La rndul su, operatorul if din interiorul ciclului for al funciei
Apartine va fi executat de 50 de ori. Prin urmare, numrul necesar de operaii este de
ordinul 2,5 10 5 50 = 1,25 10 7 , mrime comparabil cu capacitatea de prelucrare a
calculatoarelor din laboratorul de informatic. Menionm, c timpul de calcul poate fi redus
substanial prin folosirea unui rastru neuniform.

Strunguri
Se consider dou strunguri identice destinate prelucrrii automate a unor piese.
Strungurile funcioneaz independent unul de altul. n procesul prelucrrii piesele snt
avansate ctre strunguri cu ajutorul unei benzi rulante (vezi fig. 1).
n

...

1
Strungul 1

Strungul 2

Fig. 1

Piesele de prelucrat snt numerotate n ordinea apariiei lor pe band prin numerele
naturale 1, 2, 3, ..., n. Pentru fiecare pies i se cunoate timpul di necesar pentru prelucrarea ei
pe unul din cele dou strunguri.
Elaborai un program care calculeaz timpul Q necesar pentru a prelucra toate piesele.
Date de intrare. Fiierul text STRUNG.IN conine pe prima linie numrul natural n.
Fiecare din urmtoarele n linii ale fiierului de intrare conine cte un numr natural. Linia
i + 1 a fiierului de intrare conine numrul natural di timpul necesar pentru prelucrarea
piesei i pe unul din cele dou strunguri.
Date de ieire. Fiierul text STRUNG.OUT va conine pe o singur linie numrul natural
Q timpul necesar pentru a prelucra toate piesele.
Exemplu.
STRUNG.IN
5
3
1
1
2
1

STRUNG.OUT
4

Restricii. 1 n 1000 ; 1 d i 30 , i = 1, 2, 3, ..., n . Timpul de execuie nu va depi o


secund. Fiierul surs va avea denumirea STRUNG.PAS, STRUNG.C sau STRUNG.CPP.

Rezolvare
Vom calcula timpul Q prin simularea procesului de funcionare independent a celor
dou strunguri. Pentru aceasta introducem n studiu urmtoarele variabile:
t momentele de timp n care cel puin unul din strunguri devine liber. Iniial t = 0 .
s1 (s2) timpul necesar strungului 1 (strungului 2) pentru a termina prelucrarea piesei
curente. Iniial s1 = 0, s 2 = 0 .
j numrul piesei de la ieirea benzii rulante. Iniial j = 1 .
Evident, strungul k, k {1, 2} , este liber numai atunci cnd s k = 0 . Procesele de
alimentarea a acestui strung se simuleaz prin atribuirile:
sk : = d j ; j : = j + 1 .

Momentele de timp t n care cel puin unul din strunguri devine liber se calculeaz cu
ajutorul formulei recurente:

t : = t + s min , unde s min = min(s1 , s 2 ) .


ncepnd cu momentul t, timpul necesar pentru a termina prelucrrile pieselor curente se
calculeaz ca:

s1 : = s1 s min ;
s 2 : = s 2 s min .
Procesul de calcul continu pn cnd va fi ncrcat ultima pies de pe banda rulant
sau, prin alte cuvinte, cnd j devine mai mare ca n. Evident, ncepnd cu acest moment de
timp, vor mai fi necesare nc s max secunde pentru ca strungurile s termine prelucrarea
pieselor deja ncrcate. Prin urmare,
Q : = t + s max , unde s max = max(s1 , s 2 ) .
n programul ce urmeaz simularea procesului de funcionare a strungurilor este realizat
cu ajutorul procedurii Simulare.
Program Strunguri;
{ Clasele 7-9 }
const nmax=1000;
var n : integer;
D : array[1..nmax] of integer;
Q : integer;
Intrare, Iesire : text;
procedure Citire;
{ Citirea datelor din fisierul de intrare }
var i : integer;
begin
assign(Intrare, 'STRUNG.IN');
reset(Intrare);
readln(Intrare, n);
for i:=1 to n do
readln(Intrare, D[i]);
close(Intrare);
end; { Citire }

procedure Scrie;
{ Scrierea datelor in fisierul de iesire }
begin
assign(Iesire, 'STRUNG.OUT');
rewrite(Iesire);
writeln(Iesire, Q);
close(Iesire);
end; { Scrie }
procedure Simulare;
{ Simularea prelucrarilor }
label 1;
var t, j, s1, s2, smin, smax : integer;
begin
t:=0;
j:=1;
s1:=0; s2:=0;
repeat
{ Alimentarea strungurilor libere }
if s1=0 then
begin
s1:=D[j];
j:=j+1;
if j>n then goto 1;
end;
if s2=0 then
begin
s2:=D[j];
j:=j+1;
if j>n then goto 1;
end;
{ Calcularea momentului de timp t }
if s1<s2 then smin:=s1 else smin:=s2;
t:=t+smin;
{ Calcularea duratelor s1, s2 }
s1:=s1-smin;
s2:=s2-smin;
until false;
1:
if s1>s2 then smax:=s1 else smax:=s2;
Q:=t+smax;
end; { Simulare }
begin
Citire;
Simulare;
Scrie;
end.

Din analiza textului procedurii Simulare se observ c timpul Q se calculeaz printr-o


singur parcurgere a tabloului D. Prin urmare, numrul necesar de operaii este de ordinul
O(n), iar timpul de execuie va fi cu mult mai mic dect o secund.

Unitai
Se consider mulimea tuturor irurilor binare de lungimea n. Aceste iruri pot fi
reprezentate n forma:
Poziia

n-2

n-1

irul binar

x1

x2

x3

xn-2

xn-1

xn

unde x1 , x 2 , ..., x n {0, 1} . Scriei un program care calculeaz numrul k de iruri de lungimea
n n care unitile nu apar pe poziii vecine.
De exemplu, mulimea tuturor irurilor binare de lungimea n = 3 este:
{000, 001, 010, 011, 100, 101, 110, 111}.
Se observ, c unitile nu apar pe poziii vecine numai n irurile {000, 001, 010, 100, 101}.
Prin urmare k = 5.
Date de intrare. Fiierul text UNITATI.IN conine pe o singur linie numrul natural
n.
Date de ieire. Fiierul text UNITATI.OUT va conine pe o singur linie numrul
natural k.
Exemplu.
UNITATI.IN
3

UNITATI.OUT
5

Restricii. 3 n 40 . Timpul de execuie nu va depi 1 secund. Fiierul surs va


avea denumirea UNITATI.PAS, UNITATI.C sau UNITATI.CPP.

Rezolvare
Fie f (i ) numrul de iruri binare de lungimea i n care unitile nu apar pe poziii
vecine. Prin calcule directe ne putem convinge c f (1) = 2 , f ( 2) = 3 i f (3) = 5 .
Vom diviza mulimea tuturor irurilor binare de lungimea i n dou submulimi: A submulimea irurilor ce au n ultima poziie cifra binara 0 i B - submulimea irurilor ce au
n ultima poziie cifra binara 1.
n cazul submulimii A irurile respective pot fi reprezentate n forma:
Poziia

i-2

i-1

irul binar

x1

x2

x3

xi-2

xi-1

Evident, numrul de iruri din mulimea A ce corespund enunului problemei este egal cu
f (i 1) .
n cazul submulimii B irurile respective pot fi reprezentate n forma:
Poziia

i-2

i-1

irul binar

x1

x2

x3

xi-2

xi-1

Evedent, condiiilor problemei corespund numai irurile n care pe poziia i-1 se afl cifra
zero:
Poziia

i-2

i-1

irul binar

x1

x2

x3

xi-2

iar numrul acestor iruri este egal cu f (i 2) .


Prin urmare,
f (i ) = f (i 2) + f (i 1) .

n programul ce urmeaz numerele f (3) , f ( 4) , f (5) , ..., f (i ) , ..., f (n) snt calculate
prin metoda iteraiilor:
f (1) = 2 ;
f ( 2) = 3 ;
f (3) = f (1) + f ( 2) = 2 + 3 = 5 ;
f (4) = f ( 2) + f (3) = 3 + 5 = 8;
f (5) = f (3) + f ( 4) = 5 + 8 = 13;
...
f (i ) = f (i 2) + f (i 1) ;
...
f ( n) = f ( n 2) + f ( n 1) .

Menionm, c irul de numere 2, 3, 5, 8, 13, ..., n care numrul curent f (i ) este egal
cu suma celor dou numere precedente f (i 2) i f (i 1) este cunoscut n literatura de
specialitate sub numele irul lui Fibonacci.
10

Program Unitati;
{ Clasele 7-9 }
var n, i : integer;
fi, fi1, fi2 : longint;
{ fi numarul curent din sirul Fibonacci }
{ fi1, fi2 numerele precedente din sir }
Intrare, Iesire : text;
begin
assign(Intrare, 'UNITATI.IN');
reset(Intrare);
readln(Intrare, n);
close(Intrare);
fi1:=2;
fi2:=3;
for i:=3 to n do
begin
fi:=fi1+fi2;
fi1:=fi2;
fi2:=fi;
end;
assign(Iesire, 'UNITATI.OUT');
rewrite(Iesire);
writeln(Iesire, fi);
close(Iesire);
end.

Din analiza textului programului se observa ca instruciunile din corpul ciclului vor fi
executate de ( n 2) ori. Prin urmare, timpul de execuie a programului va fi cu mult mai mic
dect o secund.

11

Ziua 1
Clasele 10 12

12

Dreptunghiuri
Se consider n dreptunghiuri D1, D2, ..., Di, ..., Dn care au laturile paralele cu axele de
coordonate, iar coordonatele vrfurilor snt numere naturale. Fiecare dreptunghi Di,
i = 1, 2, 3, ..., n , este definit prin tuplul (ai , bi , ci , d i ) , unde ai, bi snt coordonatele colului
stnga-jos, iar ci, di coordonatele colului dreapta-sus (fig. 1).
Elaborai un program care determin aria S a figurii obinute prin reuniunea celor n
dreptunghiuri.

Fig. 1

Date de intrare. Fiierul text DREPT.IN conine pe prima linie numrul natural n.
Fiecare din urmtoarele n linii ale fiierului de intrare conine cte patru numere naturale
separate prin spaiu. Linia i + 1 a fiierului de intrare conine numerele naturale ai, bi, ci, di.
Date de ieire. Fiierul text DREPT.OUT va conine pe o singur linie numrul
natural S.
Exemplu.
DREPT.IN
2
1 1 5 5
4 3 7 4

DREPT.OUT
18

Restricii. 0 a i , bi , ci , d i 10 000 , i = 1, 2, 3, ..., n ; 1 n 100 . Timpul de execuie


nu va depi o secund. Fiierul surs va avea denumirea DREPT.PAS, DREPT.C sau
DREPT.CPP.

13

Rezolvare
Conform restriciilor din enunul problemei, toate dreptunghiurile D1, D2, ..., Dn se afl
n interiorul dreptunghiului (0, 0, 10000, 10000). ntruct coordonatele vrfurilor acestor
dreptunghiuri snt numere naturale, putem introduce n studiu un rastru (fig. 2), liniile cruia
formeaz microzonele:
(0, 0, 1, 1); (1, 0, 2, 1), ..., ( j , k , j + 1, k + 1) , ..., (9999, 9999, 10000, 10000).

Fig. 2

Din fig. 2 se observ, c aria figurii formate prin reuniunea dreptunghiurilor D1, D2, ...,
Dn poate fi calculat prin verificarea apartenenei fiecreia din microzonele ( j , k , j + 1, k + 1)
la cel puin unul din dreptunghiurile n studiu. Evident, microzona ( j , k , j + 1, k + 1) aparine
dreptunghiului (ai , bi , ci , d i ) atunci i numai atunci cnd se respect urmtoarele condiii:
j ai ; j + 1 ci ; k bi ; k + 1 d i .
Complexitatea temporal a unui astfel de algoritm este de ordinul
10 000 10 000 100 = 1010 , mrime care depete capacitatea de prelucrare a calculatoarelor
din laboratorul de informatic.
Pentru a micora numrul microzonelor examinate, vom utiliza n loc de rastrul
tradiional, un rastru neuniform, liniile orizontale i verticale ale cruia reprezint prelungirile
laturilor respective ale dreptunghiurilor D1, D2, ..., Dn (fig. 3). n memoria calculatorului un
astfel de rastru poate fi reprezentat cu ajutorul mulimilor:
X = {a1 , c1 } { a 2 , c 2 } ... {a n , c n } ;
Y = {b1 , d1 } {b2 , d 2 } ... {bn , d n } .
Pentru a simplifica procesul de triere a microzonelor, vom sorta aceste mulimi n ordine
cresctoare.

14

Fig. 3

Din fig. 3 se observ c microzonele z1 , z 2 , z 3 .a.m.d. ale rastrului reprezint, n


general, dreptunghiuri de dimensiuni ce difer, iar aria S poate fi calculat nsumn ariile
microzonelor ce aparin la cel puin unul din dreptunghiurile D1, D2, ..., Dn.
Fiecare microzon z poate fi identificat ntr-un mod univoc cu ajutorul unui tuplului
( j z , k z , l z , m z ) , unde j z , k z , snt coordonatele colului stnga-jos, iar l z , m z coordonatele
colului dreapta-sus. Evident, microzona ( j z , k z , l z , m z ) aparine dreptunghiului
(ai , bi , ci , d i ) atunci i numai atunci cnd se respect urmtoarele condiii:
j z ai ; l z ci ; k z bi ; m z d i .
n programul ce urmeaz apartenena microzonei ( j z , k z , l z , m z ) la cel puin unul din
dreptunghiurile D1, D2, ..., Dn se verific cu ajutorul funciei Apartine.
Program Dreptunghiuri;
{ Clasele 10-12 }
var n : longint;
A, B, C, D : array[1..100] of longint;
S : longint;
Intrare, Iesire : text;
{ X - abcisele rastrului }
X : array[1..200] of longint;
nx : longint;
{ Y - ordonatele rastrului }
Y : array[1..200] of longint;
ny : longint;
procedure Citire;
{ Citirea datelor din fisierul de intrare }
var i : longint;
begin
assign(Intrare, 'DREPT.IN');
reset(Intrare);

15

readln(Intrare, n);
for i:=1 to n do
readln(Intrare, A[i], B[i], C[i], D[i]);
close(Intrare);
end; { Citire }
procedure Scrie;
{ Scrierea datelor in fisierul de iesire }
begin
assign(Iesire, 'DREPT.OUT');
rewrite(Iesire);
writeln(Iesire, S);
close(Iesire);
end; { Scrie }
function Apartine(j, k, l, m : longint) : boolean;
{ Verifica apartenenta microzonei (j, k, l, m) }
{ la cel putin unul din dreptunghiurile D[1] .. D[n] }
var i : longint;
q : boolean; { indicator "apartine" }
begin
q:=false;
for i:=1 to n do
if ((j>=A[i]) and (l<=C[i]) and (k>=B[i]) and (m<=D[i]))
then q:=true;
Apartine:=q;
end; { Apartine }
procedure Abcisele;
{ Returneaza in vectorul X abcisele rastrului }
var i, t, p : longint;
q : boolean; { indicator "abcisa se repeta" }
begin
{ Copiem in vectorul X abcisele A[i] }
nx:=0;
for i:=1 to n do
begin
q:=false;
for t:=1 to nx do
if A[i]=X[t] then q:=true;
if (not q) then
begin nx:=nx+1; X[nx]:=A[i]; end;
end;
{ Copiem in vectorul X abcisele C[i] }
for i:=1 to n do
begin
q:=false;
for t:=1 to nx do
if C[i]=X[t] then q:=true;
if (not q) then
begin nx:=nx+1; X[nx]:=C[i]; end;
end;
{ Sortam elementele vectorului X }
for i:=1 to nx do
for t:=1 to nx-1 do
if X[t]>X[t+1] then
begin p:=X[t]; X[t]:=X[t+1]; X[t+1]:=p; end;

16

end; { Abcisele }
procedure Ordonatele;
{ Returneaza in vectorul Y ordonatele rastrului }
var i, t, p : longint;
q : boolean; { indicator "ordonata se repeta" }
begin
{ Copiem in vectorul Y ordonatele B[i] }
ny:=0;
for i:=1 to n do
begin
q:=false;
for t:=1 to ny do
if B[i]=Y[t] then q:=true;
if (not q) then
begin ny:=ny+1; Y[ny]:=B[i]; end;
end;
{ Copiem in vectorul Y ordonatele D[i] }
for i:=1 to n do
begin
q:=false;
for t:=1 to ny do
if D[i]=Y[t] then q:=true;
if (not q) then
begin ny:=ny+1; Y[ny]:=D[i]; end;
end;
{ Sortam elementele vectorului Y }
for i:=1 to ny do
for t:=1 to ny-1 do
if Y[t]>Y[t+1] then
begin p:=Y[t]; Y[t]:=Y[t+1]; Y[t+1]:=p; end;
end; { Ordonatele }
procedure Aria;
{ Calculeaza aria S }
var p, t : longint;
begin
Abcisele;
Ordonatele;
S:=0;
for p:=1 to nx-1 do
for t:=1 to ny-1 do
if Apartine(X[p], Y[t], X[p+1], Y[t+1])
then S:=S+(X[p+1]-X[p])*(Y[t+1]-Y[t]);
end; { Aria }
begin
Citire;
Aria;
Scrie;
end.

ntruct mulimile X i Y conin cte cel mult 2n elemente, complexitatea temporal a


procedurilor Abcisele i Ordonatele este O(n 2 ) . Complexitatea temporal a funciei
Apartine este O (n) , iar a procedurii Aria O (n 3 ) . Conform restriciilor din enunul
17

problemei, n 100 . Prin urmare, numrul necesar de operaii este de ordinul 10 6 , mrime
comparabil cu capacitatea de prelucrare a calculatoarelor din laboratorul de informatic.

18

Strunguri
Se consider m strunguri identice destinate prelucrrii automate a unor piese.
Strungurile funcioneaz independent unul de altul. n procesul prelucrrii piesele snt
avansate ctre strunguri cu ajutorul unei benzi rulante (vezi fig. 1).

...

Strungul 1

Strungul 2

...

Strungul m
Fig. 1

Piesele de prelucrat snt numerotate n ordinea apariiei lor pe band prin numerele
naturale 1, 2, 3, ..., n. Pentru fiecare pies i se cunoate timpul di necesar pentru prelucrarea ei
pe unul din cele m strunguri.
Elaborai un program care calculeaz timpul Q necesar pentru a prelucra toate piesele.
Date de intrare. Fiierul text STRUNG.IN conine pe prima linie numerele naturale m
i n, separate prin spaiu. Fiecare din urmtoarele n linii ale fiierului de intrare conine cte un
numr natural. Linia i + 1 a fiierului de intrare conine numrul natural di timpul necesar
pentru prelucrarea piesei i pe unul din cele m strunguri.
Date de ieire. Fiierul text STRUNG.OUT va conine pe o singur linie numrul natural
Q timpul necesar pentru a prelucra toate piesele.
Exemplu.
STRUNG.IN
3 10
1
2
3
9
7
5
2
3
4
6

STRUNG.OUT
16

Restricii. 2 m 100 ; 1 n 1000 ; 1 d i 30 , i = 1, 2, 3, ..., n . Timpul de execuie


nu va depi o secund. Fiierul surs va avea denumirea STRUNG.PAS, STRUNG.C sau
STRUNG.CPP.

19

Rezolvare
Vom calcula timpul Q prin simularea procesului de funcionare independent a celor m
strunguri. Pentru aceasta introducem n studiu urmtoarele variabile:
t momentele de timp n care cel puin unul din strunguri devine liber. Iniial t = 0 .
sk timpul necesar strungului k ( k = 1, 2, ..., m) pentru a termina prelucrarea piesei
curente. Iniial s k = 0 .
j numrul piesei de la ieirea benzii rulante. Iniial j = 1 .
Evident, strungul k, k {1, 2, ..., m} , este liber numai atunci cnd s k = 0 . Procesele de
alimentarea a acestui strung se simuleaz prin atribuirile:
sk : = d j ; j : = j + 1 .

Momentele de timp t n care cel puin unul din strunguri devine liber se calculeaz cu
ajutorul formulei recurente:

t : = t + s min , unde s min = min( s1 , s 2 , ..., s m ) .


ncepnd cu momentul t, timpul necesar pentru a termina prelucrrile pieselor curente se
calculeaz ca:
s k : = s k s min , k = 1, 2, ..., m .
Procesul de calcul continu pn cnd va fi ncrcat ultima pies de pe banda rulant
sau, prin alte cuvinte, cnd j devine mai mare ca n. Evident, ncepnd cu acest moment de
timp, vor mai fi necesare nc s max secunde pentru ca strungurile s termine prelucrarea
pieselor deja ncrcate. Prin urmare,
Q : = t + s max , unde s max = max(s1 , s 2 , ..., s k ) .
n programul ce urmeaz simularea procesului de funcionare a strungurilor este realizat
cu ajutorul procedurii Simulare.
Program Strunguri;
{ Clasele 7-9 }
const mmax=100;
nmax=1000;
var m, n : integer;
D : array[1..nmax] of integer;
S : array[1..mmax] of integer;
Q : integer;
Intrare, Iesire : text;
procedure Citire;
{ Citirea datelor din fisierul de intrare }
var i : integer;
begin
assign(Intrare, 'STRUNG.IN');
reset(Intrare);
readln(Intrare, m, n);
for i:=1 to n do
readln(Intrare, D[i]);
close(Intrare);
end; { Citire }

20

procedure Scrie;
{ Scrierea datelor in fisierul de iesire }
begin
assign(Iesire, 'STRUNG.OUT');
rewrite(Iesire);
writeln(Iesire, Q);
close(Iesire);
end; { Scrie }
function ElementulMinimal : integer;
{ Returneaza elementul minimal din tabloul S }
var a, k : integer;
begin
a:=S[1];
for k:=1 to m do
if S[k]<a then a:=S[k];
ElementulMinimal:=a;
end; { ElementulMinimal }
function ElementulMaximal : integer;
{ Returneaza elementul maximal din tabloul S }
var b, k : integer;
begin
b:=S[1];
for k:=1 to m do
if S[k]>b then b:=S[k];
ElementulMaximal:=b;
end; { ElementulMaximal }
procedure Simulare;
{ Simularea prelucrarilor }
label 1;
var t, j, k, smin, smax : integer;
begin
t:=0;
j:=1;
for k:=1 to m do
S[k]:=0;
repeat
{ Alimentarea strungurilor libere }
for k:=1 to m do
if S[k]=0 then
begin
S[k]:=D[j];
j:=j+1;
if j>n then goto 1;
end;
{ Calcularea momentului de timp t }
smin:= ElementulMinimal;
t:=t+smin;
{ Calcularea duratelor s1, s2 }
for k:=1 to m do
S[k]:=S[k]-smin;
until false;
1:

21

smax:= ElementulMaximal;
Q:=t+smax;
end; { Simulare }
begin
Citire;
Simulare;
Scrie;
end.

Din analiza textului procedurii Simulare se observ c timpul Q se calculeaz printr-o


singur parcurgere a tabloului D, iar determinarea elementului minimal i a elementului
maximal necesit o singur parcurgere a tabloului S. Prin urmare, numrul necesar de operaii
este de ordinul O(nm), iar timpul de execuie va fi cu mult mai mic dect o secund.

22

Unitai
Se consider mulimea tuturor irurilor binare de lungimea n. Aceste iruri pot fi
reprezentate n forma:
Poziia

n-2

n-1

irul binar

x1

x2

x3

xn-2

xn-1

xn

unde x {0, 1} . Scriei un program care calculeaz numrul k de iruri de lungimea n n care
unitile nu apar pe poziii vecine.
De exemplu, mulimea tuturor irurilor binare de lungimea n = 3 este:
{000, 001, 010, 011, 100, 101, 110, 111}.
Se observ, c unitile nu apar pe poziii vecine numai n irurile {000, 001, 010, 100, 101}.
Prin urmare k = 5.
Date de intrare. Fiierul text UNITATI.IN conine pe o singur linie numrul
natural n.
Date de ieire. Fiierul text UNITATI.OUT va conine pe o singur linie numrul
natural k.
Exemplu.
UNITATI.IN
3

UNITATI.OUT
5

Restricii. 3 n 100 . Timpul de execuie nu va depi o secund. Fiierul surs va


avea denumirea UNITATI.PAS, UNITATI.C sau UNITATI.CPP.

23

Rezolvare
Fie f (i ) numrul de iruri binare de lungimea i n care unitile nu apar pe poziii
vecine. Prin calcule directe ne putem convinge c f (1) = 2 , f ( 2) = 3 i f (3) = 5 .
Vom diviza mulimea tuturor irurilor binare de lungimea i n dou submulimi: A submulimea irurilor ce au n ultima poziie cifra binara 0 i B - submulimea irurilor ce au
n ultima poziie cifra binara 1.
n cazul submulimii A irurile respective pot fi reprezentate n forma:
Poziia

i-2

i-1

irul binar

x1

x2

x3

xi-2

xi-1

Evident, numrul de iruri din mulimea A ce corespund enunului problemei este egal cu
f (i 1) .
n cazul submulimii B irurile respective pot fi reprezentate n forma:
Poziia

i-2

i-1

irul binar

x1

x2

x3

xi-2

xi-1

Evedent, condiiilor problemei corespund numai irurile n care pe poziia i-1 se afl cifra
zero:
Poziia

i-2

i-1

irul binar

x1

x2

x3

xi-2

iar numrul acestor iruri este egal cu f (i 2) .


Prin urmare,
f (i ) = f (i 2) + f (i 1) .

n programul ce urmeaz numerele f (3) , f ( 4) , f (5) , ..., f (i ) , ..., f (n) snt calculate
prin metoda iteraiilor:
f (1) = 2 ;
f ( 2) = 3 ;
f (3) = f (1) + f ( 2) = 2 + 3 = 5 ;
f (4) = f ( 2) + f (3) = 3 + 5 = 8;
f (5) = f (3) + f ( 4) = 5 + 8 = 13;
...
f (i ) = f (i 2) + f (i 1) ;
...
f ( n) = f ( n 2) + f ( n 1) .

Menionm, c irul de numere 2, 3, 5, 8, 13, ..., n care numrul curent f (i ) este egal
cu suma celor dou numere precedente f (i 2) i f (i 1) este cunoscut n literatura de
specialitate sub numele irul lui Fibonacci.
24

Program Unitati;
{ Clasele 10-12 }
{ Erori de depasire pentru n >= 45 }
var n, i : integer;
fi, fi1, fi2 : longint;
{ fi numarul curent din sirul Fibonacci }
{ fi1, fi2 numerele precedente din sir }
Intrare, Iesire : text;
begin
assign(Intrare, 'UNITATI.IN');
reset(Intrare);
readln(Intrare, n);
close(Intrare);
fi1:=2;
fi2:=3;
for i:=3 to n do
begin
fi:=fi1+fi2;
fi1:=fi2;
fi2:=fi;
end;
assign(Iesire, 'UNITATI.OUT');
rewrite(Iesire);
writeln(Iesire, fi);
close(Iesire);
end.

ntruct complexitatea temporal a programului n studiu este de ordinul n, iar n 100 ,


timpul de execuie va fi mai mic dect o secund.
n procesul depanrii programului se observ c n cazul variabilelor fi, fi1 i fi2,
pentru valori n 45 , apar erori de depire. Aceste erori pot fi evitate prin reprezentarea
numerelor foarte mari cu ajutorul unor structuri de date mai complexe i elaborarea
subprogramelor ce simuleaz adunarea numerelor respective. Una din soluiile posibile const
n reprezentarea numerelor foarte mari prin tablouri, fiecare element al tabloului reprezentnd
cte o cifr. n acest reprezentare, operaiea de adunare a numerelor foarte mari se reduce la
adunarea cifrelor respective i calcularea transportului.
Program Unitati;
{Clasele 10-12}
var
{Pentru modelearea adunarii numerelor intregi foarte mari vor fi
folosite tablourile A,B,C}
A,B,C : array [1..1000] of integer;
n,i,j,t,ka,kb,kc:integer;
Intrare, Iesire:text;
begin
assign(Intrare,'UNITATI.IN');
reset(Intrare);
read(Intrare,n);
close(Intrare);
assign(Iesire,'UNITATI.OUT');
rewrite(Iesire);
ka:=1; A[1]:=2; kb:=1; b[1]:=3;
for i:=3 to n do

25

begin {Modelarea sumelor pentru numere mari}


t:=0;
for j:=1 to ka do
begin
t:=t+A[j]+B[j];
C[j]:= t mod 10;
t:=t div 10;
end;
for j:=ka+1 to kb do
begin
t:=t+B[j];
C[j]:=t mod 10;
t:=t div 10;
end;
kc:=kb;
if t>0 then begin kc:=kc+1; C[kc]:=t; end;
ka:=kb; A:=B;{fi1:=fi2}
kb:=kc; B:=C;{fi2:=fi}
end;
for i:=kc downto 1 do write(Iesire,C[i]);
close(Iesire);
end.

26

Ziua 2
Clasele 7 9

27

Depozitul
Pentru pstrarea n siguran a unor cantiti mari de substane radioactive, ntr-o regiune
ndeprtat a fost construit un depozit subteran. Depozitul este format dintr-o reea de tuneluri la
intersecia crora se afl zone de depozitare. Orice zon de depozitare poate fi liber sau ocupat de
containere cu substane radioactive. Tunelurile depozitului formeaz un caroiaj, iar distana dintre
oricare dou zone vecine este egal cu 1 (vezi fig. 1).

Fig. 1
Tunelurile care merg n direcia est-vest snt numerotate prin 1, 2, 3, ..., m, iar cele n direcia
nord-sud prin 1, 2, 3, ..., n. Fiecare zon de depozitare se identific printr-o adres unic de forma (i,
j), unde i este numrul tunelului est-vest, iar j al celui nord-sud, la intersecia crora se afl zona
respectiv.
Prin coridoare i prin zonele de depozitare se deplaseaz un robot. Robotul poate trece printr-o
zon de depozitare numai atunci cnd ea este liber. Se consider c indiferent de zona de plecare,
robotul poate ajunge n oricare alt zon liber a depozitului.
Elaborai un program care cunoscnd adresele zonelor ocupate, calculeaz lungimea L a celui
mai scurt drum ce trebuie parcurs de robot pentru a ajunge din zona (a, b) n zona (c, d). Distanele
parcurse de robot n interiorul zonelor de depozitare nu vor fi luate n consideraie.
Date de intrare. Fiierul text DEPOZIT.IN conine pe prima linie numerele naturale m, n
separate prin spaiu. Linia a doua a fiierului de intrare conine numerele naturale a, b adresa zonei
de plecare, iar linia a treia numerele naturale c, d adresa zonei de sosire. Linia a patra a fiierului de
intrare conine numrul natural k numrul zonelor ocupate de containerele cu substane radioactive.
Urmtoarele k linii ale fiierului de intrare conin cte dou numere naturale i, j adresele zonelor
ocupate.
Date de ieire. Fiierul text DEPOZIT.OUT va conine pe o singur linie numrul natural L.
Exemplu.
DEPOZIT.IN
4 5
2 2
3 5
7
1 3
1 4
1 5
2 5
3 2
3 3
4 5

DEPOZIT.OUT
4

Restricii. 1 m, n 100 ; 1 a, c m ; 1 b, d n ; 1 k 1 000 . Timpul de execuie nu


va depi 2 secunde. Fiierul surs va avea denumirea DEPOZIT.PAS, DEPOZIT.C sau
DEPOZIT.CPP.

28

Rezolvare
Pentru a determina lungimea celui mai scurt drum vom folosi metoda propagrii undei
numerice, cunoscut n literatura de specialitate ca algoritmul lui Lee. Introducem n studiu
tabloul Z = z ij , unde zij reprezint lungimea celui mai scurt drum de la zona (a, b) la zona
(i, j). Iniial zonele libere vor fi marcate n tabloul Z printr-o valoare negativ, de exemplu 1,
iar zonele ocupate prin alt valoare negativ, de exemplu, 2 (vezi fig. 2). Evident, zab = 0.

L=0

Tabloul iniial
1

L=1
4

1 1 2 2 2

1 1

2 2 2

2 2 2

1 0 1 1 2

1 1 2

1 2 2 1 1

1 2 2 1 1

2 2 2 1 1

1 1 1 1 2

1 1 1 1 2

1 1 1 1 2

L=2

2 2

L=3
4

2 2 2

2 2 2

2 2

2 2 2 3 1

2 2 2 3

3 1 1 1 2

2 2
4

4 1 4 2
Fig. 2

n continuare propagm prin zonele depozitului o und numeric L, unde L ia


consecutiv valorile 0, 1, 2, 3 .a.m.d. Pentru aceasta parcurgem iterativ tabloul Z i atribuim
valoarea L+1 elementelor ce corespund zonelor libere, vecine cu zona n care a ajuns unda
numeric L. Procesul iterativ se termin n momentul cnd unda numeric ajunge n celula (c,
d).
n programul ce urmeaz valorile iniiale ale tabloului Z snt stabilite cu ajutorul
procedurii Initializare. Pentru a simplifica analiza zonelor de la marginile depozitului,
n tabloul Z au fost incluse liniile 0, m+1 i coloanele 0, n+1 care formeaz un chenar, iar
elementelor respective li se atribuie valloarea 2 (zone ocupate). Unda numeric se propag
cu ajutorul procedurii UndaNumerica, iar lungimea celui mai scurt drum se scrie n fiierul
de ieire cu ajutorul procedurii Scrie.
Program Depozitul;
{Clasele 7-9 }
const mmax=100; nmax=100;
ocupata=-2; libera=-1;
var m, n, a, b, c, d : integer;
L : integer;
Z : array[0..mmax+1, 0..nmax+1] of integer;
Intrare, Iesire : text;

29

Procedure Initializare;
{ Initializarea tabloului Z }
var i, j : integer;
begin
for i:=1 to m do
for j:=1 to n do Z[i, j]:=libera;
for i:=0 to m+1 do
begin
Z[i, 0]:=ocupata;
Z[i, n+1]:=ocupata;
end;
for j:=0 to n+1 do
begin
Z[0, j]:=ocupata;
Z[m+1, j]:=ocupata;
end;
end; { Initializare }
Procedure Citire;
{ Citirea datelor din fisierul de intrare }
var i, j, k, q : integer;
begin
assign(Intrare, 'DEPOZIT.IN');
reset(Intrare);
readln(Intrare, m, n);
readln(Intrare, a, b);
readln(Intrare, c, d);
Initializare;
readln(Intrare, k);
for q:=1 to k do
begin
readln(Intrare, i, j);
Z[i, j]:=ocupata;
end;
close(Intrare);
end; { Citire }
Procedure Scrie;
{ Scrierea datelor in fisierul de iesire }
begin
assign(Iesire, 'DEPOZIT.OUT');
rewrite(Iesire);
writeln(Iesire, L);
close(Iesire);
end; { Scrie }
Procedure UndaNumerica;
{ Propagarea undei numerice }
var i, j : integer;
begin
Z[a, b]:=0;
L:=0;
while Z[c, d]=libera do
begin
for i:=1 to m do
for j:=1 to n do
if Z[i, j]=L then

30

begin
if Z[i-1, j]=libera
if Z[i, j-1]=libera
if Z[i+1, j]=libera
if Z[i, j+1]=libera
end; { then }
L:=L+1;
end; { while }
end; { UndaNumerica }

then
then
then
then

Z[i-1, j]:=L+1;
Z[i, j-1]:=L+1;
Z[i+1, j]:=L+1;
Z[i, j+1]:=L+1;

begin
Citire;
UndaNumerica;
Scrie;
end.

Din analiza textului procedurii UndaNumerica se observ c instruciunea if din


componena ciclurilor imbricate for va fi executat de mn ori. Corpul ciclului while va fi
executat de cel mult L ori, unde L este lungimea celui mai scurt drum din zona (a, b) n zona
(c, d). Evident, lungimea acestui drum nu poate depi lungimea total a tunelurilor
depozitului, deci L < mn . Prin urmare, n cel mai nefavorabil caz, numrul de execuii ale
instruciunii if va fi de ordinul m2n2.
Conform restriciilor din enunul problemei, m, n 100 . Prin urmare, numrul necesar
de operaii este de ordinul 108, mrime comparabil cu capacitatea de prelucrare a
calculatoarelor personale.

31

Ghicete numrul
Se consider urmtorul joc. Primul juctor este calculatorul, iar al doilea juctor eti
chiar tu. Calculatorul alege n mod aleator un numr natural x din intervalul nchis [m, n] . Tu
trebuie s ghiceti acest numr, adresnd calculatorului ct mai puine ntrebri de genul
Numrul ales se afla in intervalul nchis [a, b] ?, unde m a, b n . La fiecare ntrebare
calculatorul rspunde prin cuvntul "da" (true) sau "nu" (false).
Elaborai un program care ghicete numrul x.
Date de intrare. Fiier de intrare nu exist. Intervalul [m, n] poate fi aflat apelnd
procedura predefinit Interval:
procedure Interval(var m, n : integer);

care returneaz valorile m, n.


Pentru a pune ntrebri, putei apela funcia predefinit SeAflaIn:
function SeAflaIn(a, b : integer) : boolean;

care returneaz valoarea true dac a x b i false n caz contrar.


Pentru ca subprogramele Interval i SeAflaIn s fie accesibile, includei n
partea declarativ a programului de elaborat linia
uses Numere;

Unitatea de program Numere se afla n directorul ORI2004.


Date de ieire. Fiier de ieire nu exist. Pentru a comunica calculatorului numrul
ghicit x, apelai procedura predefinit NumarulGhicit:
procedure NumarulGhicit(x : integer);

Punctaj.
1. Programul care pune mai mult de 30 de ntrebri, nu va primi nici un punct.
2. Programul poate primi cel mult 10 puncte, dup cum urmeaz:
Dac numrul x din fiierul de ieire este corect, programul va primi 2 puncte.
Restul de pn la 8 puncte snt alocate n dependen de numrul total de ntrebri
adresate calculatorului (apeluri ale funciei SeAflaIn):
cu ct mai puine ntrebri vor fi adresate calculatorului, cu att mai multe
puncte va primi programul;
programul care va pune un numr minim de ntrebri va primi 8 puncte;
programul care va pune 30 de ntrebri nu va primi puncte suplimentare.
Exemplu. Presupunem, c apelul Interval(m, n) returneaz valorile m = 2 i n = 8.
Pentru a ghici numrul x, calculatorului i-au fost adresate urmtoarele ntrebri:
ntrebare
SeAflaIn(2, 5)
SeAflaIn(2, 3)
SeAflaIn(4, 4)

Rspuns
true
false
true

Prin urmare, se va executa apelul NumarulGhicit(4).


Restricii. 1 m, n 32 000 . Timpul de execuie nu va depi o secund. Fiierul surs
va avea denumirea GHICI.PAS, GHICI.C sau GHICI.CPP. Execuia programului va fi
ntrerupt dac calculatorului i vor fi adresate mai mult de 30 de ntrebri.
32

Rezolvare
Presupunem, c se dorete gsirea numrului x prin metoda trierii:
for i:= m to n do
if SeAflaIn(i, i) then begin x:=i; goto 1 end;
1: writeln(x);

Media numrului de ntrebri k adresate calculatorului n metoda trierii se determin


din relaia:
n m +1
.
k=
2

n condiiile problemei, 1 m, n 32 000 i k = 16 000 . Evident, acest fapt poate duce


la nclcarea restriciei referitoare la numrul de ntrebri, conform creia snt admise numai
valorile k 30 .
Pentru a elabora un algoritm ce minimizeaz media numrului de ntrebri k , vom
considera primul juctor ca o surs de informaie cu mulimea mesajelor posibile:
S = {s1 , s 2 , ..., s p } = {a, a + 1, a + 2, ..., b} ,

unde numrul de mesaje p = n m + 1.


Este cunoscut faptul, c cantitatea de informaie I dintr-un mesaj al unei surse cu p
mesaje posibile coincide cu media numrului minim de ntrebri k , necesare pentru
identificarea univoc a mesajelor. Procesul de identificare se realizeaz cu ajutorul unor
ntrebri standart, generate prin metoda dihotonomiei, i la care se rspunde prin "da" sau
"nu".
Algoritmul ce realizeaz metoda dihotonomiei include urmtoarele etape:
1. Introducem n studiu intervalul curent [a, b] . Iniial [a, b] = [ m, n] .
2. Divizm intervalul curent [a, b] n intervalele [a, c ] i [c + 1, b] . Pentru aceasta
calculm "mijlocul" intervalului [a, b] :
ba
c = a + Trunc (
),
2
unde Trunc este o funcie ce returneaz partea ntreag a argumentului (b a ) / 2 .
3. n continuare, n dependen de rspunsul la ntrebarea standard Numrul cutat se
afl n intervalul [a, c ] ?, desemnm ca interval curent unul din intervalele [a, c ] sau
[c + 1, b] .

4. Procesul de calcul continu pn cnd intervalul curent va conine numai un singur


numr.
Arborele ce simbolizeaz ntr-o form grafic procesul de cutare a numrului x, este
prezentat n fig. 1. ntruct x = 4 , n procesul cutrii vor fi examinate intervalele [ 2, 5] , [ 2, 3]
i [4, 4] .

33

Fig. 1

n programul ce urmeaz metoda dihotonomiei este realizat cu ajutorul procedurii


recursive Cauta.
Program Ghici;
uses Numere;
var m, n, x : integer;
Intrare, Iesire : text;
procedure Cauta(a, b : integer; var x : integer);
{ Cauta numarul x prin metoda dihotonomiei }
var c : integer;
begin
if a=b then x:=a
else
begin
c:=a+trunc((b-a)/2);
if SeAflaIn(a, c) then Cauta(a, c, x)
else Cauta(c+1, b, x);
end;
end; { Cauta }
begin
Interval(m, n);
Cauta(m, n, x);
NumarulGhicit(x);
end.

Din fig. 1 se observ c numrul de ntrebri k adresate calculatorului satisface


inegalitatea:
2 k 1 < p 2 k .
Acest numr poate fi calculat prin metoda trierii, evalund consecutiv 20, 21, 22, 23 .a.m.d.
pn se ajunge la soluia inecuaiei respective. n particular, pentru restriciile din enunul
problemei p = 32 000 , 214 < p < 215 , deci k = 15 . Evident, durata de execuie a procedurii
Cauta va fi cu mult mai mic dect 5 secunde.
34

Radiaii
n urma unei catastrofe tehnogene o poriune dreptungiular de teren a fost poluat cu
substane radioactive. Pentru a descrie gradul de poluare, terenul respectiv a fost divizat n
ptrate de dimensiuni identice, numrul acestora fiind n m. Fiecare ptrat este definit prin
coordonatele sale (i, j). Cercettorul trebuie s ajung din ptratul (1, 1) n ptratul (n, m).
Trecerea dintr-un ptrat n altul se efectueaz numai prin laturile adiacente. Este cunoscut
faptul c la parcurgerea ptratului (i, j) cercettorul va primi o doz de radiai de dij uniti,
doza total reprezentnd suma dozelor din ptratele parcurse. Alegnd diferite drumuri,
cercettorul ar putea minimiza doza total. Elaborai un program ce calculeaz doza total
minim dmin.
Date de intrare. Fiierul text RADIATII.IN conine pe prima linie numerele naturale
n, m, separate prin spaiu. Urmtoarele n linii conin cte m numere ntregi. Linia i+1 a
fiierului de intrare conine numerele di1, di2, ..., dim.
Date de ieire. Fiierul text RADIATII.OUT va conine pe o singur linie numrul
ntreg dmin.
Exemplu.
RADIATII.IN

RADIATII.OUT

3
2
1
1

5
100 0 100 100
100 0 0 0
0 3 100 2

Restricii. 1 n, m 30 ; 1 d ij 100 . Timpul de execuie nu va depi o secund. Fiierul


surs va avea denumirea RADIATII.PAS, RADIATII.C sau RADIATII.CPP.

35

Rezolvare
Vom reprezenta procesul de cutare a drumului cu ajutorul desenului ce urmeaz:
(1, 1)

(2, 1)

(1, 2)

(1, 3)

(1, 4)

(1, 5)

(2, 2)

(3, 1)

(2, 3)

(3, 2)

(2, 4)

(3, 3)

(3, 4)

(2, 5)

(3, 5)

Pe acest desen ptratele terenului snt simbolizate prin puncte, iar trecerea dintr-un
ptrat n altul prin liniile ce reunesc punctele respective. De exemplu, linia ce reunete
punctele (1, 1) i (1, 2) reprezint trecerea din ptratul cu coordonatele (1, 1) n ptratul cu
coordonatele (1, 2). Prin urmare, problema iniial se reduce la cutarea unui drum de cost
minim n graful ce descrie poriunea poluat de teren. Algoritmul respectiv este cunoscut n
literatura de specialitate ca algoritmul lui Deijkstra. Totui n cazul nostru acest algoritm nu
poate fi programat n varianta clasic, ntruct mecesarul de memorie pentru pstrarea matricei
de adiacen va fi de ( n m)( n m) = (30 30)(30 30) = 900 900 de elemente.
Pentru a micora necesarul de memorie, vom efectua toate calculele ntr-o matrice
nm :

R = rij

nm

unde elementul rij reprezint doza minim de radiaie care va fi primit la trecerea din
ptratul (1,1) pn n ptratul (i, j). Elementele matricei R pot fi calculate iterativ, memornd la
fiecare pas numai dozele minime. Elementele, valorile crora au fost deja calculate, vor fi
marcate prin schimbarea semnului n minus. Evident, dup calcularea tuturor elementelor
matricei R, semnul elementului (m, n) va fi schimbat n plus.
Program Radiatii
Const
MaxN=30;
{Pentru miscarea in celula adiacenta}
Dx: Array [1..4] Of Integer=( 0, 0,-1, 1);
Dy: Array [1..4] Of Integer=(-1, 1, 0, 0);
Var
{A-tabloul care se citeste din fisier
R-tabloul care este recalculat la fiecare pas}
A, R : Array [1..MaxN, 1..MaxN] Of Integer;
N, M, Rez : Integer;
i, j : Integer;

36

Intrare, Iesire:text;
{gaseste elementul minim din tabelul R, si pozitia lui}
{se vor considera doar elementele pozitive}
Procedure GetMin(Var si, sj: Integer);
Var i, j, min : Integer;
begin
min:=MaxInt; si:=1; sj:=1;
For i:=1 To N Do
For j:=1 To M Do
If (R[i,j]>0) And (R[i,j]<min) then
Begin si:=i; sj:=j; min:=R[i,j] end
end;
Procedure Calculeaza;
Var i, j, k, si, sj, ni, nj : Integer;
Begin
{initializare. nici un patrat marcat}
R[1,1]:=A[1,1];
{ciclu care marcheaza cite un patrat la fiecare iteratie}
For j:=1 To N*M-1 Do
Begin
{cauta patratul cu radiatie minima pentru marcare}
GetMin(si,sj);
{reinnoieste tabloul R considerind patratul pentru marcare}
For k:=1 To 4 Do
Begin
ni:=si+Dx[k]; nj:=sj+Dy[k];
If (ni<=N) And (ni>0) And (nj<=M) And (nj>0) And (R[ni,nj]>=0)
then
Begin
If (R[ni,nj]=0) Or (R[si,sj]+A[ni,nj]<R[ni,nj]) then
R[ni,nj]:=R[si,sj]+A[ni,nj]
End
End;
{marcarea patratlui}
R[si,sj]:=-R[si,sj]
End;
{Rezultatul se obtine in R[N,M]}
Rez:=Abs(R[N,M])
End;
Begin
{Citirea din Fisier}
Assign(Intrare,'RADIATII.IN'); Reset(Intrare);
Read(N,M);
For i:=1 To N Do
For j:=1 To M Do Read(A[i,j]);
Close(Intrare);
{Initializare tablolui R cu zerouri}
FillChar(R, SizeOf(R),0);
Calculeaza;
{Scrierea in fisier}
assign(Iesire,'RADIATII.OUT'); rewrite(Iesire);
Write(Iesire,Rez);
Close(Iesire)
end.

37

Ziua 2
Clasele 10 12

38

Depozitul
Pentru pstrarea n siguran a unor cantiti mari de substane radioactive, ntr-o regiune
ndeprtat a fost construit un depozit subteran. Depozitul este format dintr-o reea de tuneluri la
intersecia crora se afl zone de depozitare. Orice zon de depozitare poate fi liber sau ocupat de
containere cu substane radioactive. Tunelurile depozitului formeaz un caroiaj, iar distana dintre
oricare dou zone vecine este egal cu 1 (vezi fig. 1).

Fig. 1
Tunelurile care merg n direcia est-vest snt numerotate prin 1, 2, 3, ..., m, iar cele n direcia
nord-sud prin 1, 2, 3, ..., n. Fiecare zon de depozitare se identific printr-o adres unic de forma (i,
j), unde i este numrul tunelului est-vest, iar j al celui nord-sud, la intersecia crora se afl zona
respectiv.
Prin coridoare i prin zonele de depozitare se deplaseaz un robot. Robotul poate trece printr-o
zon de depozitare numai atunci cnd ea este liber. Se consider c indiferent de zona de plecare,
robotul poate ajunge n oricare alt zon liber a depozitului.
Elaborai un program care cunoscnd adresele zonelor ocupate, determin cel scurt drum ce
trebuie parcurs de robot pentru a ajunge din zona (a, b) n zona (c, d). Distanele parcurse de robot n
interiorul zonelor de depozitare nu vor fi luate n consideraie.
Date de intrare. Fiierul text DEPOZIT.IN conine pe prima linie numerele naturale m, n
separate prin spaiu. Linia a doua a fiierului de intrare conine numerele naturale a, b adresa zonei
de plecare, iar linia a treia numerele naturale c, d adresa zonei de sosire. Linia a patra a fiierului de
intrare conine numrul natural k numrul zonelor ocupate de containerele cu substane radioactive.
Urmtoarele k linii ale fiierului de intrare conin cte dou numere naturale i, j adresele zonelor
ocupate.
Date de ieire. Fiierul text DEPOZIT.OUT va conine pe prima linie numrul natural L
lungimea celui mai scurt drum ce trebuie parcurs de robot pentru a ajunge din zona (a, b) n zona (c,
d). Fiecare din urmtoarele L + 1 linii ale fiierului de ieire va conine cte dou numere naturale
separate prin spaiu, ce reprezint adresele zonelor ce formeaz cel mai scurt drum. Zonele respective
vor fi indicate n ordinea parcurgerii lor de ctre robot. Dac exist dou sau mai multe drumuri de
lungimea L, n fiierul de ieire se va indica numai unul din ele.
Exemplu.
DEPOZIT.IN
4 5
2 2
3 5
7
1 3
1 4
1 5
2 5
3 2
3 3
4 5

DEPOZIT.OUT
4
2 2
2 3
2 4
3 4
3 5

Restricii. 1 m, n 100 ; 1 a, c m ; 1 b, d n ; 1 k 1 000 . Timpul de execuie nu


va depi 2 secunde. Fiierul surs va avea denumirea DEPOZIT.PAS, DEPOZIT.C sau
DEPOZIT.CPP.

39

Rezolvare
Pentru a determina lungimea celui mai scurt drum vom folosi metoda propagrii undei
numerice, cunoscut n literatura de specialitate ca algoritmul lui Lee. Introducem n studiu
tabloul Z = z ij , unde zij reprezint lungimea celui mai scurt drum de la zona (a, b) la zona
(i, j). Iniial zonele libere vor fi marcate n tabloul Z printr-o valoare negativ, de exemplu 1,
iar zonele ocupate prin alt valoare negativ, de exemplu, 2 (vezi fig. 2). Evident, zab = 0.

L=0

Tabloul iniial
1

L=1
4

1 1 2 2 2

1 1

2 2 2

2 2 2

1 0 1 1 2

1 1 2

1 2 2 1 1

1 2 2 1 1

2 2 2 1 1

1 1 1 1 2

1 1 1 1 2

1 1 1 1 2

L=2

2 2

L=3
4

2 2 2

2 2 2

2 2

2 2 2 3 1

2 2 2 3

3 1 1 1 2

2 2
4

4 1 4 2
Fig. 2

n continuare propagm prin zonele depozitului o und numeric L, unde L ia


consecutiv valorile 0, 1, 2, 3 .a.m.d. Pentru aceasta parcurgem iterativ tabloul Z i atribuim
valoarea L+1 elementelor ce corespund zonelor libere, vecine cu zona n care a ajuns unda
numeric L. Procesul iterativ se termin n momentul cnd unda numeric ajunge n celula (c,
d).
Pentru a construi unul din cele mai scurte drumuri, vom parcurge elementele tabloului Z
n ordinea invers apariiei zonele respective n drumul cutat: de la zona (c, d) la zona (a, b).
Vom include n drumul n curs de construcie cte una din celulele ce aparin undei numerice:
L, L 1 , L 2 , ..., 1.
n programul ce urmeaz valorile iniiale ale tabloului Z snt stabilite cu ajutorul
procedurii Initializare. Pentru a simplifica analiza zonelor de la marginile depozitului,
n tabloul Z au fost incluse liniile 0, m+1 i coloanele 0, n+1 care formeaz un chenar, iar
elementelor respective li se atribuie valloarea 2 (zone ocupate). Unda numeric se propag
cu ajutorul procedurii UndaNumerica, iar unul din cele mai scurte drumuri este construit n
tabloul ** cu ajutorul procedurii DrumulMinim.
Program Depozit;
{ Clasele 10-12 }
const mmax=100; nmax=100;
ocupata=-2; libera=-1;
var m, n, a, b, c, d : integer;

40

L : integer;
Z : array[0..mmax+1, 0..nmax+1] of integer;
Intrare, Iesire : text;
Procedure Initializare;
{ Initializarea tabloului Z }
var i, j : integer;
begin
for i:=1 to m do
for j:=1 to n do Z[i, j]:=libera;
for i:=0 to m+1 do
begin
Z[i, 0]:=ocupata;
Z[i, n+1]:=ocupata;
end;
for j:=0 to n+1 do
begin
Z[0, j]:=ocupata;
Z[m+1, j]:=ocupata;
end;
end; { Initializare }
Procedure Citire;
{ Citirea datelor din fisierul de intrare }
var i, j, k, q : integer;
begin
assign(Intrare, 'DEPOZIT.IN');
reset(Intrare);
readln(Intrare, m, n);
readln(Intrare, a, b);
readln(Intrare, c, d);
Initializare;
readln(Intrare, k);
for q:=1 to k do
begin
readln(Intrare, i, j);
Z[i, j]:=ocupata;
end;
close(Intrare);
end; { Citire }
Procedure Scrie;
{ Scrierea datelor in fisierul de iesire }
begin
assign(Iesire, 'DEPOZIT.OUT');
rewrite(Iesire);
writeln(Iesire, L);
close(Iesire);
end; { Scrie }
Procedure UndaNumerica;
{ Propagarea undei numerice }
var i, j : integer;
begin
Z[a, b]:=0;
L:=0;
while Z[c, d]=libera do

41

begin
for i:=1 to m do
for j:=1 to n do
if Z[i, j]=L then
begin
if Z[i-1, j]=libera
if Z[i, j-1]=libera
if Z[i+1, j]=libera
if Z[i, j+1]=libera
end; { then }
L:=L+1;
end; { while }
end; { UndaNumerica }

then
then
then
then

Z[i-1, j]:=L+1;
Z[i, j-1]:=L+1;
Z[i+1, j]:=L+1;
Z[i, j+1]:=L+1;

begin
Citire;
UndaNumerica;
Scrie;
end.

Din analiza textului procedurii UndaNumerica se observ c instruciunea if din


componena ciclurilor imbricate for va fi executat de mn ori. Corpul ciclului while va fi
executat de cel mult L ori, unde L este lungimea celui mai scurt drum din zona (a, b) n zona
(c, d). Evident, lungimea acestui drum nu poate depi lungimea total a tunelurilor
depozitului, deci L < mn . Prin urmare, n cel mai nefavorabil caz, numrul de execuii ale
instruciunii if va fi de ordinul m2n2.
Conform restriciilor din enunul problemei, m, n 100 . Prin urmare, numrul necesar
de operaii este de ordinul 108, mrime comparabil cu capacitatea de prelucrare a
calculatoarelor personale.

42

Iepuraul
Se consider un sector de pdure de form dreptunghiular cu dimensiunile m n , unde
n i m snt numere naturale. Sectorul de pdure este divizat n ptrele cu latura 1 (fig. 1). n
unul din aceste ptrele se afl un iepura. Elaborai un program care determin coordonatele
i, j ale ptrelului n care se afl iepuraul.
Putei adresa calculatorului ntrebri de genul Iepuraul se afl n sectorul (a, b, c, d)?,
unde a, b reprezint coordonatele colului stnga-jos, iar c, d coordonatele colului dreapta-sus
ale unui sector dreptunghiular de pdure. La fiecare ntrebare calculatorul rspunde prin
cuvntul "da" (true) sau "nu" (false).

7
6
5
4
3
2
1

Iepuraul
4

1 2 3 4 5 6 7 8 9

Fig. 1

Date de intrare. Fiier de intrare nu exist. Dimensiunile m, n pot fi aflate apelnd


procedura predefinit Dimensiuni:
procedure Dimensiuni(var m, n : integer);

care returneaz valorile m, n.


Pentru a pune ntrebri, putei apela funcia predefinit SeAflaIn:
function SeAflaIn(a, b, c, d : integer) : boolean;

care returneaz valoarea true dac iepuraul se afl n dreptunghiul (a, b, c, d) i false n
caz contrar.
Pentru ca subprogramele Dimensiuni i SeAflaIn s fie accesibile, includei n
partea declarativ a programului de elaborat linia
uses Padure;

Unitatea de program Padure se afla n directorul ORI2004.


Date de ieire. Fiier de ieire nu exist. Pentru a comunica calculatorului coordonatele
i, j, apelai procedura predefinit Coordonatele:
procedure Coordonatele(i, j : integer);

Punctaj.
1. Programul care pune mai mult de 60 de ntrebri, nu va primi nici un punct.
2. Programul poate primi cel mult 10 puncte, dup cum urmeaz:
Dac coordonatele i, j din fiierul de ieire snt corecte, programul va primi 2
puncte.
Restul de pn la 8 puncte snt alocate n dependen de numrul total de ntrebri
adresate calculatorului (apeluri ale funciei SeAflaIn):
43

cu ct mai puine ntrebri vor fi adresate calculatorului, cu att mai multe


puncte va primi programul;
programul care va pune numrul minim de ntrebri va primi 8 puncte;
programul care va pune 60 de ntrebri nu va primi puncte suplimentare.
Exemplu. Presupunem, c apelul Dimensiuni(m, n) returneaz valorile m = 9 i
n = 7. Pentru a determina coordonatele (i, j), calculatorului i-au fost adresate urmtoarele
ntrebri:
ntrebare

Rspuns

SeAflaIn(1, 1, 5, 7)
SeAflaIn(6, 1, 7, 7)

false
true

SeAflaIn(6, 1, 6, 7)
SeAflaIn(1, 1, 9, 4)
SeAflaIn(1, 1, 9, 2)

false
true
false

SeAflaIn(1, 3, 9, 3)

false

Prin urmare, se va executa apelul Coordonatele(7, 4).


Restricii. 1 m, n 32 000 ; 1 a, c m ; 1 b, d n . Timpul de execuie nu va depi
o secund. Fiierul surs va avea denumirea IEPURAS.PAS, IEPURAS.C sau IEPURAS.CPP.
Evaluatorul va ntrerupe forat execuia programului n cazurile n care calculatorului i vor fi
adresate mai mult de 60 de ntrebri.
Programele scrise n limbajele C i C++ vor conine directiva:
#include Padure.h

iar suprogramele respective vor fi:


void Dimensiuni(int &m, int &n);
int SeAflaIn(int a, int b, int c, int d);
void Coordonatele(int i, int j);

44

Rezolvare
Presupunem, c se dorete gsirea coordonatelor i, j prin metoda trierii:
for a:= 1 to m do
for b:= 1 to n do
if SeAflaIn(a, b, a, b) then
begin i:=a; j:=b; goto 1 end;
1: writeln(i, j);

Media numrului de ntrebri k adresate calculatorului n metoda trierii se determin din


relaia:
mn
.
k=
2
n condiiile problemei, 1 m, n 32 000 i k = 51 200 000 . Evident, acest fapt poate
duce la nclcarea restriciei referitoare la numrul de ntrebri adresate calculatorului,
conform creia snt admise numai valorile k 60 .
Pentru a elabora un algoritm ce minimizeaz media numrului de ntrebri k , vom
considera calculatorul ca o surs de informaie cu mulimea mesajelor posibile:
S = {(i, j ) | i = 1, m; j = 1, n} ,

n total mn mesaje.
Este cunoscut faptul, c cantitatea de informaie I dintr-un mesaj al sursei de informaie
coincide cu media numrului minim de ntrebri k , necesare pentru identificarea univoc a
mesajelor. Procesul de identificare se realizeaz cu ajutorul unor ntrebri standart, generate
prin metoda dihotonomiei, i la care se rspunde prin "da" sau "nu". Prin urmare,
k = I = log 2 mn = log 2 m + log 2 n ,

unde I reprezint cantitatea de informaie dintr-un mesaj al sursei n studiu.


ntruct
S = S x S y , unde S x = {1, 2, 3, ..., m) i S y = {1, 2, 3, ..., n) ,
coordonatele i, j pot fi calculate separat, aplicnd metoda dihotonomiei pentru fiecare din
mulimile Sx i Sy .
Algoritmul ce realizeaz metoda dihotonomiei include urmtoarele etape (cazul
mulimii Sx):
5. Introducem n studiu intervalul curent [ A, B ] . Iniial, [ A, B ] = [1, m ] .
6. Divizm intervalul curent [ A, B ] n intervalele [ A, C ] i [C + 1, B ] . Pentru aceasta
calculm "mijlocul" intervalului [ A, B ] :
B A
C = A + Trunc (
),
2
unde Trunc este o funcie ce returneaz partea ntreag a argumentului ( B A) / 2 .
7. n continuare, n dependen de rspunsul la ntrebarea standard Iepuraul se afl n
sectorul (A, 1, C, n )?", desemnm ca interval curent unul din intervalele [ A, C ] sau
[C + 1, B ] .
8. Procesul de calcul continu pn cnd intervalul curent va conine numai un singur
numr.
Evident, n cazul mulimii Sy, intervalul iniial [ A, B ] = [1, n] , iar ntrebarea standard va
avea forma Iepuraul se afl n sectorul (1, A, m, C)?".

45

Arborele ce simbolizeaz ntr-o form grafic procesul de cutare a coordonatei i, este


prezentat n fig. 2. ntruct iepuraul se afl n ptrelul cu coordonatele (7, 4), n procesul
cutrii vor fi examinate intervalele [1, 5] , [6, 7] i [6, 6] .

{1, 2, 3, 4, 5, 6, 7, 8, 9}
k=1

da

nu

{6, 7, 8, 9}

{1, 2, 3, 4, 5}
k=2

nu

da

{1, 2, 3}
k=3

nu

da

{1, 2} {3}
k = 4 da
{1}

{4, 5}
da

nu

da

nu

{4} {5}

{6, 7}
da

nu

{6} {7}

{8, 9}
da

nu

{8} {9}

nu

{2}
Fig. 2

n programul ce urmeaz metoda dihotonomiei este realizat cu ajutorul procedurilor


recursive CautaX i CautaY.
Program Iepuras;
uses Padure;
var m, n, i, j : integer;
procedure CautaX(a, b : integer; var i : integer);
{ Cauta coordonata i prin metoda dihotonomiei }
var c : integer;
begin
if a=b then i:=a
else
begin
c:=a+trunc((b-a)/2);
if SeAflaIn(a, 1, c, n)
then CautaX(a, c, i)
else CautaX(c+1, b, i);
end;
end; { CautaX }
procedure CautaY(a, b : integer; var j : integer);
{ Cauta coordonata j prin prin metoda dihotonomiei }
var c : integer;
begin
if a=b then j:=a
else
begin

46

c:=a+trunc((b-a)/2);
if SeAflaIn(1, a, m, c)
then CautaY(a, c, j)
else CautaY(c+1, b, j);
end;
end; { CautaY }
begin
Dimensiuni(m, n);
CautaX(1, m, i);
CautaY(1, n, j);
Coordonatele(i, j);
end.

Din analiza arborilor de cutare ( fig. 2) rezult, c n cazul cel mai nefavorabil numrul
de ntrebri k adresate calculatorului se determin din relaia:
k = k x + k y = ] log 2 32 000 [ + ] log 2 32 000 [ = 15 + 15 = 30 ,

unde ] z [ simbolizeaz cel mai apropiat numr ntreg, mai mare sau egal cu z. Evident, durata
de execuie a procedurilor CautaX i CautaY va fi cu mult mai mic dect 5 secunde.

47

Radiaii
n urma unei catastrofe tehnogene o poriune dreptungiular de teren a fost poluat cu
substane radioactive. Pentru a descrie gradul de poluare, terenul respectiv a fost divizat n
ptrate de dimensiuni identice, numrul acestora fiind n m. Fiecare ptrat este definit prin
coordonatele sale (i, j). Cercettorul trebuie s ajung din ptratul (1, 1) n ptratul (n, m).
Trecerea dintr-un ptrat n altul se efectueaz numai prin laturile adiacente. Este cunoscut
faptul c la parcurgerea ptratului (i, j) cercettorul va primi o doz de radiai de dij uniti,
doza total reprezentnd suma dozelor din ptratele parcurse. Alegnd diferite drumuri,
cercettorul ar putea minimiza doza total. Elaborai un program ce calculeaz doza total
minim dmin.
Date de intrare. Fiierul text RADIATII.IN conine pe prima linie numerele naturale
n, m, separate prin spaiu. Urmtoarele n linii conin cte m numere ntregi. Linia i+1 a
fiierului de intrare conine numerele di1, di2, ..., dim.
Date de ieire. Fiierul text RADIATII.OUT va conine pe o singur linie numrul
ntreg dmin.
Exemplu.
RADIATII.IN

RADIATII.OUT

3
2
1
1

5
100 0 100 100
100 0 0 0
0 3 100 2

Restricii. 1 n, m 30 ; 1 d ij 100 . Timpul de execuie nu va depi o secund. Fiierul


surs va avea denumirea RADIATII.PAS, RADIATII.C sau RADIATII.CPP.

48

Rezolvare
Vom reprezenta procesul de cutare a drumului cu ajutorul desenului ce urmeaz:
(1, 1)

(2, 1)

(1, 2)

(1, 3)

(1, 4)

(1, 5)

(2, 2)

(3, 1)

(2, 3)

(3, 2)

(2, 4)

(3, 3)

(3, 4)

(2, 5)

(3, 5)

Pe acest desen ptratele terenului snt simbolizate prin puncte, iar trecerea dintr-un
ptrat n altul prin liniile ce reunesc punctele respective. De exemplu, linia ce reunete
punctele (1, 1) i (1, 2) reprezint trecerea din ptratul cu coordonatele (1, 1) n ptratul cu
coordonatele (1, 2). Prin urmare, problema iniial se reduce la cutarea unui drum de cost
minim n graful ce descrie poriunea poluat de teren. Algoritmul respectiv este cunoscut n
literatura de specialitate ca algoritmul lui Deijkstra. Totui n cazul nostru acest algoritm nu
poate fi programat n varianta clasic, ntruct mecesarul de memorie pentru pstrarea matricei
de adiacen va fi de ( n m)( n m) = (30 30)(30 30) = 900 900 de elemente.
Pentru a micora necesarul de memorie, vom efectua toate calculele ntr-o matrice
nm :

R = rij

nm

unde elementul rij reprezint doza minim de radiaie care va fi primit la trecerea din
ptratul (1,1) pn n ptratul (i, j). Elementele matricei R pot fi calculate iterativ, memornd la
fiecare pas numai dozele minime. Elementele, valorile crora au fost deja calculate, vor fi
marcate prin schimbarea semnului n minus. Evident, dup calcularea tuturor elementelor
matricei R, semnul elementului (m, n) va fi schimbat n plus.
Program Radiatii
Const
MaxN=30;
{Pentru miscarea in celula adiacenta}
Dx: Array [1..4] Of Integer=( 0, 0,-1, 1);
Dy: Array [1..4] Of Integer=(-1, 1, 0, 0);
Var
{A-tabloul care se citeste din fisier
R-tabloul care este recalculat la fiecare pas}
A, R : Array [1..MaxN, 1..MaxN] Of Integer;
N, M, Rez : Integer;
i, j : Integer;

49

Intrare, Iesire:text;
{gaseste elementul minim din tabelul R, si pozitia lui}
{se vor considera doar elementele pozitive}
Procedure GetMin(Var si, sj: Integer);
Var i, j, min : Integer;
begin
min:=MaxInt; si:=1; sj:=1;
For i:=1 To N Do
For j:=1 To M Do
If (R[i,j]>0) And (R[i,j]<min) then
Begin si:=i; sj:=j; min:=R[i,j] end
end;
Procedure Calculeaza;
Var i, j, k, si, sj, ni, nj : Integer;
Begin
{initializare. nici un patrat marcat}
R[1,1]:=A[1,1];
{ciclu care marcheaza cite un patrat la fiecare iteratie}
For j:=1 To N*M-1 Do
Begin
{cauta patratul cu radiatie minima pentru marcare}
GetMin(si,sj);
{reinnoieste tabloul R considerind patratul pentru marcare}
For k:=1 To 4 Do
Begin
ni:=si+Dx[k]; nj:=sj+Dy[k];
If (ni<=N) And (ni>0) And (nj<=M) And (nj>0) And (R[ni,nj]>=0)
then
Begin
If (R[ni,nj]=0) Or (R[si,sj]+A[ni,nj]<R[ni,nj]) then
R[ni,nj]:=R[si,sj]+A[ni,nj]
End
End;
{marcarea patratlui}
R[si,sj]:=-R[si,sj]
End;
{Rezultatul se obtine in R[N,M]}
Rez:=Abs(R[N,M])
End;
Begin
{Citirea din Fisier}
Assign(Intrare,'RADIATII.IN'); Reset(Intrare);
Read(N,M);
For i:=1 To N Do
For j:=1 To M Do Read(A[i,j]);
Close(Intrare);
{Initializare tablolui R cu zerouri}
FillChar(R, SizeOf(R),0);
Calculeaza;
{Scrierea in fisier}
assign(Iesire,'RADIATII.OUT'); rewrite(Iesire);
Write(Iesire,Rez);
Close(Iesire)
end.

50