Sunteți pe pagina 1din 77

Probleme rezolvate de programare Subiecte propuse la ATESTAT - 2005

2005
BACKTRACKING

ATESTAT - 2005 - 1 - Se citesc de la tastatur dou numere naturale n i k (0 < k < n < 12). S se
afieze toate irurile formate din k litere distincte, litere alese dintre primele n ale alfabetului
englez. Exemplu: pentru k = 2 i n = 4, se afieaz, nu neaprat n aceast ordine, irurile: AB, BA,
AC, CA, AD, DA, BC, CB, BD, DB, CD, DC.

Rezolvare:
Aplicm algoritmul BACKTRACKING pentru generarea aranjamentelor.
program ATESTAT_2005_1_ARANJAMENTE_1;
uses CRT;
CONST
Kmax = 20; { nr. max al elementelor din A }
Nmax = 50; { nr. max al elementelor din B sau nr. valorilor functiei }
TYPE
functie = array [ 1..Kmax ] of 0..Nmax;
VAR
k, poz, i : 1 .. Kmax; { se considera k <= n }
n : 0 .. Nmax;
f : functie; {sau f : array [1..Kmax] of [1..Nmax];}
IMAG : set of 1 .. Nmax; { IMAG = multimea imaginilor elementelor din A }
{ adica f [poz] }
Begin { PROGRAM PRINCIPAL }
clrscr;
repeat
write ('k = ');
readln (k);
until ( k >= 1 ) AND ( k <= Kmax );
repeat
write ('Introduceti un n >= ', k,' n = ');
readln (n);
if n < k then
writeln ('Pentru acest n = ', n,' Nu exista solutii')
until ( n >= k ) AND ( n >= 1 ) AND ( n <= Nmax );
writeln;
writeln ('Apasati ENTER pentru urmatoarea solutie');
writeln;
readln;

poz := 1; { poz = pozitia virfului stivei }


f [poz] := 0 ; { initializare element }
IMAG := [] ; { initializare multime imagini cu multimea vida }

while poz > 0 do { cat timp stiva nu este vida }


begin
while f [poz] < n do { cat timp nu s-au epuizat toate }
{ elementele din B }
begin
f [poz] := f [poz] + 1; {INSERARE}
if not ( f[poz] IN IMAG ) then
begin
if poz = k then { daca stiva este plina }
begin
for i := 1 to k do
Probleme rezolvate de programare Subiecte propuse la ATESTAT
begin {tiparire SOLUTIE}
write ( CHR (64 + f[i] ) ,' ');
end;
readln;
end
else
begin
IMAG := IMAG + [ f [poz] ];
poz := poz + 1 ; {pas INAINTE}
f [poz] := 0 {reinitializare element}
end;
end; { sf. IF NOT }
end; { sf. WHILE interior }
poz := poz - 1; {pas INAPOI}
IMAG := IMAG - [ f [poz] ];
end; { sf. WHILE exterior }
readln
END.

ATESTAT - 2005 - 2 - Civa copii cu vrste ntre 2 si 7 ani trebuie s fie vizitai de Mo Crciun.
Scriei un program care determin toate modurile diferite n care pot ei s fie aezai n lista lui Mo
Crciun, astfel nct s fie vizitai toi copiii i vizitele s se fac n ordinea cresctoare a vrstei
lor. Se citesc de la tastatur: n = numrul de copii (0 < n < 10), apoi numele i vrsta fiecruia dintre
cei n copii. Se scriu, pe linii diferite, liste cu numele copiilor, n ordinea n care vor fi vizitai de Mo
Crciun. O list este format din toate cele n nume ale copiilor, ntr-o anumit ordine, oricare dou
nume succesive fiind desprite prin spaii.
Exemplu:
Pentru datele de intrare: n = 4, Dan 6, Cristina 4, Corina 2, Iulia 4
se scriu urmtoarele soluii:
Corina Iulia Cristina Dan
Corina Cristina Iulia Dan
Rezolvare:
Definim o procedur ORDONEAZ, pentru ordonarea numelor copiilor.
program ATESTAT_2005_2_MOS_CRACIUN_SI_COPIII;
uses crt;
const
nmax = 100;
type
vector = array [1..nmax] of integer;
vector_nume = array [1..nmax] of string;
vector_virsta = array [1..nmax] of integer;
var
f : vector;
sol, n, i : integer;
incep, sf : integer;
NUME : vector_nume;
VIRSTA : vector_virsta;
EGAL : boolean;
t : integer;
k : integer; {contor care numara elementele vecine egale in vectorul VIRSTA }
pozitie : integer; {pozitia incepind de la care apar elemente egale}
{in vectorul VIRSTA}

4
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure ORDONEAZA (VAR v1:vector_virsta; VAR v2 : vector_nume; q:integer);
var
k1, j, aux: integer;
siraux : string;
begin
repeat
k1:= 0;
j := 1;
repeat
if v1[j] > v1 [j+1] then
begin
aux := v1 [j];
v1 [j] := v1 [j+1];
v1 [j+1] := aux;

siraux := v2 [j];
v2 [j] := v2 [j+1];
v2 [j+1] := siraux;

k1 := 1
end;
j := j + 1
until (j > q-1)
until (k1 = 0);
end;
procedure VERIFICA ( pozitia : integer; f : vector ; VAR CONTIN : boolean );
LABEL
10;
VAR
j : integer;
begin
CONTIN := TRUE;
for j := 1 to pozitia - 1 do
begin
if f [j] = f [pozitia] then
begin
CONTIN := FALSE;
GOTO 10
end;
end;
10:
end;
procedure SCRIE ;
var
j : integer;
begin
sol := sol + 1;
write ('Solutia nr. ',sol,' ');
for t := 1 to incep - 1 do
begin
write ( NUME [t],' ');
end;
for j := 1 to sf - incep + 1 do
begin
write ( NUME [ f [j] + incep - 1 ],' ' )
end;
for t := sf + 1 to n do
begin
write ( NUME [t],' ');
end;
writeln;
readln;
end;

5
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure PERMUTA ( incep, sf : integer );
LABEL
20;
var
m : integer;
poz : integer;
CONTIN : boolean;

begin

m := sf - incep + 1;

poz := 1;
f [poz] := 0;
while poz > 0 do
begin
CONTIN := FALSE;
while f [poz] < m do
begin
f [poz] := f [poz] + 1;
VERIFICA (poz, f, CONTIN);
if CONTIN = TRUE then
GOTO 20
end;
20: if ( CONTIN = TRUE ) AND (poz = m) then
SCRIE;
if ( CONTIN = TRUE ) and (poz < m) then
begin
poz := poz + 1;
f [poz] := 0;
end;
if CONTIN = FALSE then
poz := poz - 1
end; {sf. WHILE exterior}
end;

Begin { PROGRAM PRINCIPAL }


clrscr;

sol := 0;

write ('Dati numarul de copii, n = ');


readln (n);
writeln;
writeln;

for i := 1 to n do
begin
write ('Dati NUMELE copilului ', i,' nume = ');
readln ( nume [i] );
write ('Dati VIRSTA copilului ', i, ' virsta = ');
readln ( virsta [i] );
writeln;
writeln ('*****************************************');
writeln
end;
ORDONEAZA (virsta, nume, n);

writeln;
writeln ('Apasati ENTER pentru urmatoarea solutie');
readln;

6
Probleme rezolvate de programare Subiecte propuse la ATESTAT
i := 1;
while i < n do
begin
EGAL := FALSE;
k := 0;
while ( VIRSTA [i] = VIRSTA [i+1] ) AND (i < n ) do
begin
EGAL := TRUE;
k := k + 1;
i := i + 1
end;
if EGAL = TRUE then
begin
k := k + 1;
pozitie := i - k + 1;
incep := pozitie;
sf := pozitie + k - 1;

PERMUTA (incep, sf);


end;
i := i + 1
end;
writeln;

if sol = 0 then
writeln ('Nu exista solutie');
readln
END.

ATESTAT - 2005 - 3 - Se citesc de la tastatur numerele naturale n i k (0 < n <= 10000 i


0 < k <= 10) reprezentate n baza 10. S se afieze n ordine cresctoare toate numerele naturale de
k cifre cu proprietatea c sunt formate numai cu cifre ale numrului n.
Exemplu: pentru n = 216 i k = 2, se vor afia numerele:
11, 12, 16, 21, 22, 26, 61, 62, 66.

Rezolvare:
Completm acest algoritm cu cerinele enunului de mai sus.
Mulimile care se nmulesc cartezian vor avea "nrcif" elemente.
Numrul de mulimi care se vor nmuli cartezian = k. Altfel spus, numerele generate vor avea
cte k cifre.
Exemplu, pentru n = 216 (nrcif = 3) i k = 2, vom obine:
(1,2,6) x (1,2,6) = (1,1), (1,2), (1,6), (2,1), (2,2), (2,6), (6,1), (6,2), (6,6)
program ATESTAT_2005_3_Produs_cartezian;

uses CRT;
type
vector = array [1..20] of integer;
var
k, nrcif, i, x, n : integer;
w, m, f : vector;
sir : string;
a, er : integer;

7
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure SCRIE;
begin
for i := 1 to k - 1 do
begin
write (w [ f[i] ]);
end;
write ( w [ f[k] ]);
writeln;
end;

function NRCIFRE (x : integer) : integer;


begin
if x = 0 then
nrcif := 1
else
begin
nrcif := 0;
while x <> 0 do
begin
nrcif := nrcif + 1;
x := x DIV 10
end;
end;
NRCIFRE := nrcif
end;

procedure ORDONEAZA (var v:vector; q:integer);


var
k, j, aux: integer;
begin
repeat
k:= 0;
j := 1;
repeat
if v[j] > v [j+1] then
begin
aux := v[j];
v[j] := v[j+1];
v[j+1] := aux;
k := 1
end;
j := j + 1
until (j > q-1)
until (k = 0);
end;

Begin { PROGRAM PRINCIPAL }


CLRSCR;
write ('Dati numarul n (de ex. n = 215), n = ');
readln (n);
nrcif := NRCIFRE (n);
STR (n, sir);
for i:= 1 to nrcif do
begin
VAL (sir [i], a, er);
w [i] := a;
end;
ORDONEAZA (w, nrcif);
writeln ('Precizati cite cifre vor avea numerele generate, de ex. k = 2');
write ('Dati k = ');
readln (k);
writeln ('Apasati ENTER pentru afisarea urmatoarei solutii');
readln;

8
Probleme rezolvate de programare Subiecte propuse la ATESTAT
x := 1;
f [x] := 0;
while x > 0 do
begin
if f [x] < nrcif then
begin
f [x] := f[x] + 1;
if x = k then
begin
SCRIE;
readln;
end
else
begin
x := x + 1; {PAS INAINTE}
f [x] := 0
end
end
else
x := x 1 {PAS INAPOI}
end;
readln
END.

ATESTAT - 2005 - 4 - S se genereze toate irurile de n (n < 6, numr natural dat de la tastatur)
note muzicale din mulimea {do, re, mi, fa, sol, la, si}. Orice not poate s nu apar sau se poate
repeta n cadrul unui ir. Fiecare ir va fi afiat pe cte o linie, n cadrul liniei, notele fiind separate
prin cte un spaiu.
Exemplu: pentru n = 5, unul dintre irurile generate este:
mi do do si mi

Rezolvare:

program ATESTAT_2005_4_Produs_cartezian;

uses CRT;
type
vector = array [1..20] of integer;
var
p, i, x, n : integer;
f : vector;
nota : array [1..7] of string;
procedure SCRIE;
begin
write ('{ ');
for i := 1 to n - 1 do
begin
write (nota [ f[i] ],' , ');
end;
write ( nota [ f[n] ],' ');
write ('} ');
writeln;
end;

9
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
CLRSCR;
writeln ('Precizati cite note trebuie sa contina sirul, de exemplu n = 6');
write ('Dati n = ');
readln (n);

p := 7; {numarul total de note: do, re,... si}

writeln;
writeln ('Apasati ENTER dupa fiecare solutie');
readln;

nota [1] := 'do';


nota [2] := 're';
nota [3] := 'mi';
nota [4] := 'fa';
nota [5] := 'sol';
nota [6] := 'la';
nota [7] := 'si';

x := 1;
f [x] := 0;
while x > 0 do
begin
if f [x] < p then
begin
f [x] := f[x] + 1;
if x = n then
begin
SCRIE;
readln;
end
else
begin
x := x + 1; {PAS INAINTE}
f [x] := 0
end
end
else
x := x 1 {PAS INAPOI}
end;
readln
END.

ATESTAT - 2005 - 5 - S se genereze toate cuvintele de lungime n (n < 10) ale alfabeltului Morse
(formate doar din caracterele '-' i '.'), care nu ncep i nu se termin cu caracterul '-'. Fiecare cuvnt
va fi afiat pe cte o linie.

Rezolvare:

Vom genera produsul cartezian M x M x M ...x M, de n ori, n care mulimea M este format
doar din caracterele . i -.
Asociem: cifrei 1, caracterul "-" cu codul ASCII 45
i cifrei 2, caracterul "." cu codul ASCII 46.

10
Probleme rezolvate de programare Subiecte propuse la ATESTAT
program ATESTAT_2005_5_Codul_Morse_produs_cartezian;
uses CRT;
type
vector = array [1..20] of integer;
var
p, i, x, n : integer;
m, f : vector;
procedure SCRIE;
begin
for i := 1 to n do
write (CHR (44 + f[i] ),' ');
writeln;
end;
Begin { PROGRAM PRINCIPAL }
CLRSCR;
writeln ('Precizati de cite ori trebuie inmultita multimea M cu ea insasi');
write ('Dati n = '); readln (n);

writeln ('Multimea M are doar p = 2 elemente: . si - ');


p := 2;
writeln; writeln ('Apasati ENTER dupa fiecare solutie'); readln;
x := 1;
f [x] := 0;
while x > 0 do
begin
if f [x] < p then
begin
f [x] := f[x] + 1;
if x = n then
begin
if NOT ( f [1] = 1 ) AND NOT ( f [n] = 1 ) then
begin
SCRIE;
readln;
end;
end
else
begin
x := x + 1; {PAS INAINTE}
f [x] := 0
end
end
else
x := x 1 {PAS INAPOI}
end;
readln
END.

ATESTAT - 2005 - 6 - Se citete un cuvnt format din maxim 20 de litere distincte. S se afieze
toate anagramele cuvntului respectiv. Un cuvnt A este anagrama unui cuvnt C dac A
este format din aceleai litere ca i cuvntul C, dar aezate n alt ordine.
Exemplu: Pentru cuvntul "car", trebuie afiate, nu neaprat n aceast ordine, anagramele:
car -> cra, acr, arc, rca, rac.
Rezolvare:

11
Probleme rezolvate de programare Subiecte propuse la ATESTAT
program ATESTAT_2005_6_PERMUTARI_ITERATIV;
uses crt;
const
nmax = 100;
type
vector = array [1..nmax] of integer;
var
f : vector;
sir : string;
lungime_sir : integer;
sol, n, i : integer;
procedure VERIFICA ( k : integer; f : vector ; VAR CONTIN : boolean );
LABEL
10;
begin
CONTIN := TRUE;
for i := 1 to k - 1 do
begin
if f [i] = f [k] then
begin
CONTIN := FALSE;
GOTO 10
end;
end;
10: end;
procedure SCRIE ;
begin
sol := sol + 1;
write ('Solutia nr. ',sol,' ');
for i := 1 to n do
write ( sir [f [i] ] )
readln; writeln {optionale}
end;
procedure PERMUTA ( m : integer );
LABEL
20;
var
k : integer;
CONTIN : boolean;
begin
k := 1;
f [k] := 0;
while k > 0 do
begin
CONTIN := FALSE;
while f [k] < m do
begin
f [k] := f [k] + 1;
VERIFICA (k, f, CONTIN);
if CONTIN = TRUE then
GOTO 20
end;
20: if ( CONTIN = TRUE ) AND (k = n) then
SCRIE;
if ( CONTIN = TRUE ) and (k < n) then
begin
k := k + 1; {PAS INAINTE}
f [k] := 0
end;
if CONTIN = FALSE then
k := k 1 {PAS INAPOI}
end; {sf. WHILE exterior}
end;

