Documente Academic
Documente Profesional
Documente Cultură
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
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.
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
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:
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.
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
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
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
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
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.
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
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:
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.
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
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
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.
25
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
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
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.
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);
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
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);
33
Fig. 1
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
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
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
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.
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
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;
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
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
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);
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 ,
45
{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
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
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