12
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
clrscr;

sol := 0;

writeln;

write ('Dati sirul care se va permuta, sir = ');


readln (sir);
writeln;
writeln;
writeln;
writeln ('Apasati ENTER dupa fiecare solutie afisata');
writeln;

lungime_sir := LENGTH (sir);

n := lungime_sir;

writeln;
writeln;

PERMUTA (n);

if sol = 0 then
writeln ('Nu exista solutie');
readln
END.

ATESTAT - 2005 - 7 - Se citete din fiierul standard de intrare un numr natural n aparinnd N*
i o mulime M cu p elemente numere ntregi. S se determine i s se scrie elementele produsului
cartezian M x M x...x M (de n ori).

Rezolvare:
program ATESTAT_2005_7_produs_cartezian;
uses CRT;
type
vector = array [1..20] of integer;
var
p, i, x, n : integer;
m, f : vector;

procedure SCRIE;
begin
write ('{ ');
for i := 1 to n - 1 do
begin
write (f[i],' , ');
end;
write ( f[n],' ');
write (' ');
writeln;
end;

13
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
CLRSCR;
writeln ('Precizati de cite ori trebuie inmultita multimea M cu ea insasi');
write ('Dati n = '); readln (n);
write ('Dati numarul de elemente ale multimii M, p = '); readln (p);
writeln;
writeln ('Apasati ENTER dupa fiecare solutie');
readln;
x := 1;
f [x] := 0;
while x > 0 do
begin
if f [x] < p then
begin
f [x] := f[x] + 1;
if x = n then
begin
SCRIE;
readln;
end
else
begin
x := x + 1; {PAS INAINTE}
f [x] := 0
end
end
else
x := x 1 {PAS INAPOI}
end;
readln
END.

ATESTAT - 2005 - 8 - Un copil dorete s introduc n bile numerotate de la 1 la n n n cutii, cte o


bil n fiecare cutie. S se afieze toate posibilitile pe care le are copilul de a pune cele n bile n
cele n cutii.

Rezolvare:
program ATESTAT_2005_8_PERMUTARI_ITERATIV;
uses crt;
const nmax = 100;
type
vector = array [1..nmax] of integer;
var
f : vector;
sol, n, i : integer;
procedure SCRIE ;
begin
sol := sol + 1;
write ('Solutia nr. ',sol,' ');
for i := 1 to n do
begin
write ( f [i] : 5 )
end;
readln; writeln
end;

14
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure VERIFICA ( k : integer; f : vector ; VAR CONTIN : boolean );
LABEL 10;
begin
CONTIN := TRUE;
for i := 1 to k - 1 do
begin
if f [i] = f [k] then
begin
CONTIN := FALSE;
GOTO 10
end;
end;
10: end;

procedure PERMUTA ( m : integer );


LABEL 20;
var
k : integer;
CONTIN : boolean;
begin
k := 1;
f [k] := 0;
while k > 0 do
begin
CONTIN := FALSE;
while f [k] < m do
begin
f [k] := f [k] + 1;
VERIFICA (k, f, CONTIN);
if CONTIN = TRUE then
GOTO 20
end;
20: if ( CONTIN = TRUE ) AND (k = n) then
begin
SCRIE;
readln;
end;
if ( CONTIN = TRUE ) and (k < n) then
begin
k := k + 1;
f [k] := 0
end;
if CONTIN = FALSE then
k := k - 1
end; {sf. WHILE exterior}
end;

Begin { PROGRAM PRINCIPAL }


clrscr;
sol := 0;
write('Dati n = '); readln (n);
writeln;
writeln ('Apasati ENTER dupa fiecare solutie');
writeln;
PERMUTA (n);
if sol = 0 then
writeln ('Nu exista solutie');
readln
END.

15
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 9 - S se genereze toate PALINDROAMELE care au n cifre, iar cifrele au
valori ntre 0 i p. Se citesc de la tastatur n i p (0 < n < 10, 0 < p < 5). Reamintim c un numr este
PALINDROM dac numrul coincide cu imaginea lui n oglind. Altfel spus, un numr este
PALINDROM dac citit direct i invers rezultatul este acelai.
Exemplu: 121 este PALINDROM.
Barem :
- declararea variabilelor: 0.5 puncte
- citirea datelor de intrare: 1 punct
- un algoritm de generare principial corect: 3 puncte
- verificarea condiiilor de continuare : 2 puncte
- afiarea soluiilor: 2 puncte
- corectitudinea sintactic a programului : 0.5 puncte
- din oficiu 1 punct.

Rezolvare:
program ATESTAT_2005_9_ PALINDROAME;
uses CRT;
type
vector = array [1..20] of integer;
var
m, f : vector;
p, poz, A, B, x, n, nrcif, i : integer;
OK : boolean;
y : array [1..100] of integer;
function PUTERE (z: integer; t : integer): integer;
var
p1, j: integer;
begin
p1 := 1;
for j := 1 to t do
p1 := p1 * z;
PUTERE := p1
end;
function NRCIFRE (x : integer) : integer;
begin
if x = 0 then
nrcif := 1
else
begin
nrcif := 0;
while x <> 0 do
begin
nrcif := nrcif + 1;
x := x DIV 10
end;
end;
NRCIFRE := nrcif
end;
function PALINDROM ( x : integer ) : boolean;
begin
n := NRCIFRE (x);
for i := n DOWNTO 1 do
begin
y [i] := x MOD 10;
x := x DIV 10;
end;

16
Probleme rezolvate de programare Subiecte propuse la ATESTAT
OK := TRUE;
for i := 1 to n DIV 2 do
begin
if y [i] <> y [n-i+1] then
OK := FALSE
end;
PALINDROM := OK
end; { sfarsit functie PALINDROM }
procedure SCRIE;
begin
write ('{ ');
for i := 1 to n - 1 do
begin
write (f[i],' , ');
end;
write ( f[n],' ');
write (' ');
writeln; writeln;
end;
Begin { PROGRAM PRINCIPAL }
CLRSCR;
writeln ('Precizati numarul de cifre al viitorului numar');
write ('Dati n = '); readln (n);
{n = nr de multimi ale produsului cartezian }
writeln;
repeat
writeln ('Precizati care este cea mai mare cifra din viitorul numar');
write ('Dati p = '); readln (p);
until (p > 0) AND (p<=5);
writeln;
{este acelasi lucru cu a cere numarul de elemente din fiecare multime }
{implicata in calculul produsului cartezian }
poz := 1;
f [poz] := 0;
while poz > 0 do
begin
if f [poz] < p then
begin
f [poz] := f[poz] + 1;
if poz = n then
begin
x := 0;
for i := n downto 1 do
begin
x := x + PUTERE (10, n-i) * f [i];
end;
if PALINDROM (x) = TRUE then
begin
writeln ('x = ', x, ' este PALINDROM');
SCRIE;
end;
end
else
begin
poz := poz + 1; {PAS INAINTE}
f [poz] := 0
end
end
else
poz := poz 1 {PAS INAPOI}
end;
readln
END.

17
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ALOCARE DINAMICA

ATESTAT - 2005 - 10 - S se realizeze operaiile de creare i vizualizare a unei stive implementate


dinamic, precum i eliminarea unui element din stiv.
Barem:
- declararea corect a variabilelor: 1 punct
- crearea: 4 puncte
- vizualizarea: 2 puncte
- eliminarea unui element: 2 puncte
- din oficiu: 1 punct

Rezolvare:
program ATESTAT_2005_10_STIVA;
label
10,500;
type
STIVA = ^Nod;
Nod = record
cheie : integer;
data : integer;
urm : STIVA
end;
var
p, q, r, baza : STIVA;
n, x, i, j : integer;
data : integer;
c : char;

procedure CITDATA; { introducere date utile }


begin
write ('introduceti datele nodului : ');
readln (data);
end;

procedure TRAVLISTA ; { traversare in ordinea introducerii }


begin
p:=baza;
while p<>nil do
begin
writeln(' cheia= ',p^.cheie,' data= ',p^.data);
p:=p^.urm;
writeln
end;
end;

procedure INSEREAZAPRIMUL ; {introduce primul element - la incep. Listei }


begin
baza:=nil;
new(p);
write('dati cheia nodului 1 : ');
readln(p^.cheie);
p^.urm:=baza;
baza:=p;
CITDATA;
p^.data:=data
end;

18
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure INSEREAZAREST ; { introduce celelalte elem. - la sfirs. listei }
begin
new (q);
q^.urm:=nil;
p^.urm:=q;
if j<=n then
begin
write('dati cheia nodului ', j,' : ');
readln(q^.cheie);
CITDATA;
q^.data:=data;
p:=q
end
else
begin
q^.cheie:=N+1;
{ q^.data:='ACEST NOD NU SE VA STERGE SI NU SE ADAUGA NIMIC DUPA EL'; }
p:=q
end
end;

procedure CAUTA ; { cauta un nod dupa cheie }


var
b:boolean;
begin
b:=false;
write('DATI CHEIA X = ');
readln(x);
writeln;
p:=baza;

while (p<>nil) and not b do


begin
if p^.cheie=x then
b:=true
else
p:=p^.urm
end;
if not b then
writeln('NODUL ( CHEIA ) NU EXISTA ')
else
begin
writeln('PRIMUL NOD CARE ARE CHEIA ',X,' ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln
end
end;

procedure STERGE ;{ sterge un nod indicat printr-o cheie }


begin
q:=p^.urm;
p^:=q^
end;

Begin { PROGRAM PRINCIPAL }


write('dati nr.de noduri N = ');
readln(n);
writeln;
if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end

19
Probleme rezolvate de programare Subiecte propuse la ATESTAT
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');
INSEREAZAPRIMUL;
writeln
end;
if n > 1 then
begin
for j:=2 to n do
begin
INSEREAZAREST;
writeln
end
end;
j:=j+1;
INSEREAZAREST;
writeln;
writeln(' LISTA ESTE : ');
TRAVLISTA;
writeln;
10: write('DORITI SA CAUTATI UN NOD ? APASATI D SAU N ');
readln(c);
if (c='d') or (c='D') then
begin
CAUTA
end;
writeln;
write('DORITI SA STERGETI UN NOD ? APASATI D SAU N ');
readln(c);
writeln;

if (c='d') or ( c='D') then


begin
CAUTA;
writeln('CONTINUT NOD CU CHEIA ',X,' INAINTE DE STERGERE ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln;
STERGE;
writeln;
writeln('CONTINUTUL NODULUI DUPA STERGERE ESTE :');
writeln(p^.cheie,' ',p^.data);
writeln;
writeln('LISTA DUPA STERGEREA NODULUI CU CHEIA ',X,' ESTE :');
TRAVLISTA;
writeln
end;
write('DORITI SA RELUATI PROGRAMUL ? APASATI D SAU N ');
readln(c);
writeln;
if ( c='d') or ( c='D') then goto 10;
500: readln
END.

ATESTAT - 2005 - 11 - S se realizeze operaiile de creare i vizualizare a unei cozi implementate


dinamic, precum i eliminarea unui element din coad.
Barem:
- declararea corect a variabilelor: 1 punct
- crearea: 4 puncte
- vizualizarea: 2 puncte
- eliminarea unui element: 2 puncte
- din oficiu: 1 punct

20
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare:
program ATESTAT_2005_11_COADA;
label
10,500;
type

COADA=^nod;
nod=record
cheie : integer;
data : integer;
urm : COADA
end;
var
q, r, baza, p : COADA;
n, x, i, j : integer;
data : integer;
c : char;

procedure CITDATA; { introducere date utile }


begin
write ('introduceti datele nodului : ');
readln (data);
end;

procedure TRAVLISTA ; { traversare in ordinea introducerii }


begin
p:=baza;
while p<>nil do
begin
writeln(' cheia= ',p^.cheie,' data= ',p^.data);
p:=p^.urm;
writeln
end;
end; {sfarsit procedura TRAVLISTA}
procedure INSEREAZAPRIMUL ; {introduce primul element - la incep. listei }
begin
baza:=nil;
new(p);
write('dati cheia nodului 1 : ');
readln(p^.cheie);
p^.urm:=baza;
baza:=p;
CITDATA;
p^.data:=data
end;
procedure INSEREAZAREST ; { introduce celelalte elem. - la sfirs. listei }
begin
new (q);
q^.urm:=nil;
p^.urm:=q;

if j<=n then
begin
write('dati cheia nodului ', j,' : ');
readln(q^.cheie);
CITDATA;
q^.data:=data;
p:=q
end

21
Probleme rezolvate de programare Subiecte propuse la ATESTAT
else
begin
q^.cheie:=N+1;
{ q^.data:='ACEST NOD NU SE VA STERGE SI NU SE ADAUGA NIMIC DUPA EL'; }
p:=q
end
end;
procedure CAUTA ; { cauta un nod dupa cheie }
var
b:boolean;
begin
b:=false;
write('DATI CHEIA X = ');
readln(x);
writeln;
p:=baza;
while (p<>nil) and not b do
begin
if p^.cheie=x then
b:=true
else
p:=p^.urm
end;
if not b then
writeln('NODUL ( CHEIA ) NU EXISTA ')
else
begin
writeln('PRIMUL NOD CARE ARE CHEIA ',X,' ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln
end
end;
procedure STERGE ;{ sterge un nod indicat printr-o cheie }
begin
q:=p^.urm;
p^:=q^
end;
Begin { PROGRAM PRINCIPAL }
write('Dati numarul de noduri N = '); readln(n);
writeln;
if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');
INSEREAZAPRIMUL;
writeln
end;
if n > 1 then
begin
for j:=2 to n do
begin
INSEREAZAREST;
writeln
end
end;
j:=j+1;
writeln('INTRODUCETI NODUL F A N I O N ');
INSEREAZAREST;
writeln;

22
Probleme rezolvate de programare Subiecte propuse la ATESTAT
writeln(' LISTA ESTE : ');
TRAVLISTA;
writeln;
10: write('DORITI SA CAUTATI UN NOD ? APASATI D SAU N ');
readln(c);
if (c='d') or (c='D') then
CAUTA
writeln;
write('DORITI SA STERGETI UN NOD ? APASATI D SAU N ');
readln(c);
writeln;
if (c='d') or ( c='D') then
begin
CAUTA;
writeln('CONTINUT NOD CU CHEIA ',X,' INAINTE DE STERGERE ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln;
STERGE;
writeln;
writeln('CONTINUTUL NODULUI DUPA STERGERE ESTE :');
writeln(p^.cheie,' ',p^.data);
writeln;
writeln('LISTA DUPA STERGEREA NODULUI CU CHEIA ',X,' ESTE :');
TRAVLISTA;
writeln
end;
write('DORITI SA RELUATI PROGRAMUL ? APASATI D SAU N ');
readln(c);
writeln;
if ( c='d') or ( c='D') then goto 10;
500: readln
END.

ATESTAT - 2005 - 12 - S se creeze o list liniar dublu nlnuit avnd ca elemente cuvinte
citite din fiierul standard de intrare, pn la ntlnirea caracterului * . S se afieze cuvintele n
ordine invers citirii i apoi n ordinea n care s-au citit.
Barem:
- declararea corect a variabilelor: 1 punct
- crearea: 4 puncte
- vizualizarea: 4 puncte
- din oficiu: 1 punct

Rezolvare:
program ATESTAT_2005_12_LISTA_DUBLU_INLANTUITA;
uses CRT;
label
10, 500;
type
LISTA = ^nod;
nod = record
cheie : integer;
data : string;
urm, preced : LISTA
end;

23
Probleme rezolvate de programare Subiecte propuse la ATESTAT
var
q,r,baza,p: LISTA;
n,x,i,j:integer;
data:string;
c:char;
procedure CITDATA; { introducere date utile }
begin
write ('Introduceti datele nodului : ');
readln (data);
end;
procedure TRAVLISTA_INCEP_SFARSIT ; { traversare lista inceput -> sfirsit }
begin
p:=baza;
writeln ('--------------------------------------');
writeln ('Traversare in sens direct');
writeln ('--------------------------------------');
while ( p<>nil ) AND ( p^.data <> '*' ) do
begin
writeln ('NODUL cu cheia= ',p^.cheie,' data= ',p^.data);
p:=p^.urm;
end;
writeln('Ultimul NOD (FANION): cheia= ',p^.cheie,' data= ',p^.data);
end;
procedure TRAVLIST_SFARSIT_INCEP; { traversare lista sfirsit -> inceput }
begin
p:=baza;

q:=p;
p:=p^.urm;
p^.preced := q;

while ( p<>nil ) AND ( p^.data <> '*' ) do


begin

q := p;
p:=p^.urm;
p^.preced := q;

end;

writeln ('--------------------------------------');
writeln ('Traversare in sens invers');
writeln ('--------------------------------------');

while p <> baza do


begin
writeln ('NOD CURENT cheia= ',p^.cheie,' data= ',p^.data);
p:=p^.preced;
end;
writeln('NOD CURENT cheia= ',p^.cheie,' data= ',p^.data);

end; {sfarsit procedura TRAVLIST_SFARSIT_INCEP }


procedure INSEREAZAPRIMUL ; {introduce primul element - la incep. listei }
begin
baza:=nil;
new(p);
write('dati cheia nodului 1 : ');
readln(p^.cheie);
p^.urm:=baza;
baza:=p;
CITDATA;
p^.data:=data
end;

24
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure INSEREAZAREST ; { introduce celelalte elem. }
{ prin tehnica "la sfarsitul listei" }
begin
new (q);
q^.urm:=nil;
p^.urm:=q;
if j<=n then
begin
write('dati cheia nodului ', j,' : ');
readln(q^.cheie);
CITDATA;
q^.data:=data;
p:=q
end
else
begin
q^.cheie:=N+1;
q^.data:='*';

{ NOD FANION - ACEST NOD NU SE VA STERGE }


{ SI NU SE ADAUGA NIMIC DUPA EL }
p := q
end
end;

procedure CAUTA ; { cauta un nod dupa cheie }


var
b:boolean;
begin
b:=false;
write('DATI CHEIA X = ');
readln(x);
writeln;
p:=baza;
while (p<>nil) and not b do
begin
if p^.cheie=x then
b:=true
else
p:=p^.urm
end;
if not b then
writeln('NODUL ( CHEIA ) NU EXISTA ')
else
begin
writeln('PRIMUL NOD CARE ARE CHEIA ',X,' ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln
end
end;

procedure STERGE ;{ sterge un nod indicat printr-o cheie }


begin
q:=p^.urm;
p^:=q^
end;

Begin { PROGRAM PRINCIPAL }


clrscr;
write('Dati nr.de noduri N = ');
readln(n);
writeln;

25
Probleme rezolvate de programare Subiecte propuse la ATESTAT
if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');

INSEREAZAPRIMUL;

writeln
end;
if n > 1 then
begin
for j:=2 to n do
begin

INSEREAZAREST;

writeln
end
end;
j:=j+1;

INSEREAZAREST;
writeln;
writeln(' LISTA parcursa de la INCEPUT la SFIRSIT este : ');

TRAVLISTA_INCEP_SFIRSIT;

writeln;
writeln ('*********************************************');
writeln;
writeln(' LISTA parcursa de la SFIRSIT la INCEPUT este : ');

TRAVLIST_SFIRSIT_INCEP;

writeln;

500: readln
END.

ATESTAT - 2005 - 13 - Se citete de la tastatur un ir de numere ntregi, care se ncheie cu citirea


valorii 0. S se creeze o list liniar simplu nlnuit astfel nct, la parcurgerea listei, elementele
s apar n ordinea n care au fost citite.
a). S se afieze coninutul listei;
b). S se verifice dac elementele listei sunt ordonate cresctor.

Barem:
- declaraii corecte: 1 punct
- crearea listei: 3 puncte
- vizualizarea coninutului: 2 puncte
- algoritm de verificare a ordonrii cresctoare: 3 puncte
- din oficiu: 1 punct

26
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare:
program ATESTAT_2005_13_LISTA_LINIARA_SIMPLU_INLANTUITA_INTREGI;

uses CRT;

label
10,500;
const
nmax = 50;
type

LISTA = ^Nod;
Nod = record
cheie : integer;
data : integer;
urm : LISTA
end;
vector = array [1..nmax] of integer;
var
q, r, baza, p : LISTA;
n, x, i, j : integer;
data : integer;
c : char;
v : vector;
function VERIFICA ( v : vector; q:integer) : boolean;
var
j : integer;

begin
VERIFICA := TRUE;
j := 1;
repeat
if v[j] > v [j+1] then
VERIFICA := FALSE;
j := j + 1
until (j > q-1)
end;

procedure TRAVLISTA ; { traversare in ordinea introducerii }


begin
p:=baza;
while p<>nil do
begin
writeln ('data= ',p^.data);
p:=p^.urm;
end;
end;

Begin { PROGRAM PRINCIPAL }


clrscr;
writeln ('Dati elementele listei');
writeln ('**********************');
i := 0; {contor care numara numerele introduse }
write ('Dati primul element, x = ');
readln (x);
writeln;

27
Probleme rezolvate de programare Subiecte propuse la ATESTAT
If x = 0 then
begin
writeln ('LISTA VIDA');
goto 500
end
else
begin { INSERARE PRIMUL NOD }
i := i + 1;
baza:=nil;
new (p);
p^.urm:=baza;
baza:=p;
p^.data := x;
v [i] := x;
end;
writeln;
writeln ('Dati urmatoarele elemente');
repeat
write ('Dati elementul ', i + 1,' x = ');
readln (x);
if x <> 0 then { INSERARE URMATOARELE NODURI }
begin
i := i + 1;
v [i] := x;
new (q);
q^.urm := nil;
p^.urm := q;
q^.data := x;
p := q
end;
until x = 0;
n := i;
writeln;
writeln ('Lista are ', n, ' elemente');
writeln;
writeln(' LISTA ESTE : ');
TRAVLISTA;
writeln;

if VERIFICA (v, n) = TRUE then


writeln ('Lista este ORDONATA')
else
writeln ('Lista NU este ORDONATA');

500: readln
END.

ATESTAT - 2005 - 14 - S se creeze o list liniar simplu nlnuit format din numere ntregi
introduse de la tastatur. S se afieze coninutul listei, dup care s se realizeze transferul
primului element la sfritul listei.
Exemplu: Dac lista conine iniial elementele 2, 51, 4, 7, 14, 25, 69 (n aceast ordine), dup
transfer coninutul va fi: 51, 4, 7, 14, 25, 69, 2 (n aceast ordine).
Barem:
- declaraii corecte: 1 punct
- crearea listei: 3 puncte
- vizualizarea coninutului: 2 puncte
- realizarea transferului cerut: 3 puncte
- din oficiu: 1 punct

28
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare:
program ATESTAT_2005_14_LISTA_SIMPLU_INLANTUITA;

uses CRT;
label
10, 500;
type
LISTA = ^NOD;
NOD = record
cheie : integer;
data : integer;
urm : LISTA
end;
var
q,r,baza,p: LISTA;
n,x,i,j:integer;
data:integer;
primul, ultimul : integer;
c:char;

procedure CITDATA; { introducere date utile }


begin
write('introduceti datele nodului : ');
readln(data);
end;

procedure TRAVLISTA_INCEP_SFIRSIT ; { traversare lista inceput -> sfirsit }


begin
p:=baza;
writeln ('--------------------------------------');

primul := p^.data;
writeln ('Primul = ', primul);
writeln;
while p <> nil do
begin
writeln ('NODUL cu cheia= ',p^.cheie,' data= ',p^.data);
ultimul := p^.data;
p:=p^.urm;
end;
writeln;

writeln ('Ultimul = ', ultimul);


writeln;

end;

procedure INSEREAZAPRIMUL ; {introduce primul element - la incep. listei }


begin
baza:=nil;
new(p);
write('dati cheia nodului 1 : ');
readln(p^.cheie);
p^.urm:=baza;
baza:=p;
CITDATA;
p^.data:=data
end;

29
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure TRANSFERA ; { insereaza un nod NOU dupa un nod cu cheia cautata }
var
aux : integer;
begin
aux := primul;
primul := ultimul;
ultimul := aux;

end;

procedure INSEREAZAREST ; { introduce celelalte elem. }


{ prin tehnica "la sfirs. listei" }
begin
new (q);
q^.urm:=nil;
p^.urm:=q;
if j<=n then
begin
write('dati cheia nodului ', j,' : ');
readln(q^.cheie);
CITDATA;
q^.data:=data;
p:=q
end
else
begin
q^.cheie:=N+1;
q^.data:= 0;

{ NOD FANION - ACEST NOD NU SE VA STERGE }


{ SI NU SE ADAUGA NIMIC DUPA EL }
p:=q
end
end;

procedure CAUTA ; { cauta un nod dupa cheie }


var
b:boolean;
begin
b:=false;
write('DATI CHEIA X = ');
readln(x);
writeln;
p:=baza;
while (p<>nil) and not b do
begin
if p^.cheie=x then
b:=true
else
p:=p^.urm
end;

if not b then
writeln('NODUL ( CHEIA ) NU EXISTA ')
else
begin
writeln('PRIMUL NOD CARE ARE CHEIA ',X,' ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln
end
end;

30
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure STERGE ;{ sterge un nod indicat printr-o cheie }
begin
q:=p^.urm;
p^:=q^
end;

Begin { PROGRAM PRINCIPAL }


clrscr;
write('dati nr.de noduri N = ');
readln(n);

writeln;
if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end
else
begin
writeln ('INTRODUCETI DATELE NODULUI 1 ');

INSEREAZAPRIMUL;

writeln
end;

if n > 1 then
begin
for j:=2 to n do
begin

INSEREAZAREST;

writeln
end
end;
writeln;
writeln ('Prima traversare a listei');

TRAVLISTA_INCEP_SFIRSIT;

writeln;
writeln ('*********************************************');
writeln;
readln;

TRANSFERA;

writeln;
writeln ('Dupa TRANSFER, avem:');
writeln;
writeln ('Primul = ', primul);
writeln ('Ultimul = ', ultimul);
p := baza;
p^.data := primul;

j := 1;

while (p <> nil) AND (j <> n) do


begin
p:=p^.urm;
j := j + 1;
end;

31
Probleme rezolvate de programare Subiecte propuse la ATESTAT
p^.data := ultimul;

writeln;

writeln ('A doua traversare a listei:');

TRAVLISTA_INCEP_SFIRSIT ;

500: readln
END.

ATESTAT - 2005 - 15 - S se descrie operaia de adugare a unui nou element la o list liniar
simplu nlnuit, implementat dinamic, ce conine caractere n noduri.
Barem:
- declaraii corecte: 1 punct
- crearea listei: 3 puncte
- vizualizarea coninutului: 2 puncte
- adugarea unui element: 3 puncte
- din oficiu: 1 punct

Rezolvare:
program ATESTAT_2005_15_LISTA_LINIARA_SIMPLU_INLANTUITA;
label
10,500;
type
LISTA = ^NOD;
NOD = record
cheie: integer;
data: CHAR;
urm: LISTA
end;
var
p, q, r, baza : LISTA;
n, x, i, j:integer;
data: CHAR;
c: char;

procedure CITDATA; { introducere date utile }


begin
write ('introduceti datele nodului : ');
readln (data);
end;

procedure TRAVLISTA ; { traversare in ordinea introducerii }


begin
p:=baza;
while p<>nil do
begin
writeln(' cheia= ',p^.cheie,' data= ',p^.data);
p:=p^.urm;
writeln
end;
end;

32
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure INSEREAZAPRIMUL ; {introduce primul element - la incep. listei }
begin
baza:=nil;
new(p);
write('dati cheia nodului 1 : ');
readln(p^.cheie);
p^.urm:=baza;
baza:=p;
CITDATA;
p^.data:=data
end;

procedure INSEREAZAREST ; { introduce celelalte elem. - la sfirs. listei }


begin
new (q);
q^.urm:=nil;
p^.urm:=q;
if j<=n then
begin
write('dati cheia nodului ', j,' : ');
readln(q^.cheie);
CITDATA;
q^.data:=data;
p:=q
end
else
begin
q^.cheie:=N+1;
{ q^.data:='ACEST NOD NU SE VA STERGE SI NU SE ADAUGA NIMIC DUPA EL';}
p:=q
end
end;

procedure CAUTA ; { cauta un nod dupa cheie }


var
b:boolean;
begin
b:=false;
write('DATI CHEIA X = ');
readln(x);
writeln;
p:=baza;
while (p<>nil) and not b do
begin
if p^.cheie=x then
b:=true
else
p:=p^.urm
end;
if not b then
writeln('NODUL ( CHEIA ) NU EXISTA ')
else
begin
writeln('PRIMUL NOD CARE ARE CHEIA ',X,' ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln
end
end;
procedure STERGE ;{ sterge un nod indicat printr-o cheie }
begin
q:=p^.urm;
p^:=q^
end;

33
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
write('dati nr.de noduri N = ');
readln(n);
writeln;
if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');
INSEREAZAPRIMUL;
writeln
end;
if n > 1 then
begin
for j:=2 to n do
begin
INSEREAZAREST;
writeln
end
end;
j:=j+1;
writeln('INTRODUCETI NODUL F A N I O N ');
INSEREAZAREST;
writeln;
writeln(' LISTA ESTE : ');
TRAVLISTA;
writeln;
10: write('DORITI SA CAUTATI UN NOD ? APASATI D SAU N ');
readln(c);
if (c='d') or (c='D') then
begin
CAUTA
end;
writeln;
write('DORITI SA STERGETI UN NOD ? APASATI D SAU N ');
readln(c);
writeln;
if (c='d') or ( c='D') then
begin
CAUTA;
writeln('CONTINUT NOD CU CHEIA ',X,' INAINTE DE STERGERE ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln;
STERGE;
writeln;
writeln('CONTINUTUL NODULUI DUPA STERGERE ESTE :');
writeln(p^.cheie,' ',p^.data);
writeln;
writeln('LISTA DUPA STERGEREA NODULUI CU CHEIA ',X,' ESTE :');
TRAVLISTA;
writeln
end; { sfarsit IF }
write('DORITI SA RELUATI PROGRAMUL ? APASATI D SAU N ');
readln(c);
writeln;
if ( c='d') or ( c='D') then goto 10;
500: readln
END.

34
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 16 - S se realizeze operaiile de creare i vizualizare a unei liste circulare.
Barem:
- declaraii corecte: 1 punct
- crearea listei: 4 puncte
- vizualizarea coninutului: 4 puncte
- din oficiu: 1 punct

Rezolvare:
program ATESTAT_2005_16_LISTA_CIRCULARA;
label
10,500;
type
LISTA = ^NOD;
NOD = record
cheie : integer;
data : integer;
urm : LISTA
end;
var
q, r, baza, p : LISTA;
n, x, i, j : integer;
data : integer;
c : char;

procedure CITDATA; { introducere date utile }


begin
write ('introduceti datele nodului : ');
readln (data);
end;

procedure TRAVLISTA ; { traversare lista in ordinea introducerii }


begin
p:=baza;

while p^.cheie < n do


begin
writeln(' cheia= ',p^.cheie,' data= ',p^.data);
p:=p^.urm;
writeln
end;

{afisare ultim nod


writeln(' cheia= ',p^.cheie,' data= ',p^.data);
end;

procedure INSEREAZAPRIMUL ; {introduce primul element - la incep. listei }


begin
baza:=nil;
new(p);
write('dati cheia nodului 1 : ');
readln(p^.cheie);
p^.urm:=baza;
baza:=p;
CITDATA;
p^.data:=data
end;

35
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure INSEREAZAREST ; { introduce celelalte elem. - la sfirs. listei }
begin
new (q);
q^.urm:=nil;
p^.urm:=q;
if j <= n then
begin
write ('dati cheia nodului ', j,' : ');
readln (q^.cheie);
CITDATA;
q^.data := data;
p := q
end
end;
procedure CAUTA ; { cauta un nod dupa cheie }
var
b:boolean;
begin
b:=false;
write('DATI CHEIA X = ');
readln(x);
writeln;
p:=baza;
while (p<>nil) and not b do
begin
if p^.cheie=x then
b:=true
else
p:=p^.urm
end;
if not b then
writeln('NODUL ( CHEIA ) NU EXISTA ')
else
begin
writeln('PRIMUL NOD CARE ARE CHEIA ',X,' ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln
end
end;

procedure STERGE ;{ sterge un nod indicat printr-o cheie }


begin
q:=p^.urm;
p^:=q^
end;

Begin { PROGRAM PRINCIPAL }


write('dati nr.de noduri N = ');
readln(n);
writeln;

if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');
INSEREAZAPRIMUL;
writeln
end;

36
Probleme rezolvate de programare Subiecte propuse la ATESTAT
if n > 1 then
begin
for j:=2 to n do
begin
INSEREAZAREST;
writeln
end
end;
q^.urm := baza;
{ j:=j+1;}
writeln ('INTRODUCETI NODUL F A N I O N ');
INSEREAZAREST;

writeln;
writeln (' LISTA ESTE : ');
TRAVLISTA;
writeln;
500: readln
END.

ATESTAT - 2005 - 17 - S se realizeze operaia de eliminare a unui element dintr-o list simplu
nlnuit, implementat dinamic, ce conine numere ntregi citite de la tastatur. S se afieze lista
nainte i dup tergerea elementului.
Barem:
- declaraii i citire: 1 punct
- crearea listei : 3 puncte
- tergerea unui element: 3 puncte
- afiarea listei: 2 punct
- din oficiu: 1 punct

Rezolvare:
program ATESTAT_2005_17_LISTA SIMPLU INLANTUITA;
label
10,500;
type
LISTA = ^NOD;
NOD = record
cheie : integer;
data : integer;
urm : LISTA
end;
var
q, r, baza, p : LISTA;
n, x, i, j : integer;
data : integer;
c : char;

procedure CITDATA; { introducere date utile }


begin
write ('introduceti datele nodului : '); readln (data);
end;

37
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure TRAVLISTA ; { traversare in ordinea introducerii }
begin
p:=baza;
while p<>nil do
begin
writeln(' cheia= ',p^.cheie,' data= ',p^.data);
p:=p^.urm;
writeln
end;
end;
procedure INSEREAZAPRIMUL ; {introduce primul element - la incep. listei }
begin
baza:=nil;
new(p);
write('dati cheia nodului 1 : '); readln(p^.cheie);
p^.urm:=baza;
baza:=p;
CITDATA;
p^.data:=data
end;
procedure INSEREAZAREST ; { introduce celelalte elem. - la sfirs. listei }
begin
new (q);
q^.urm:=nil;
p^.urm:=q;
if j<=n then
begin
write('dati cheia nodului ', j,' : '); readln(q^.cheie);
CITDATA;
q^.data:=data;
p:=q
end
else
begin
q^.cheie:=N+1;
{ q^.data:='ACEST NOD NU SE VA STERGE SI NU SE ADAUGA NIMIC DUPA EL'; }
p:=q
end
end;
procedure CAUTA ; { cauta un nod dupa cheie }
var
b:boolean;
begin
b:=false;
write('DATI CHEIA X = '); readln(x);
writeln;
p:=baza;
while (p<>nil) and not b do
begin
if p^.cheie=x then
b:=true
else
p:=p^.urm
end;
if not b then
writeln('NODUL ( CHEIA ) NU EXISTA ')
else
begin
writeln('PRIMUL NOD CARE ARE CHEIA ',X,' ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln
end
end;

38
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure STERGE ;{ sterge un nod indicat printr-o cheie }
begin
q:=p^.urm;
p^:=q^
end;
Begin { PROGRAM PRINCIPAL }
write('dati nr.de noduri N = '); readln(n);
writeln;
if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');
INSEREAZAPRIMUL;
writeln
end;
if n > 1 then
begin
for j:=2 to n do
begin
INSEREAZAREST;
writeln
end
end;
j:=j+1;
writeln('INTRODUCETI NODUL F A N I O N ');
INSEREAZAREST;
writeln;
writeln(' LISTA ESTE : ');
TRAVLISTA;
writeln;
10: write('DORITI SA CAUTATI UN NOD ? APASATI D SAU N ');
readln(c);
if (c='d') or (c='D') then
begin
CAUTA
end;
writeln;
write('DORITI SA STERGETI UN NOD ? APASATI D SAU N ');
readln(c);
writeln;
if (c='d') or ( c='D') then
begin
CAUTA;
writeln('CONTINUT NOD CU CHEIA ',X,' INAINTE DE STERGERE ESTE ');
writeln(p^.cheie,' ',p^.data);
STERGE;
writeln;
writeln('CONTINUTUL NODULUI DUPA STERGERE ESTE :');
writeln(p^.cheie,' ',p^.data);
writeln('LISTA DUPA STERGEREA NODULUI CU CHEIA ',X,' ESTE :');
TRAVLISTA;
end;
write('DORITI SA RELUATI PROGRAMUL ? APASATI D SAU N ');
readln (c);
writeln;
if ( c='d') or ( c='D') then goto 10;
500: readln
END.

39
Probleme rezolvate de programare Subiecte propuse la ATESTAT

GRAFURI

ATESTAT - 2005 - 18 - Se d un graf neorientat G la care:


- n = numrul de vrfuri (n, numr natural pozitiv);
- pentru fiecare vrf se cunosc vrfurile adiacente cu el;
S se scrie un program prin care s se afieze:
a). gradul fiecrui vrf (nod);
b). lista tuturor vrfurilor de grad maxim;
c). numrul de vrfuri izolate;
d). numrul de muchii din graf.
Barem:
- declaraii i introducere corect a grafului: 1 punct
- realizarea punctului a): 2 puncte
- realizarea punctului b): 2 puncte
- realizarea punctului c): 2 puncte
- realizarea punctului d): 2 puncte
- din oficiu: 1 punct

Rezolvare:
Considerm urmtorul graf neorientat:
Graful are 5 noduri (vrfuri), 2 5
notate cu 1, 2, 3, 4, 5 i 1
4 muchii, notate cu
[2,3], [2,4], [3,4] i [4,5]. 3 4
n general, la un graf neorientat cu n vrfuri, matricea de adiacen A este o matrice
ptratic de ordinul n, simetric, cu elementele:
1, dac [i, j] este muchie n graf ; nodurile i i j sunt extremitile muchiei
A [i, j] =
0, n caz contrar
Este uor de observat c elementele de pe diagonala principal sunt nule (A [i, i] = 0), deoarece [i,
i] NU este muchie n graf..
Matricea de adiacen asociat grafului de mai sus este:
1 2 3 4 5
1 0 0 0 0 0
2 0 0 1 1 0
A (5, 5) = 3 0 1 0 1 0
4 0 1 1 0 1
5 0 0 0 1 0
n program, matricea de adiacen se va construi astfel:
I - Se face iniializarea tuturor elementelor matricii cu zero (n acest fel, anulm att elementele
diagonalei principale, ct i elementele matricii care nu se asociaz muchiilor). Vom scrie:
For i := 1 to n do
For j := 1 to n do
A [i, j] := 0;
II A Dac se cunoate numrul muchiilor. Notm cu [x, y] o muchie din graf, unde x i y sunt
extremitile muchiei (dou noduri ale grafului). n matricea de adiacen, elementul A [x, y] = 1.
Cum matricea de adiacen este i simetric, rezult cu i A [y, x] = 1. Notnd cu m numrul de
muchii din graf, vom folosi o structur FOR n care, pentru fiecare muchie i, vom introduce
extremitile x i y. Evident, aceste extremiti sunt vrfuri n graf. Vom scrie:

40
Probleme rezolvate de programare Subiecte propuse la ATESTAT
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:)
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1;
A [y, x] := 1;{matrice simetric}
End;
II B Dac NU se cunoate numrul muchiilor (este cazul problemei noastre), dar, pentru
fiecare vrf, se cunosc vrfurile adiacente cu el (se cunosc vecinii fiecrui vrf). Notm cu x,
respectiv cu y dou vrfuri din graf. Evident, att x ct i y iau valori ntre 1 i n (n = numrul total
de vrfuri din graf). Pentru fiecare nod x, trebuie s precizm numrul vecinilor si, precum i care
sunt acetia. n program vom scrie:
For x := 1 to n do
begin
write (Ci vecini are x, nrvecini = );
readln (nr);
For i := 1 to nrvecini do
begin
write (Dai urmtorul vecin, y = );
readln (y);
A [x, y] := 1;
A [y, x] := 1
end;
end;

a Gradul unui vrf v, se noteaz cu d(x) i este dat de numrul muchiilor incidente cu v. n
program vom folosi un vector notat cu d, cu 5 elemente (5 = numrul de noduri), fiecare element
reprezentnd gradul unui nod (vrf). Pentru cazul particular al grafului de mai sus, avem:
d (1) = 0 d (2) = 2 d (3) = 2 d (4) = 3 d (5) = 1
Se observ c gradul unui nod icoincide cu numrul de cifre de 1 de pe linia i din
matricea de adiacen. Prin urmare, pentru a determina gradul unui nod, numrm cifrele de 1 de pe
fiecare linie a matricii de adiacen i reinem aceste numere n elementele vectorului d.

b Determinm gradul maxim (elementul maxim din vectorul d) i afim doar numerele
nodurilor al cror grad = gradul maxim.

c Un vrf izolat are gradul zero. n matricea de adiacen, unui nod izolat i corespunde o linie,
respectiv o coloan cu toate elementele egale cu zero. Pentru a determina numrul de vrfuri izolate,
numrm liniile din matricea de adiacen care au toate elementele nule.

d Fiecare muchie [x, y] contribuie cu o unitate (1) la gradul nodului x i cu o unitate (1) la gradul
nodului y, deci cu dou uniti (2) la suma gradelor tuturor nodurilor. Cum n graf sunt m muchii,
rezult c suma gradelor tuturor nodurilor = 2m. De aici rezult m.

program ATESTAT_2005_18_GRAF_NEORIENTAT;
uses CRT;
CONST
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
matrice = array [1..nmax, 1..nmax] of integer;

41
Probleme rezolvate de programare Subiecte propuse la ATESTAT
VAR
n : integer; {n = numarul nodurilor}
i, j : integer;
x, y : integer; {noduri in graf, extremiti ale unei muchii}
A : matrice; {matricea de adiacenta}
d : vector; {vectorul care contine "gradele" fiecarui nod din graf}
nrvecini : integer; {numarul de vecini ai unui nod}
nrcifre1 : integer; {numarul de cifre egale cu 1 din matricea de adiacenta}
gradmax : integer; {gradul maxim al unui nod}
nrcifrezero : integer; {numarul cifrelor egale cu zero din matricea de
adiacenta}
nrnodurigradzero : integer; {numarul nodurilor cu gradul zero}
sumagrade : integer; {suma gradelor tuturor nodurilor}
m : integer; {numarul de muchii din graf}

Begin { PROGRAM PRINCIPAL }


CLRSCR;
write ('Dati numarul de noduri, n = ');
readln (n);

{Initializarea tuturor elementelor matricii de adiacenta cu zero}

for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0
end;
end;
writeln;

{Completare matrice de adiacenta}


For x := 1 to n do
begin
write ('Cati vecini are nodul ',x, ' ? Dati nrvecini = ');
readln (nrvecini);
For i := 1 to nrvecini do
begin
write ('Pentru nodul ', x,', dati urmatorul vecin, y = ');
readln (y);
A [x, y] := 1;
A [y, x] := 1
end;
writeln;
end;
writeln;

{a - Determinare grade varfuri}


for i:= 1 to n do {i = index linie in matricea de adiacenta}
begin
nrcifre1 := 0;
for j := 1 to n do {j = index coloana in matricea de adiacenta}
begin
if A [i, j] = 1 then
nrcifre1 := nrcifre1 + 1;
end;
d [i] := nrcifre1;
writeln ('gradul nodului ', i,' = ', d [i] );
end;
writeln;

42
Probleme rezolvate de programare Subiecte propuse la ATESTAT
{b - Determinam gradul maxim si afisam nodurile cu gradul maxim}
gradmax := d [1];
for i := 2 to n do
begin
if gradmax < d [i] then
gradmax := d [i]
end;
writeln ('Gradul maxim = ', gradmax);
writeln;
for i := 1 to n do
begin
if d [i] = gradmax then
writeln ('Nodul ', i,' are gradul maxim = ', gradmax);
end;
writeln;

{c Determinare noduri cu grad zero}


nrnodurigradzero := 0;
for i := 1 to n do
begin
nrcifrezero := 0;
for j := 1 to n do
begin
if A [i, j] = 0 then
nrcifrezero := nrcifrezero + 1;
end;
if nrcifrezero = n then
nrnodurigradzero := nrnodurigradzero + 1;
end;
writeln ('Graful are ', nrnodurigradzero,' noduri cu gradul zero');
writeln;

{d Determinare numar muchii = m}


sumagrade := 0;
for i := 1 to n do
begin
sumagrade := sumagrade + d [i]
end;
m := sumagrade DIV 2;
writeln ('Graful are ', m,' muchii');
readln
end.

ATESTAT - 2005 - 19 - Se d un graf neorientat G cu n vrfuri i m muchii (n i m sunt numere


naturale introduse de la tastatur). S se scrie un program care s verifice dac graful este complet.
Barem:
- declaraii corecte de variabile: 1 punct
- reprezentarea corect a grafului prin matricea de adiacen: 3 puncte
- realizarea algoritmului de prelucrare: 3 puncte
- afiarea rezultatului : 2 puncte
- din oficiu: 1 punct

Rezolvare:
Un graf este complet dac oricare dou noduri sunt adiacente (sunt legate ntre ele printr-o
muchie). Altfel spus, n matricea de adiacen, notat cu A, doar elementele de pe diagonala
principal sunt nule, celelalte elemente sunt egale cu 1, adic matricea are n2 n = n (n 1)
elemente egale cu 1.

43
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Altfel spus, fiecare nod are gradul n 1. Cum graful conine n noduri, rezult c suma
gradelor tuturor nodurilor este = n (n 1) = 2m.
Prin urmare, problema s-ar putea rezolva foarte simplu verificnd dac n (n 1) = 2m, avnd
n vedere c n i m sunt cunoscute (sunt date de intrare).
Presupunnd c nu dorim s verificm doar relaia de mai sus, vom face verificri asupra
matricii de adiacen A:
a - fie vom numra elementele egale cu 1 din matrice i vom verifica dac numrul total de elemente
egale cu 1 este egal cu n (n 1),
b - fie vom verifica dac, n matricea de adiacen, numai elementele diagonalei principale sunt nule.
Notm cu [x, y] o muchie din graf, unde x i y sunt extremitile muchiei (dou noduri ale
grafului). n matricea de adiacen, elementul A [x, y] = 1. Cum matricea de adiacen este i
simetric, rezult cu i A [y, x] = 1. Deoarece se cunoate numrul muchiilor (m), vom folosi o
structur FOR n care, pentru fiecare muchie i, vom introduce extremitile x i y. Evident,
aceste extremiti sunt vrfuri n graf. Vom scrie:
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:)
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1;
A [y, x] := 1;{matrice simetric}
End;

program ATESTAT_2005_19_GRAF_NEORIENTAT;
uses CRT;
CONST
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
matrice = array [1..nmax, 1..nmax] of integer;
VAR
n : integer; {n = numarul nodurilor}
m : integer; {numarul de muchii din graf}
x, y : integer; {noduri in graf, extremiti ale unei muchii}
A : matrice; {matricea de adiacenta}
nrcifre1 : integer; {numarul de cifre egale cu 1 din matricea de adiacenta}
nrcifrezero : integer; {numarul cifrelor egale cu zero din matricea de
adiacenta}
i, j : integer;

Begin { PROGRAM PRINCIPAL }


CLRSCR;
write ('Dati numarul de noduri, n = ');
readln (n);

{Initializarea tuturor elementelor matricii de adiacenta cu zero}

for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0
end;
end;
writeln;

44
Probleme rezolvate de programare Subiecte propuse la ATESTAT
{Completare matrice de adiacenta}
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:)
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1;
A [y, x] := 1; {matricea este simetric}
End;
writeln;
-------------------------------------------------------------------------------
{Varianta a - Numrarea cifrelor de 1 din matricea de adiacen}
nrcifre1 := 0;

for i:= 1 to n do {i = index linie in matricea de adiacenta}


begin
for j := 1 to n do {j = index coloana in matricea de adiacenta}
begin
if A [i, j] = 1 then
nrcifre1 := nrcifre1 + 1;
end;
end;
writeln;

if nrcifre1 = n (n 1) then
writeln (Graful este complet)
else
writeln (Graful este incomplet);
-------------------------------------------------------------------------------
{Varianta b - Numrarea cifrelor de zero din matricea de adiacen}
nrcifrezero := 0;
for i:= 1 to n do {i = index linie in matricea de adiacenta}
begin
for j := 1 to n do {j = index coloana in matricea de adiacenta}
begin
if A [i, j] = 0 then
nrcifrezero := nrcifrezero + 1;
end;
end;
writeln;
if nrcifrezero = n then
writeln (Graful este complet)
else
writeln (Graful este incomplet);
-------------------------------------------------------------------------------
readln
end.

ATESTAT - 2005 - 20 - Fie G un graf neorientat dat prin numrul de vrfuri i numrul de muchii
(n, respectiv m, numere naturale introduse de la tastatur). S se scrie un program care s verifice
dac graful conine un ciclu de lungime 4.
Barem:
- declaraii corecte de variabile: 1 punct
- reprezentarea corect a grafului prin matricea de adiacen: 3 puncte
- realizarea algoritmului de prelucrare: 3 puncte
- afiarea rezultatului : 2 puncte
- din oficiu: 1 punct

45
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare:
Un ciclu elementar are proprietatea c oricare dou vrfuri ale sale, cu excepia primului i
ultimului, sunt diferite dou cte dou. Lungimea unui ciclu = numrul de muchii ce apar n ciclu.
Considernd graful din figura de mai jos, se poate observa uor ciclul 1 2 3 4 1 care
are lungimea 4. Matricea de adiacen a grafului este urmtoarea:
k
2 Nod 1 2 3 4 5
i=1 0 1 0 1 0
1 2 1 0 1 0 1
3 j=3 0 1 0 1 0
4 1 0 1 0 0
5 4
5 0 1 0 0 0

Trebuie doar s se verifice dac exist cicluri de lungime 4 (NU se cere generarea acestora).
Pentru ciclul de lungime 4 identificat n graf (1 2 3 4 1), n matricea de adiacen,
liniile corespunztoare nodurilor 1 i 3 conin amndou cifra 1 pe poziiile k = 2 i k = 4.
De asemenea, liniile corespunztoare nodurilor 2 i 4 conin amndou cifra 1 pe poziiile
k = 1 i k = 3.
Va trebui s verificm dac, pentru fiecare pereche de noduri distincte, liniile (din matricea
de adiacen) corespunztoare acestor noduri conin cifra 1 pe cel puin 2 poziii (coloane) identice.
Notm cu i, respectiv j dou linii distincte din matricea de adiacen, linii
corespunztoare a dou noduri i i j. Evident, i = 1 .. n-1, iar j = i + 1 .. n.
Notm cu k indexul de coloan (din matricea de adiacen) pentru care se face testarea
perechii A [i, k] i A [j, k]. Iniializm un contor nrcifre care numr cifrele de 1, n condiia
( A [i, k] = 1 ) AND ( A [j, k] = 1 ).

program ATESTAT_2005_20_GRAF_CU_UN_CICLU_DE_LUNGIME_PATRU ;
uses CRT;
LABEL
sfarsit;
CONST
nmax = 100;
TYPE
matrice = array [1..nmax, 1..nmax] of integer;
VAR
n : integer; {n = numarul nodurilor}
m : integer; {numarul de muchii din graf}
x, y : integer; {noduri in graf, extremiti ale unei muchii}
A : matrice; {matricea de adiacenta}
i, j, k : integer;
nrcifre : integer; {numara cifrele de 1, in conditiile problemei}
GASIT : boolean; {GASIT = TRUE daca s-a gasit un ciclu de lungime 4}
Begin { PROGRAM PRINCIPAL }
CLRSCR;
write ('Dati numarul de noduri, n = ');
readln (n);
write ('Dati numarul de muchii, m = ');
readln (m);
{Initializarea tuturor elementelor matricii de adiacenta cu zero}
for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0
end;
end;
writeln;

46
Probleme rezolvate de programare Subiecte propuse la ATESTAT
{Completare matrice de adiacenta}
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:)
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1;
A [y, x] := 1; {matricea este simetric}
End;
writeln;
-------------------------------------------------------------------------------
GASIT := FALSE; {presupunem ca nu exista un ciclu de lungime 4}
for i := 1 to n 1 do {i = index elemente de pe una din liniile testate}
begin
for j := i + 1 to n do {j = index elemente de pe alta linie testata}
begin
nrcifre := 0; {initializare contor pt. fiecare pereche testata}
for k := 1 to n do {k = index de coloana}
begin
if ( A [i, k] = 1 ) AND ( A [j, k] = 1 ) then
nrcifre := nrcifre + 1;
if nrcifre >= 2 then
begin
GASIT := TRUE;
GOTO sfarsit
end;
end;
end;
end;
sfarsit: if GASIT = TRUE then
writeln (Graful contine cicluri de lungime 4)
else
writeln (Graful NU contine cicluri de lungime 4);
readln
END.

ATESTAT - 2005 - 21 - Pentru un graf orientat G cu n vrfuri i m arce (n i m numere naturale


citite la intrare) s se scrie un program care s determine matricea drumurilor. Matricea se va afia
pe ecran linie cu linie.
Barem:
- declaraii corecte de variabile: 1 punct
- reprezentarea corect a grafului prin matricea de adiacen: 3 puncte
- determinarea matricii drumurilor prin algoritmul lui Roy-Warshall: 3 puncte
- afiarea matricii drumurilor: 2 puncte
- din oficiu: 1 punct

Rezolvare:
a1 Reamintim cteva noiuni din teoria grafurilor orientate.
Un lan ( L ) ntr-un graf orientat = un ir de arce L = [a1 , a2 ,
1 2 ak , , ap], cu proprietatea c oricare arc ak are un nod comun cu
a4
a5 a2 ak-1 i cellalt nod comun cu ak+1 , pentru orice k din mulimea {
2, p-1}. NU ARE IMPORTAN ORIENTAREA ARCELOR.
a3 Exemplu: Pentru graful din figura alturat, lanuri cu extremitile
4 3 n nodurile 1 i 4 sunt:
L1 = (a1, a2, a3), L2 = (a1, a4, a5, a3), L3 = (a5, a3) se observ c
nu are importan orientarea arcelor.

47
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Un lan ntr-un graf orientat se numete drum (notat D) dac toate arcele sale au ACEEAI
ORIENTARE, dat de sensul deplasrii de la x0 (extremitatea iniial a lui a1) la xp (extremitatea
final a lui ap). Vrfurile x0 i xp = extremitile lanului. De observat c, n cazul drumului,
ARE IMPORTAN ORIENTAREA ARCELOR
Altfel spus, un drum ntr-un graf orientat este un ir de vrfuri. Un drum se poate scrie fie
ca o succesiune de arce, fie ca o succesiune de vrfuri. Pentru graful alturat, avem drumurile:
D1 = (1, 2, 3), D2 = (1, 2, 1, 3).
Matricea drumurilor unui graf G este o matrice B definit astfel:
1, dac exist drum n G
B [i, j] = de la nodul xi la nodul xj
0, n caz contrar.
Pentru graful anterior, avem:
Matricea de ADIACEN: Matricea DRUMURILOR:

Nod 1 2 3 4 Nod 1 2 3 4
1 0 1 1 0 1 1 1 1 0
A = 2 1 0 1 0 B = 2 1 1 1 0
3 0 0 0 0 3 0 0 0 0
4 0 0 1 0 4 0 0 1 0
Algoritmul Roy-Warshall determin matricea drumurilor plecnd de la matricea de
adiacen astfel:
Un element A [i, j] = 0 din matricea de adiacen devine 1 n matricea drumurilor dac
exist un vrf k astfel nct
A [i, k] = 1 i A [k, j] = 1,
adic atunci cnd exist drum de la xi la xk i drum de la xk la xj. Aceast condiie se poate exprima
i astfel:
A [i, j] = MIN ( A[i, k], A [k, j] )
sau
A [i, j] = A[i, k] * A [k, j].
Transformarea propriu-zis pe care o presupune algoritmul Roy-Warshall poate fi
exprimat astfel:
for k := 1 to n do
begin
for i := 1 to n do
begin
if i <> k then
begin
for j := 1 to n do
begin
if j <> k then
begin
IF A [i, j] = 0 then
A [i, j] := A [i, k] * A [k, j]
end
end
end
end
end;

48
Probleme rezolvate de programare Subiecte propuse la ATESTAT
program ATESTAT_2005_21_MATRICEA_DRUMURILOR_ALGORITMUL_ROY_WARSHALL;
uses CRT;
CONST
nmax = 100;
TYPE
matrice = array [1..nmax, 1..nmax] of integer;
VAR
n, m : integer; {n = numarul nodurilor; m = numarul de muchii din graf }
x, y : integer; {extremitati ale unei muchii}
A : matrice; {matricea de adiacenta}
B : matrice; {matricea drumurilor}
i, j, k : integer;
function MIN ( alfa, beta : integer) : integer;
begin
if alfa <= beta then
MIN := alfa
else
MIN := beta
end;
Begin { PROGRAM PRINCIPAL }
CLRSCR;
write ('Dati numarul de noduri, n = ');
readln (n);
write ('Dati numarul de muchii, m = ');
readln (m);
{Initializarea tuturor elementelor matricii de adiacenta cu zero}
for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0
end;
end;
writeln;
{Completare matrice de adiacenta}
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:);
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1; {matricea NU este simetric}
End;
writeln;
writeln ('Matricea de ADIACENTA este:');
for i := 1 to n do
begin
writeln;
for j := 1 to n do
begin
write ( A [i, j] : 3 ); {se lasa 3 pozitii pentru fiecare }
{element al matricii }
end;
end;
writeln;
{ Deoarece se pleaca de la matricea de ADIACENTA A, si pentru a nu afecta }
{aceasta matrice, Initializam matrice DRUMURI B, cu matricea de ADIACENTA - A}
for i := 1 to n do
begin
for j := 1 to n do
begin
B [i, j] := A [i, j];
end;
end;

49
Probleme rezolvate de programare Subiecte propuse la ATESTAT
{Transformarea propriu-zisa - Algoritmul Roy-Warshall}
{VARIANTA 1}

for k := 1 to n do
begin
for i := 1 to n do
begin
if i <> k then
begin
for j := 1 to n do
begin
if j <> k then
begin
IF B [i, j] = 0 then
B [i, j] := MIN (B [i, k], B [k, j])
end
end
end
end
end;

writeln ('Varianta 1 - Matricea drumurilor este:');


for i := 1 to n do
begin
writeln;
for j := 1 to n do
begin
write ( B [i, j] : 3 ); {se lasa 3 pozitii pentru fiecare }
{element al matricii }
end;
end;

{Transformarea propriu-zisa - Algoritmul Roy-Warshall}


{VARIANTA 2}

for k := 1 to n do
begin
for i := 1 to n do
begin
for j := 1 to n do
begin
IF B [i, j] = 0 then
B [i, j] := B [i, k] * B [k, j]
end
end
end;
writeln;

writeln ('Varianta 2 - Matricea drumurilor este:');


for i := 1 to n do
begin
writeln;
for j := 1 to n do
begin
write ( B [i, j] : 3 ); {se lasa 3 pozitii pentru fiecare }
{element al matricii }
end;
end;
readln
END.

50
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 22 - Pentru un graf orientat G cu n vrfuri i m arce (n i m sunt numere
naturale citite la intrare), s se scrie un program care s construiasc i s afieze listele de adiacen
ale succesorilor vrfurilor grafului sub form de liste liniare simplu nlnuite.
Barem:
- declaraii corecte de variabile: 2 puncte
- generarea listelor de adiacen: 4 puncte
- afiarea listelor: 3 puncte
- din oficiu: 1 punct
Rezolvare:
Pentru reprezentarea grafurilor orientate se pot folosi
a matricea de adiacen
b listele de adiacen.
La reprezentarea prin liste de adiacen, pentru orice vrf x se construiete o list L ( x ) a
succesorilor vrfului x. Liste de adiacen pot fi reprezentate folosind tablouri sau structuri
dinamice de date.
Exemplu: pentru graful alturat, listele de adiacen L vor fi:

1 4 5 1 2 NIL Nod Succesori


1: 2
2 3 NIL 2: 3
2 3 3 4 5 NIL 3: 4, 5
4: 1, 5
4 1 5 NIL 5:
5 NIL
La reprezentarea listelor de adiacen folosind structuri dinamice de date (liste liniare
nlnuite), vom considera un vector L (LISTA) cu n componente de tip pointer (referin, adres).
O component L [ i ] va pointa la nceputul listei de adiacen a nodului i.
Un arc (x, y) al grafului este reprezentat prin extremitile x i y,
Fiecare element al listei va avea dou componente:
- NodSuccesor = y = extremitatea final a nodului curent
- URM = informaia de legtur ctre urmtorul element al listei de adiacen.
Vom face urmtoarele declaraii:
TYPE
LISTA = ^ element;
element = RECORD
NodSuccesor : 1 . . n;
URM : LISTA
END;
VAR
L : array [ 1 . . n ] of LISTA ;
P : LISTA ; {variabil pointer de lucru }
n, m, i : integer ;
Iniializm toate componentele listei L cu pointerul NIL, scriind:
for i := 1 to n do
L [i] := NIL;
Prezena n graf a unui arc (x, y) presupune crearea unei locaii de memorie cu NEW (P), urmat de
calificarea celor dou cmpuri (NodSuccesor i URM) ale noii locaii. Vom scrie:
P^. NodSuccesor := y ;
P^.URM := L [ x ] ;
L [ x ] := P ;

51
Probleme rezolvate de programare Subiecte propuse la ATESTAT
program ATESTAT_2005_22_LISTE_DE_ADIACENTA ;
uses CRT;
CONST
nmax = 100;
TYPE
LISTA = ^ELEMENT;
ELEMENT = RECORD
NodSuccesor : integer;
URM : LISTA {pointer de legatura spre urmatorul nod din lista}
END;
VAR
L : array [1..nmax] of LISTA;
m, n, i : integer; { n = nr. de NODURI; m = nr. de ARCE }
P : LISTA ; { P = pointer de lucru}
x, y : integer; { x, y = extremitatile unui arc }

Begin { PROGRAM PRINCIPAL }


CLRSCR;
write ('Dati numarul de noduri, n = ');
readln (n);
writeln;
write ('Dati numarul de muchii, m = ');
readln (m);
writeln;
{ Initializam toate componentele listelor de ADIACENTA cu pointerul NIL }
for i := 1 to n do
begin
L [i] := NIL;
end;
writeln;
{Completarea LISTELOR de adiacenta}
For i := 1 to m do
Begin
Writeln ('Dati extremitatile muchiei i:');
Write ('Dati varful x = ');
readln (x);
Write ('Dati varful y = ');
readln (y);

NEW (P);
P^.NodSuccesor := y ;
P^.URM := L [x];
L [x] := P;

End;
writeln;

{Afisarea listelor de adiacenta pentru cele n noduri}


for i:= 1 to n do
begin
write ('Nodul ',i,' are urmatorii succesori : ');
P := L [i]; {P indic initial spre inceputul listei nodului i }
while P <> NIL do
begin
write (p^.NodSuccesor,' -> ');
P := P^.URM
end;
write (' NIL');
writeln;
writeln
end;
readln
END.

52
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 23 - Dat un graf orientat G cu n vrfuri i m arce, s se scrie un program prin
care:
a) s se calculeze gradul interior, respectiv exterior al fiecrui vrf
b) s se verifice dac graful are vrfuri izolate
Datele de intrare se preiau din fiierul text INPUT.TXT sub forma urmtoare :
pe prima linie: n - reprezentnd numrul de vrfuri ale grafului ;
pe linia a doua : m - reprezentnd numrul de arce ale grafului ;
pe urmtoarele m linii, cte o pereche de numere, separate printr-un spaiu, ce reprezint
extremitatea iniial, respectiv final a arcului.
Rezultatele se vor afia pe ecran.
Barem:
- declaraii corecte de variabile: 1 punct
- citirea corect a datelor din fiier: 1 punct
- reprezentarea corect a grafului prin matricea de adiacen: 2 puncte
- realizarea punctului a): 2 puncte
- realizarea punctului b): 2 puncte
- afiarea rezultatelor: 1 punct
- din oficiu: 1 punct

Rezolvare:
Vom reprezenta graful prin listele de adiacen (vezi problema anterioar ATESTAT_2005_22).
Folosim 2 vectori GradExt, respectiv GradInt, fiecare cu cte n componente, n care vom memora
gradul exterior i interior al fiecrui vrf. Dac pentru un vrf suma celor dou grade este zero,
acel vrf este izolat.
1 4 5
Exemplu: pentru graful alturat, fiierul
GRAF.TXT, de pe discul C:, va avea
coninutul:
6 {numrul de noduri} 2 3 6
8 {numrul de arce}
1 2 NOD GradExt GradInt Suma grade
1 3 1 2 1 3
2 3 2 2 1 3
2 4 3 2 2 4
3 4 4 2 2 4
3 5 5 0 2 2
4 1 6 0 0 0
4 5
De asemenea, se observ c vrful 6 este izolat.
program ATESTAT_2005_23_GRADE_INT_SI_EXT_CU_LISTE_DE_ADIACENTA ;
uses CRT;
CONST
nmax = 100;
TYPE
LISTA = ^ELEMENT;
ELEMENT = RECORD
NodSuccesor : integer;
URM : LISTA {pointer de legatura spre urmatorul nod din lista}
END;
VAR
L : array [1..nmax] of LISTA;
m, n, i : integer; { n = nr. de NODURI; m = nr. de ARCE }
P : LISTA ; { P = pointer de lucru}
x, y : integer; { x, y = extremitatile unui arc }
GradInt, GradExt : array [1..nmax] of integer ;
S : integer ; { S = suma gradele interior si exterior pt. un varf }
53
Probleme rezolvate de programare Subiecte propuse la ATESTAT
f : TEXT; {fisier in care memoram informatiile despre GRAF }
linie : STRING ; { "linie" = o linie din fisierul text GRAF.TXT }
ER : integer; { variabila eroare din apelul procedurii VAL }

Begin { PROGRAM PRINCIPAL }


CLRSCR;
writeln;

ASSIGN (f, 'C:\GRAF.TXT');


RESET (f);

{ Citim din fisier prima componenta = numarul de noduri }


readln (f, n);
writeln ('Numarul de noduri, n = ', n);
writeln;

{ Initializam toate componentele listelor de ADIACENTA cu pointerul NIL }


for i := 1 to n do
begin
L [i] := NIL;
end;
{ Citim din fisier a doua componenta = numarul de arce }
readln (f, m);
writeln ('Numarul de muchii, m = ', m);
writeln;

{ Citim din fisier urmatoarele "m" linii ce contin extremitatile arcelor. }


{ Cu aceste extremitati construim LISTELE de ADIACENTA }
For i := 1 to m do
Begin
readln (f, linie);
VAL ( linie [1], x , ER ); {transformam sirul linie [1] in numarul x }
Writeln ('Extremitatea initiala a muchiei ', i,' este x = ', x);

VAL ( linie [3], y , ER ); {transformam sirul linie [3] in numarul y }


Writeln ('Extremitatea finala a muchiei ', i,' este y = ', y);

{ Construirea LISTELOR DE ADIACENTA }


NEW (P);
P^.NodSuccesor := y ;
P^.URM := L [x];
L [x] := P;
End;
writeln;

{Afisarea listelor de adiacenta pentru cele n noduri - OPTIONAL}


for i:= 1 to n do
begin
write ('Nodul ',i,' are urmatorii succesori : ');
P := L [i];
while P <> NIL do
begin
write (p^.NodSuccesor,' -> ');
P := P^.URM
end;
write (' NIL');
writeln;
writeln
end;
writeln;

54
Probleme rezolvate de programare Subiecte propuse la ATESTAT
{ Initializare elemente vectori GradExt si GradInt }
for i:= 1 to n do
begin
GradExt [ i ] := 0;
GradInt [ i ] := 0;
end;

{ Determinam gradele exterior si interior pt. fiecare nod }


for i:= 1 to n do
begin
P := L [i];
while P <> NIL do
begin
INC ( GradExt [ i ] );
INC ( GradInt [ P^.NodSuccesor] );
P := P^.URM
end;
writeln
end;
writeln;

writeln ('Gradele nodurilor sunt urmatoarele:');


writeln;
for i := 1 to n do
begin
writeln ('GradExt ( ', i,' ) = ', GradExt [i] );
writeln ('GradInt ( ', i,' ) = ', GradInt [i] );
S := GradExt [ i ] + GradInt [ i ] ;
writeln;
writeln ('Suma gradelor = ', S );
writeln ;
writeln;

if GradExt [ i ] + GradInt [ i ] = 0 then


writeln ('Nodul ', i,' este IZOLAT');
end;
readln
END.

ATESTAT - 2005 - 24 - Se d un graf orientat G cu n vrfuri i m arce, reprezentat n memorie


prin matricea de adiacen. S se scrie un program care, pornind de la matricea drumurilor
corespunztoare grafului, s verifice dac:
a). graful are vrfuri izolate;
b). graful conine circuite (n i m sunt numere naturale citite la intrare).
Barem:
- declaraii corecte de variabile: 1 punct
- reprezentarea corect a grafului prin matricea de adiacen: 2 puncte
- determinarea matricii drumurilor prin algoritmul lui Roy-Warshall: 2 puncte
- realizarea punctului a): 2 puncte
- realizarea punctului b): 2 puncte
- din oficiu: 1 punct

55
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare:
1 4 5
Considerm graful din figura alturat.
Notm cu GradExt, respectiv GradInt, gradul
exterior i interior al fiecrui vrf.
Dac pentru un vrf suma celor dou grade 2 3 6
este zero, acel vrf este izolat.
De asemenea, un vrf este izolat dac i NOD GradExt GradInt Suma grade
numai dac linia i i coloana i din 1 2 1 3
matricea de ADIACEN au toate 2 2 1 3
elementele NULE. 3 2 2 4
Un drum ntr-un graf orientat este un ir de 4 2 2 4
vrfuri. Un drum se poate scrie fie ca o 5 0 2 2
succesiune de arce, fie ca o succesiune de 6 0 0 0
vrfuri.
Dac toate arcele unui drum sunt distincte, iar primul i ultimul nod coincid, drumul se numete
circuit.
Dac toate vrfurile unui circuit, cu excepia primului i ultimului, sunt distincte, circuitul este
elementar.
Pentru graful alturat, avem circuitele:
C1 = (1, 2, 3, 4, 1, 3, 4, 1), C2 = (1, 3, 4, 1, 2, 3, 4, 1)
precum i circuitele elementare:
C3 = (1, 2, 4, 1), C4 = (1, 3, 4, 1), C5 = (1, 2, 3, 4, 1)
Pentru graful de mai sus, avem:
Matricea de ADIACEN: Matricea DRUMURILOR:

Nod 1 2 3 4 5 6 Nod 1 2 3 4 5 6
1 0 1 1 0 0 0 1 1 1 1 1 1 0
A = 2 0 0 1 1 0 0 B = 2 1 1 1 1 1 0
3 0 0 0 1 1 0 3 1 1 1 1 1 0
4 1 0 0 0 1 0 4 1 1 1 1 1 0
5 0 0 0 0 0 0 5 0 0 0 0 0 0
6 0 0 0 0 0 0 6 0 0 0 0 0 0

Pentru a verifica dac graful conine noduri izolate, declarm doi vectori zeropelin si zeropecol in
care memorm numarul de zero-uri de pe fiecare linie, respectiv fiecare coloan. Apoi, pentru fiecare
linie din matricea de ADIACEN, verificam dac este ndeplinit condiia
( zeropelin [ i ] = n) AND (zeropecol [ i ] = n)
adic, simultan pe linia i i coloana i avem numai zero-uri (n zero-uri).
Se observ c, n matricea de ADIACEN linia 6 i coloana 6 au toate elementele nule. Rezult
c nodul 6 este nod izolat.
Pentru a verifica dac graful are circuite, se verific dac matricea drumurilor conine elemente
egale cu 1 pe diagonala principal. Din faptul c matricea drumurilor are numai elemente de 1 pe
diagonala principal deducem doar c fiecare vrf aparine unui circuit; NU rezult c exist un
circuit care trece prin toate nodurile grafului.

program ATESTAT_2005_24_CIRCUITE_MATRICEA_DRUMURILOR_ALGORITMUL_ROY_WARSHALL;
uses CRT;
CONST
nmax = 100;
TYPE
matrice = array [1..nmax, 1..nmax] of integer;

56
Probleme rezolvate de programare Subiecte propuse la ATESTAT
VAR
n : integer; {n = numarul nodurilor}
m : integer; {numarul de muchii din graf}
x, y : integer; { extremitati ale unei muchii}
A : matrice; {matricea de adiacenta}
B : matrice; {matricea drumurilor}
i, j, k : integer;
zeropelin : array [1..nmax] of integer;
{vector in care memoram numarul zero-urile gasite pe o linie }
zeropecol : array [1..nmax] of integer;
{vector in care memoram numarul zero-urile gasite pe o coloana }
GASIT : boolean ; {testeaza daca exista circuite in graf }

function MIN ( alfa, beta : integer) : integer;


begin
if alfa <= beta then
MIN := alfa
else
MIN := beta
end;

Begin { PROGRAM PRINCIPAL }


{ CLRSCR;}
write ('Dati numarul de noduri, n = ');
readln (n);
write ('Dati numarul de muchii, m = ');
readln (m);

{Initializarea tuturor elementelor matricii de adiacenta cu zero}


for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0
end;
end;
writeln;

{Completare matrice de adiacenta}


For i := 1 to m do
Begin
Writeln ('Dati extremitatile muchiei ', i, ':');
Write ('Dati varful x = ');
readln (x);
Write ('Dati varful y = ');
readln (y);
A [x, y] := 1; {matricea NU este simetrica}
End;
writeln;
writeln ('Matricea de ADIACENTA este:');
for i := 1 to n do
begin
writeln;
for j := 1 to n do
begin
write ( A [i, j] : 3 ); {se lasa 3 pozitii pentru fiecare }
{element al matricii }
end;
end;
writeln;

57
Probleme rezolvate de programare Subiecte propuse la ATESTAT
{ Deoarece se pleaca de la matricea de ADIACENTA, se va face }
{ Initializarea matricii DRUMURILOR B cu matricea de ADIACENTA A }

for i := 1 to n do
begin
for j := 1 to n do
begin
B [i, j] := A [i, j];
end;
end;

{Transformarea propriu-zisa - Algoritmul Roy-Warshall}


for k := 1 to n do
begin
for i := 1 to n do
begin
if i <> k then
begin
for j := 1 to n do
begin
if j <> k then
begin
IF B [i, j] = 0 then
B [i, j] := MIN (B [i, k], B [k, j])
end
end
end
end
end;
writeln ('Matricea drumurilor este:');
for i := 1 to n do
begin
writeln;
for j := 1 to n do
begin
write ( B [i, j] : 3 ); {se lasa 3 pozitii pentru fiecare }
{element al matricii }
end;
end;
{--------------------------------------------------------------------------}

{ Verificam, in matricea de ADIACENTA, daca exista varfuri IZOLATE }

for i := 1 to n do
begin
zeropelin [ i ] := 0;
for j := 1 to n do
begin
if A [i, j] = 0 then
zeropelin [i] := zeropelin [i] + 1;
end
end;

for j := 1 to n do
begin
zeropecol [ j ] := 0;
for i := 1 to n do
begin
if A [i, j] = 0 then
zeropecol [ j ] := zeropecol [ j ] + 1;
end
end;
writeln;

58
Probleme rezolvate de programare Subiecte propuse la ATESTAT
for i := 1 to n do
begin
writeln ('zeropelin [ ',i,' ] = ', zeropelin [ i ] );
writeln ('zeropecol [ ',i,' ] = ', zeropecol [ i ] );
writeln
end;

for i := 1 to n do
begin
if ( zeropelin [ i ] = n) AND (zeropecol [ i ] = n) then
writeln ('Varful ', i,' este izolat') ;
writeln
end;

{ Verificam, in matricea de DRUMURILOR, daca exista 1 pe diagonala principala }

GASIT := FALSE; {presupunem ca nu exista circuite in graf }


for i := 1 to n do
begin
if B [i, i] = 1 then
GASIT := TRUE
end;
if GASIT = TRUE then
writeln ('Graful contine circuite')
else
writeln ('Graful NU contine circuite');
readln
END.

FUNCII I PROCEDURI RECURSIVE

ATESTAT - 2005 - 25 - S se scrie un program care citete de la tastatur un numr natural n i


apeleaz o funcie recursiv, care ntoarce valoarea produsului:
p (n) = 1 * 3 * 5 ** (2n+1).
Exemple: pentru n = 0, se va afia p (0) = 1, adic 2 * 0 + 1
pentru n = 3, se va afia p (3) = 105, adic 1 * 3 * 5 * 7
Barem:
- corectitudinea definiiei recursive: 3 puncte
- declaraie corect de funcie: 2 puncte
- condiia de ieire din funcie: 2 puncte
- corectitudine sintactic: 1 punct
- din oficiu: 1 punct

Rezolvare: Algoritmul recursiv pentru calcularea produsului din enun este asemntor cu cel pentru
calcularea lui xn n variant recursiv.
program ATESTAT_2005_25_PRODUS_RECURSIV;
var
i, n, p : integer;
function PRODUS (m : integer) : integer;
begin
if m = 0 then
PRODUS := 1
else
PRODUS := (2*m + 1) * PRODUS (m - 1)
end;

59
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
write ('Dati n = ');
readln (n);

p := PRODUS (n);

writeln ('p ( ', n, ') = ', p);


readln
END.

ATESTAT - 2005 - 26 - S se scrie un program prin care se citete de la tastatur numrul natural n.
Programul trebuie s apeleze o funcie recursiv, care s ntoarc valoarea sumei S (n), unde
S (n) = 2 + 5 + 8 + ... + (2 + 3*n).
Valoarea pentru numrul n este citit n programul principal. Valoarea calculat de funcie va fi
afiat pe ecran tot n programul principal.
Exemplu: pentru n = 3, se va afia valoarea 26 ( S (3) = 2 + 5 + 8 + 11 ).
Barem:
- corectitudinea definiiei recursive: 3 puncte
- declaraie corect de funcie: 2 puncte
- condiia de ieire din funcie: 2 puncte
- corectitudine sintactic: 1 punct
- din oficiu: 1 punct

Rezolvare: Algoritmul recursiv pentru calcularea sumei din enun este asemntor cu cel pentru
calcularea, n variant recursiv, a sumei S = 1 + 2 + 3 + + n.
program ATESTAT_2005_26_SUMA_RECURSIVA;
var
i, n, s : integer;

function SUMA (m : integer) : integer;


begin
if m = 0 then
SUMA := 2
else
SUMA := (2 + 3 * m) + SUMA (m-1 )
end;

Begin { PROGRAM PRINCIPAL }


write ('Dati n = ');
readln (n);

s := SUMA (n);

writeln ('S ( ', n, ') = ', s);


s:=2;
for i := 1 to n do
begin
writeln ('SUMA ( ', i, ' ) = ', SUMA (i) );
s := s + SUMA (i);
end;
readln
END.

60
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 27 - Se d un numr natural n introdus de la tastatur. Scriei un program care
calculeaz suma cifrelor acestui numr. Programul trebuie s apeleze o funcie recursiv care s
ntoarc valoarea sumei.
Barem:
- corectitudinea definiiei recursive: 3 puncte
- declaraie corect de funcie: 2 puncte
- condiia de ieire din funcie: 2 puncte
- corectitudine sintactic: 1 punct
- din oficiu: 1 punct

Rezolvare: Pentru numrul x, trebuie s determinm, mai nti, numrul de cifre i apoi vom
calcula suma cifrelor. Vom defini dou funcii NRCIFRE i SUMACIFRE, n acest scop
program ATESTAT_2005_27_SUMA_CIFRE_NUMAR_X;
{Folosind o functie recursiva, sa se calculeze suma cifrelor unui nr. natural x}
const
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
var
s, x, x1, n, i : integer;
y : vector;
k : BOOLEAN;
function NRCIFRE (y : integer) : integer;
var
m : integer;
begin
if y = 0 then
m := 1
else
begin
m := 0;
while y <> 0 do
begin
y := y DIV 10;
m := m + 1
end
end;
NRCIFRE := m
end;
function SUMACIFRE ( nr : integer) : integer;
var
s1, i : integer;
begin
s1 := 0;
for i := 1 to NRCIFRE (nr) do
begin
S1 := s1 + y [i] ;
end;
SUMACIFRE := s1
end;

Begin { PROGRAM PRINCIPAL }


write ('Introduceti un numar natural x = ');
readln (x);

n := NRCIFRE (x);
writeln ('Numarul ',x,' are ',n,' cifre');
writeln;

61
Probleme rezolvate de programare Subiecte propuse la ATESTAT
x1 := x; {conservam valoarea numarului initial x, folosind auxiliarul x1}
for i := 1 to n do
begin
y [ i ] := x1 MOD 10;
writeln ('y [',i,'] = ', y [i]);
x1 := x1 DIV 10;
end;
s := SUMACIFRE (x);
writeln ('Suma cifrelor numarului ', x, ' = ', s);
readln
END.

ATESTAT - 2005 - 28 - Se d un numr natural n n baza 10 i un numr natural b (2 <= b <= 9).
S se scrie un program care s converteasc numrul n n baza b, utiliznd n acest scop un
subprogram recursiv.
Barem:
- apel corect de subprogram: 2 puncte
- declaraie corect de subprogram: 3 puncte
- algoritm pentru conversia n baza b (algoritm corect): 3 puncte
- corectitudine sintactic: 1 punct
- din oficiu: 1 punct

Rezolvare: Folosim un vector R n care se rein resturile mpririi numrului zecimal nr10 la b
(de exemplu, b = 2).
program ATESTAT_2005_28_TRANSFORMARE_BAZA_10_IN_BAZA_2_VARIANTA_ITERATIVA_1;
uses CRT;
type
vector = array [1..100] of integer;
VAR
ZECIMAL, BINAR, nr10 : integer; {numarul zecimal}
nr2inversat, nr2 : integer; {numar binar inversat respectiv nr binar final}
R : vector;
n, i, j, k, rest : integer;
Begin { PROGRAM PRINCIPAL }
clrscr;
write ('Dati numarul zecimal = ');
readln (nr10);
if nr10 = 0 then
begin
ZECIMAL := 0;
i:=1;
R[i] := 0
end
else
begin
i := 0;
ZECIMAL := nr10;
while nr10 <> 1 do
begin
rest := nr10 MOD 2;
i := i + 1;
R [i] := rest;
nr10 := nr10 DIV 2;
end;
i := i + 1;
r [i] := nr10;
end;
n := i;

62
Probleme rezolvate de programare Subiecte propuse la ATESTAT
writeln;
write ('Numarul binar echivalent lui ', ZECIMAL,' este ');
for i := n downto 1 do
begin
write ( R[i] );
end;
readln
END.

program ATESTAT_2005_28_TRANSFORMARE_BAZA_10_IN_BAZA_B_VARIANTA_ITERATIVA_2;
uses CRT;
type
vector = array [1..100] of integer;
VAR
ZECIMAL, BINAR, nr10 : integer; {numarul zecimal}
nr2inversat, nr2 : integer; {numar binar inversat respectiv nr binar final}
R : vector;
baza, n, i, j, k, rest : integer;
Begin { PROGRAM PRINCIPAL }
clrscr;
write ('Dati numarul zecimal nr10 = ');
readln (nr10);
write ('Dati noua baza = ');
readln (baza);

i := 0;
ZECIMAL := nr10;
while nr10 <> 0 do
begin
rest := nr10 MOD baza;
i := i + 1;
R [i] := rest;
nr10 := nr10 DIV baza;
end;

n := i;

write ('Numarul in baza ', baza,' echivalent este ');


for i := n downto 1 do
begin
write ( R[i] );
end;
readln
END.

program ATESTAT_2005_28_TRANSFORMARE_BAZA_10_IN_BAZA_2_VARIANTA_RECURSIVA;

var
n: integer;
b: byte;

procedure conversie (x: integer; b:byte);


var r:byte;
begin
if x>0 then
begin
r:=x mod b;
conversie (x div b, b);
write(r);
end;
end;

63
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
write ('Dati n = ');
readln (n);
write ('Dati noua baza de numeratie, b = ');
readln (b);
writeln ('Reprezentarea numarului ',n,' in baza ',b,' este:');
conversie (n,b);
readln;
end.

ATESTAT - 2005 - 29 - Se citesc n cuvinte terminate fiecare cu cte un spaiu. Cuvintele se citesc
de la tastatur din n linii. S se scrie un program care s afieze fiecare cuvnt aa cum s-a citit i
apoi cu literele inversate. S se rezolve problema recursiv.
Barem:
- apel corect de subprogram: 2 puncte
- declaraie corect de subprogram: 3 puncte
- algoritm corect de inversare recursiv: 3 puncte
- corectitudine sintactic: 1 punct
din oficiu: 1 punct

Rezolvare: Definim o funcie recursiv pentru inversarea unui ir.


program ATESTAT_2005_29_INVERSAREA_ELEMENTELOR_UNUI_SIR;
{ Inversare cuvinte - cu functie recursiva }
uses CRT;
const
nmax = 100;
type
vector = array [1..nmax] of string;
VAR
sir, inv : string;
n, i : integer;
siruri : vector;
function INVERS ( s : string ) : string;
begin
if s = '' then
INVERS := ''
else
INVERS := s [ LENGTH (s) ] + INVERS ( COPY (s, 1, LENGTH (s) - 1 ));
end; { sfarsit functie }

Begin { PROGRAM PRINCIPAL }


write ('Dati numarul de cuvinte, n = ');
readln (n);
for i := 1 to n do
begin
write ('Introduceti cuvintul ', i,' ');
readln (sir);
siruri [i] := sir;
end;
writeln;
writeln ('********************************');
for i := 1 to n do
begin
writeln (siruri [i] : 20, ' ', INVERS ( siruri [i] ) );
end;
readln
END.

64
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 30 - Se d un ir de caractere citit de la tastatur, ir ce se termin cu caracterul
punct. Scriei un program care afieaz irul citit n ordine invers. S se rezolve problema
recursiv.
Barem:
- apel corect de subprogram: 2 puncte
- declaraie corect de subprogram: 3 puncte
- algoritm corect de inversare recursiv: 3 puncte
- corectitudine sintactic: 1 punct
- din oficiu: 1 punct

Rezolvare: Definim o funcie recursiv pentru inversarea unui ir.


program ATESTAT_2005_30_INVERSAREA_UNUI_SIR;
{ Inversare sir - cu functie recursiva }
uses CRT;
const
nmax = 100;
VAR
sir2, sir, inv : string;
n, L, i : integer;

function INVERS ( s : string ) : string;


begin
if s = '' then
INVERS := ''
else
INVERS := s [ LENGTH (s) ] + INVERS ( Copy (s, 1, LENGTH (s) - 1 ));
end; { sfirsit functie

Begin { PROGRAM PRINCIPAL }


clrscr;
write ('Dati sirul (max 8 caractere), sir = ');
readln (sir);

L := LENGTH (sir);
sir := COPY (sir, 1, L - 1);
writeln ('Noul sir = ', sir);

writeln;
writeln ('********************************');
sir2 := INVERS (sir);
writeln ('sir 2 = ', sir2 );
readln
END.

ALGORITMI FUNDAMENTALI
CARE LUCREAZ CU TABLOURI
(varianta iterativ)

ATESTAT - 2005 - 31 - S se citeasc din fiierul standard de intrare un numr natural x. S se


creeze un fiier text, numit FACTORI.TXT cu structura :
- pe prima linie se va scrie valoarea lui x;
- pe urmtoarele linii se vor scrie factorii primi i puterile lor, n descompunerea lui x n factori
primi (cte un factor pe o linie).
S se citeasc fiierul creat i s se afieze pe ecran descompunerea numrului x.

65
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Barem:
- declaraii i citire corect: 1 punct
- algoritmul de descompunere n factori primi: 3 puncte
- crearea fiierului FACTORI.TXT: 2 puncte
- listarea coninutului fiierului: 3 puncte
- din oficiu: 1 punct

Rezolvare:
n ipoteza c fiierul text nu exist deja pe disc, vom crea acest fiier cu acelai program care face
i celelalte determinri cerute de enun.
Dup citirea de la tastatur a numrului x, l vom converti ntr-un ir de caractere, notat sirx,
prin apelarea procedurii STR. Introducem n fiierul text irul sirx asociat numrului x.
n fiierul text se vor introduce att factorii primi n care se descompune x, ct i puterile lor,
astfel:
Transformm factorii n sir1, iar puterile n sir2
Dup fiecare astfel de numr transformat n ir, fie vom lsa cte un singur spaiu liber
(blank), fie vom aduga un comentariu (un ir de caractere). n acest fel, se va crea, prin
CONCATENARE, cte o linie n fiierul text. Evident, linie este tot un ir de caractere.
Celelalte etape sunt comentate direct n program.
program ATESTAT_2005_31_FACTORI_PRIMI_SI_PUTERILE_LOR;
{ Fie x un numar natural. Afisati factorii primi ai lui x si puterile lor }
CONST
nmax = 1000;
TYPE
vector = array [1..nmax] of integer;
VAR
f : TEXT;
linie : string;
sirx, sir1, sir2 : string;
putere : vector; {retinem in vectorul "putere" puterea unui factor prim}
divizor : vector; {"divizor" = vector in care se retin factorii primi}
x, d : integer;
divmax : integer; {divizorul sau factorul prim maxim}
{d = un divizor oarecare, curent}

Begin { PROGRAM PRINCIPAL }


ASSIGN (f, 'C:\FACTORI.TXT');
REWRITE (f);

write ('Dati x = ');


readln (x);
STR (x, sirx);

writeln (f, sir1); {scriu pe prima linie a lui "f" valoarea lui x}

RESET (f);
while not EOF (f) do
begin
readln (f, linie);
writeln (linie);
end;

d := 2; {primul divizor = primul factor}

divizor [d] := d; {initializare element din vectorul divizor}


putere [d] := 0; {initializare numar de impartiri ale lui x la d}

66
Probleme rezolvate de programare Subiecte propuse la ATESTAT
while x > 1 do
begin
If x MOD d = 0 then {daca x se imparte la d}
begin
putere [d] := putere [d] + 1;
x := x DIV d;
end
else
begin
d := d + 1;
divizor [d] := d;
putere [d] := 0
end;
end;
writeln;

divmax := d;

for d := 2 to divmax do
begin
if putere [d] <> 0 then
begin
writeln ('Divizorul ', divizor [d],
' apare la puterea a ', putere [d] , '-a');

STR (divizor [d], sir1); {transform divizor [d] in sir1}


STR (putere [d], sir2); {transform putere [d] in sir2}
linie := 'Divizorul ' + sir1 + ' apare la puterea a ' + sir2 + '-a';
APPEND (f); {APPEND, deoarece am scris deja sirx in f}
writeln (f, linie);
end
end;
writeln;
writeln ('Continutul fisierului este:');

RESET (f);
while NOT EOF (f) do
begin
readln (f, linie);
writeln (linie)
end;
readln
end.

ATESTAT - 2005 - 32 - Se d un tablou bidimensional cu m linii i n coloane, ce conine numere


ntregi. S se determine linia ce conine cel mai mare element n valoare absolut din matrice.
Datele de intrare se vor prelua dintr-un fiier text MATRICE.TXT cu structura :
- prima linie conine m i n (dou numere ntregi pozitive, separate printr-un spaiu)
- urmtoarele m linii conin fiecare n numere ntregi separate printr-un spaiu.
Rezultatele se vor afia pe ecran.
Barem :
- crearea fiierului de intrare : 1 punct
- citire din fiier : 3 puncte
- algoritmul pentru determinarea elementului maxim: 4 puncte
- afiare rezultate: 1 punct
din oficiu: 1 punct

67
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare: Folosim funcia STR pentru conversia unui numr ntr-un ir, la introducerea
elementelor matricii n fiier.
program ATESTAT_2005_32_ELEMENT_MAX_IN_MATRICE;
uses CRT;
LABEL
100;
CONST
nmax = 100;
TYPE
matrice = array [1..nmax, 1..nmax] of integer;
VAR
m, n, i, j, MAX : integer;
f : TEXT;
A : matrice;
sir, sir1, sir2, linie : STRING;

begin
CLRSCR;
ASSIGN (f, 'C:\MATRICE.txt');
rewrite (f); {generam fisierul text}

{ ---------------------------------------------------------------------- }
{ scriem pe prima linie din fisierul TEXT cele doua valori "m" si "n" }

linie := ''; { initializare variabila "linie" cu sirul vid }


{ "linie" = un STRING care se va introduce in fisierul text }
{ Prima "linie" va contine "m" si "n" separate de spatii }
{ Urmatoarele "m" linii vor contine cate "n" elemente separate de
spatii }
writeln ;
write ('Dati numarul de linii, m = ');
readln (m);

STR (m, sir1); {transforma "m" in "sir1", pentru a-l memora in fisier}
linie := linie + sir1 + ' '; {construim "linie" prin concatenare,}
{scriind un "spatiu" dupa fiecare sir }
writeln;
write ('Dati numarul de coloane, n = ');
readln (n);

STR (n, sir2); {transforma "n" in "sir2", pentru a-l memora in fisier}
linie := linie + sir2 ; {construim "linie" prin concatenare cu vechea valoare}
{ a sirului "linie" }

writeln (f, linie); { scriem sirul "linie" in fisierul TEXT }


writeln;

{ Introducerea matricii }

writeln ;
writeln ('Dati matricea');
writeln;
for i := 1 to m do
begin
for j := 1 to n do
begin
write ('Dati A [ ', i,',',j, ' ] = ');
readln ( A [i, j] );
end;
end;
writeln;

68
Probleme rezolvate de programare Subiecte propuse la ATESTAT
{ Scrierea matricii in fisierul TEXT }

for i := 1 to m do
begin
linie := '' ; { initializare sir "linie" cu sirul vid }
{ pt. fiecare linie a matricii }
for j := 1 to n - 1 do
begin
STR ( A [i, j] , sir ); {transforma A [i,j] intr-un sir }
linie := linie + sir + ' ' ; { construirea liniei curente }
{ din fisierul text }
end;

writeln (f, linie); { scriem sirul "linie" in fisierul TEXT }

end;

writeln ;
writeln ('Continutul fisierului TEXT este :');
writeln;

RESET (f);

WHILE NOT EOF (f) do


begin
readln (f, linie);
writeln (linie)
end;
writeln;

RESET (f);

{ Se citesc din fisier dimensiunile matricii }

Read (f, m);


Readln (f, n);

{ Se citesc din fisier elementele matricii }

for i := 1 to m do
begin
for j:=1 to n do
begin
Read (f, A [i, j]);
end;
Readln (f); { avansul la linia urmatoare in fisier }
end;

Close (f);

{ Determinare element MAXIM }

MAX := ABS ( A [1, 1] );


for i := 1 to m do
begin
for j := 1 to n do
begin
if ABS ( A [i, j] ) >= MAX then
begin
MAX := ABS ( A [i, j] ) ;
end;
end;
end;

69
Probleme rezolvate de programare Subiecte propuse la ATESTAT
writeln;
writeln ('Elementul maxim, in modul, este : ', MAX );
writeln;
writeln ('Linia / liniile pe care se afla elementul cautat : ');
writeln;
for i := 1 to m do
begin
for j := 1 to n do
begin
if ABS ( A [i, j] ) = MAX then
begin
writeln ('Elementul cautat se afla pe Linia = ', i );
GOTO 100; { daca MAX a fost gasit intr-o linie, }
{ trecem la urmatoarea linie }
end;
end;
100 :
end;
readln;
end.

ATESTAT - 2005 - 33 - Se consider o matrice cu m linii i n coloane. S se scrie un program care


s ordoneze cresctor n funcie de suma liniilor matricii, prin una din metodele nvate. Se va
meniona metoda folosit printr-un comentariu n program. Datele de intrare se vor citi dintr-un fiier
text INPUT.TXT, iar matricea ordonat se va afia pe ecran linie cu linie.
Barem :
- crearea fiierului de intrare: 1 punct
- citire din fiier: 3 puncte
- algoritm de sortare cresctoare a liniilor: 4 puncte
- afiare matrice: 1 punct
- din oficiu: 1 punct

Rezolvare: Pentru ordonare, vom defini dou proceduri: BUBBLE care apeleaz la algoritmul
bubble sort, i ORDONEAZ, bazat pe sortarea prin selecie.

program ATESTAT_2005_33_ORDONARI;
uses CRT;
const
nmax = 30;
type
vector = array [1..nmax] of integer;
matrice = array [1..nmax, 1..nmax] of integer;
var
f : file of integer;
A : matrice;
linia : vector;
n, j, i, m : integer;
t, suma, index : integer;

procedure BUBBLE (var v : vector; nr:integer);


var
k1, j : integer;
aux : integer;

70
Probleme rezolvate de programare Subiecte propuse la ATESTAT
begin
repeat
k1:= 0;
j := 1;
repeat
if v[j] > v [j+1] then
begin
aux := v [j];
v [j] := v [j+1];
v [j+1] := aux;
k1 := 1
end;
j := j + 1
until (j > nr - 1)
until (k1 = 0);
end;
procedure ORDONEAZA (var v : vector; nr : integer ); {alt algoritm de sortare}
var
aux : integer;
begin
for t := 1 to nr - 1 do
begin
for j := t + 1 to nr do
begin
if v [t] < v [j] then
begin
aux := v [t];
v [t] := v [j];
v [j] := aux
end;
end;
end;
end;
procedure TIPARESTE (x:vector; nr:integer);
begin
for t := 1 to nr do
write ( x [t],',')
end;
Begin { PROGRAM PRINCIPAL }
clrscr;
ASSIGN (f, 'c:\intregi.txt');
rewrite (f);
repeat
write ('Dati numarul de linii, m = ');
readln (m);
until (m >= 1) and (m <= nmax);

repeat
write ('Dati numarul de coloane, n = ');
readln (n);
until (n >= 1) and (n <= nmax);

writeln;
writeln ('Dati matricea A');
for i := 1 to m do
begin
for j := 1 to n do
begin
write ('a [ ',i,',',j,' ] = ');
readln (a [i,j] )
end;
end;
writeln;

71
Probleme rezolvate de programare Subiecte propuse la ATESTAT
for i := 1 to m do
begin
for j := 1 to n do
begin
linia [j] := a [i,j];
end;
writeln;
TIPARESTE (linia, n);
readln;
end;

suma := m + n;

index := suma mod 2;

case index of
0 : begin
for i := 1 to m do
begin
for j := 1 to n do
begin
linia [j] := a[i, j];
end;

write ('linia ', i,' este ');

TIPARESTE (linia, n);


writeln;
readln;
BUBBLE (linia, n); {un prim algoritm de sortare}
writeln;
TIPARESTE (linia, n);
writeln;
readln;

end;
end;

1 : begin
for i := 1 to m do
begin
for j := 1 to n do
begin
linia [j] := a[i, j];
end;

write ('linia ', i,' este ');


TIPARESTE (linia, n);
readln;
ORDONEAZA (linia, n); {al doilea algoritm de sortare}
writeln;
TIPARESTE (linia, n);
readln;

end;
end;

end; {end CASE}

writeln;
readln
END.

72
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 34 - Scriei un program care s realizeze REUNIUNEA a dou mulimi A i B
introduse prin doi vectori ce au m, respectiv n elemente numere ntregi, distincte. Datele de intrare
se vor citi de la tastatur. Rezultatele se vor afia pe ecran.
Barem:
- declaraii de variabile: 1 punct
- citire corect a datelor: 2 puncte
- algoritm de prelucrare corect descris: 5 puncte
- afiarea reuniunii: 1 punct
- din oficiu: 1 punct

Rezolvare: Construim dou mulimi Ma i Mb care conin, fiecare, elementele vectorilor A,


respectiv B, i apoi reunim cele dou mulimi.

program ATESTAT_2005_34_REUNIUNE_MULTIMI;
const
nmax = 100;
type
vector = array [1..nmax] of integer;
var
a, b : vector;
R, Ma, Mb : set of byte;
elem, m,n,i,j : integer;
Begin { PROGRAM PRINCIPAL }
repeat
write ('Dati nr. de elemente ale multimii A, m = ');
readln (m)
until (m >= 1 ) AND (m <= nmax);
repeat
write ('Dati nr. de elemente ale multimii B, n = ');
readln (n)
until (n >= 1 ) AND (n <= nmax);
writeln;
writeln ('Dati elementele multimii A');
for i := 1 to m do
begin
write ('A [ ', i,' ] = ');
readln ( A [i] );
end;
writeln;
writeln ('Dati elementele multimii B');

for i := 1 to n do
begin
write ('B [ ', i,' ] = ');
readln ( B [i] );
end;

Ma := [];
for i := 1 to m do
begin
Ma := Ma + [ A[i] ]; {construiesc Ma prin reuniune
end;

Mb := [];
for i := 1 to n do
begin
Mb := Mb + [ B[i] ]; {construiesc Ma prin reuniune
end;
R := Ma + Mb;
writeln;

73
Probleme rezolvate de programare Subiecte propuse la ATESTAT
writeln ('Elementele multimii REUNIUNE sunt :');
for elem := 0 to 255 do
begin
if elem IN R then
write (elem,' , ');
end;
readln
END.

ATESTAT - 2005 - 35 - Scriei un program care s realizeze INTERSECIA a dou mulimi A i


B introduse prin doi vectori ce au m, respectiv n elemente numere ntregi, distincte.
Datele de intrare se vor citi de la tastatur. Rezultatele se vor afia pe ecran.
Barem:
- declaraii de variabile: 1 punct
- citire corect a datelor: 2 puncte
- algoritm de prelucrare corect descris: 5 puncte
- afiarea interseciei: 1 punct
- din oficiu: 1 punct

Rezolvare: Construim dou mulimi Ma i Mb care conin, fiecare, elementele vectorilor A,


respectiv B, i apoi intersectm cele dou mulimi.

program ATESTAT_2005_35_INTERSECTIE;
const
nmax = 100;
type
vector = array [1..nmax] of integer;
var
a, b : vector;
INTERS, Ma, Mb : set of byte;
elem, m,n,i,j : integer;
Begin { PROGRAM PRINCIPAL }
repeat
write ('Dati nr. de elemente ale multimii A, m = ');
readln (m)
until (m >= 1 ) AND (m <= nmax);
repeat
write ('Dati nr. de elemente ale multimii B, n = ');
readln (n)
until (n >= 1 ) AND (n <= nmax);
writeln;
writeln ('Dati elementele multimii A');
for i := 1 to m do
begin
write ('A [ ', i,' ] = ');
readln ( A [i] );
end;
writeln;
writeln ('Dati elementele multimii B');

for i := 1 to n do
begin
write ('B [ ', i,' ] = ');
readln ( B [i] );
end;

74
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Ma := [];
for i := 1 to m do
begin
Ma := Ma + [ A[i] ]; {construiesc Ma prin reuniune }
end;

Mb := [];
for i := 1 to n do
begin
Mb := Mb + [ B[i] ]; {construiesc Ma prin reuniune }
end;
INTERS := Ma * Mb;
writeln;
writeln ('Elementele multimii INTERS sunt :');
for elem := 0 to 255 do
begin
if elem IN INTERS then
write (elem,' , ');
end;
readln
END.

ATESTAT - 2005 - 36 - Scriei un program care s realizeze DIFERENA a dou mulimi A i B


introduse prin doi vectori ce au m, respectiv n elemente numere ntregi, distincte.
Datele de intrare se vor citi de la tastatur. Rezultatele se vor afia pe ecran.
Barem:
- declaraii de variabile: 1 punct
- citire corect a datelor: 2 puncte
- algoritm de prelucrare corect descris: 5 puncte
- afiarea diferenei: 1 punct
- din oficiu: 1 punct

Rezolvare: Construim dou mulimi Ma i Mb care conin, fiecare, elementele vectorilor A,


respectiv B, i apoi facem diferena celor dou mulimi.

program ATESTAT_2005_36_INTERSECTIE;
const
nmax = 100;
type
vector = array [1..nmax] of integer;
var
a, b : vector;
DIFER, Ma, Mb : set of byte;
elem, m,n,i,j : integer;

Begin { PROGRAM PRINCIPAL }


repeat
write ('Dati nr. de elemente ale multimii A, m = ');
readln (m)
until (m >= 1 ) AND (m <= nmax);
repeat
write ('Dati nr. de elemente ale multimii B, n = ');
readln (n)
until (n >= 1 ) AND (n <= nmax);
writeln;

75
Probleme rezolvate de programare Subiecte propuse la ATESTAT
writeln ('Dati elementele multimii A');
for i := 1 to m do
begin
write ('A [ ', i,' ] = ');
readln ( A [i] );
end;
writeln;
writeln ('Dati elementele multimii B');

for i := 1 to n do
begin
write ('B [ ', i,' ] = ');
readln ( B [i] );
end;

Ma := [];
for i := 1 to m do
begin
Ma := Ma + [ A[i] ]; {construiesc Ma prin reuniune }
end;

Mb := [];
for i := 1 to n do
begin
Mb := Mb + [ B[i] ]; {construiesc Ma prin reuniune }
end;
DIFER := Ma - Mb;
writeln;
writeln ('Elementele multimii DIFER sunt :');
for elem := 0 to 255 do
begin
if elem IN DIFER then
write (elem,' , ');
end;
readln
END.

ATESTAT - 2005 - 37 - Scriei un program care s afieze elementele care sunt numere prime,
dintr-o matrice ptratic cu n x n elemente ntregi pozitive. Dac n matrice nu sunt astfel de
elemente s se menioneze acest lucru printr-un mesaj adecvat afiat pe ecran.
Barem:
- declaraii de variabile: 1 punct
- citire corect a datelor: 2 puncte
- algoritm de determinare numr prim: 5 puncte
- afiare numere prime, respectiv mesaj: 1 punct
- din oficiu: 1 punct

Rezolvare: Verificm primalitatea unui numr ntreg, definind o funcie PRIM.

program ATESTAT_2005_37_NUMERE_PRIME_IN_MATRICE_PATRATICA;
const
nmax = 100;
type
matrice = array [1..nmax, 1..nmax] of integer;
var
A : matrice;
PRIME, m,n,i,j : integer;

76
Probleme rezolvate de programare Subiecte propuse la ATESTAT
function PRIM (x : integer) : boolean;
var
nrdiv, divizor: integer;
begin
nrdiv := 0;
for divizor := 1 to x do
begin
if x mod divizor = 0 then
nrdiv := nrdiv + 1
end;
if nrdiv <= 2 then
PRIM := TRUE
else
PRIM := FALSE
end;
Begin { PROGRAM PRINCIPAL }
repeat
write ('Dati nr. de linii = nr. de coloane, n = ');
readln (n)
until (n >= 1 ) AND (n <= nmax);
writeln ('Dati elementele matricii A');
for i := 1 to n do
begin
for j := 1 to n do
begin
write ('A [ ', i,',',j,' ] = ');
readln ( A [i,j] );
end;
end;
PRIME := 0; {contor care numara numerele prime gasite }
for i := 1 to n do
begin
for j := 1 to n do
begin
if PRIM (A[i,j]) = TRUE then
begin
PRIME := PRIME + 1;
writeln (A[i,j],' este numar prim');
end;
end;
end;
writeln;
writeln ('Matricea are ', PRIME,' numere prime');
if PRIME = 0 then
writeln ('Matricea nu are numere prime');
readln
END.

ATESTAT - 2005 - 38 - S se scrie un program care s realizeze INTERCLASAREA a doi vectori


A i B ordonai cresctor. Vectorii au m, respectiv n componente numere reale. La citire, s se
verifice dac vectorii sunt ordonai cresctor. Dac unul din ei nu satisface aceast condiie, s se
fac ordonarea prin una din metodele nvate.
Barem:
- declaraii de variabile: 1 punct
- citire corect a datelor, cu ordonare, cnd este cazul: 3 puncte
- algoritm de interclasare: 4 puncte
- afiare vector interclasat: 1 punct
- din oficiu: 1 punct

77
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare: Ordonm vectorii prin metoda bubble sort, dup care interclasm vectorii.
program ATESTAT_2005_38_INTERCLASARE;
uses CRT;
const
Nmax = 30;
type
vector = array [1 .. Nmax] of integer;
var
A, B : vector;
C : array [1 .. 2 * Nmax] of REAL;
i, j, m, n, k : integer;
procedure ORDONEAZA (VAR v : vector; q:integer);
var
k1, t: integer;
aux : integer;
begin
repeat
k1:= 0;
t := 1;
repeat
if v [t] > v [t+1] then
begin
aux := v [t];
v [t] := v [t+1];
v [t+1] := aux;
k1 := 1
end;
t := t + 1
until (t > q-1)
until ( k1 = 0);
end;
Begin { PROGRAM PRINCIPAL }
clrscr;
REPEAT
write ('Dati nr. de elemente pentru vectorul A, m = ');
readln (m);
UNTIL (m >=1) AND (m <= Nmax);
writeln;
REPEAT
write ('Dati nr. de elemente pentru vectorul B, n = ');
readln (n);
UNTIL (n >=1) AND (n <= Nmax);
writeln;
writeln ('Dati elementele vectorului A');
for i := 1 to m do
begin
write ('A [i] = ');
readln (A [i] )
end;
writeln;
ORDONEAZA (A, m);

writeln ('Dati elementele vectorului B');


for j := 1 to n do
begin
write ('B [j] = ');
readln (B [j])
end;
ORDONEAZA (B, n);

78
Probleme rezolvate de programare Subiecte propuse la ATESTAT

{ Algoritmul de INTERCLASARE }

k := 0;
i := 1;
j := 1;

WHILE ( i <= m ) AND ( j <= n) do


begin
if A [i] < B [j] then
begin
k := k + 1;
C [k] := A [i];
i := i + 1
end
else
begin
k := k + 1;
C [k] := B [j];
j := j + 1
end;
end;
WHILE i <= m DO
begin
k := k + 1;
C [k] := A [i];
i := i + 1
end;
WHILE j <= n DO
begin
k := k + 1;
C [k] := B [j];
j := j + 1
end;

writeln;

writeln ('Vectorul rezultant C este:');


for k := 1 to m + n do
begin
writeln ('C [k] = ', C [k])
end;
readln
END.

79

S-ar putea să vă placă și