Sunteți pe pagina 1din 77

Probleme rezolvate de programare – Subiecte propuse la ATESTAT

2005
BACKTRACKING

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

Rezolvare:
Aplicăm 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 - Câţiva copii cu vârste între 2 si 7 ani trebuie să fie vizitaţi de Moş Crăciun.
Scrieţi un program care determină toate modurile diferite în care pot ei să fie aşezaţi în lista lui Moş
Crăciun, astfel încât să fie vizitaţi toţi copiii şi vizitele să se facă în ordinea crescătoare a vârstei
lor. Se citesc de la tastatură: n = numărul de copii (0 < n < 10), apoi numele şi vârsta fiecăruia dintre
cei n copii. Se scriu, pe linii diferite, liste cu numele copiilor, în ordinea în care vor fi vizitaţi de Moş
Crăciun. O listă este formată din toate cele n nume ale copiilor, într-o anumită ordine, oricare două
nume succesive fiind despărţite prin spaţii.
Exemplu:
Pentru datele de intrare: n = 4, Dan 6, Cristina 4, Corina 2, Iulia 4
se scriu următoarele soluţii:
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 afişeze în ordine crescătoare toate numerele naturale de
k cifre cu proprietatea că sunt formate numai cu cifre ale numărului n.
Exemplu: pentru n = 216 şi k = 2, se vor afişa numerele:
11, 12, 16, 21, 22, 26, 61, 62, 66.

Rezolvare:
Completăm acest algoritm cu cerinţele enunţului de mai sus.
 Mulţimile care se înmulţesc cartezian vor avea "nrcif" elemente.
 Numărul de mulţimi care se vor înmulţi cartezian = k. Altfel spus, numerele generate vor avea
câte k cifre.
Exemplu, pentru n = 216 (nrcif = 3) şi k = 2, vom obţine:
(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, număr natural dat de la tastatură)
note muzicale din mulţimea {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 afişat pe câte o linie, în cadrul liniei, notele fiind separate
prin câte un spaţiu.
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 cuvânt
va fi afişat pe câte o linie.

Rezolvare:

 Vom genera produsul cartezian M x M x M ...x M, de n ori, în care mulţimea 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 citeşte un cuvânt format din maxim 20 de litere distincte. Să se afişeze
toate anagramele cuvântului respectiv. Un cuvânt “A” este anagrama unui cuvânt “C” dacă “A”
este format din aceleaşi litere ca şi cuvântul “C”, dar aşezate în altă ordine.
Exemplu: Pentru cuvântul "car", trebuie afişate, nu neapărat î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 citeşte din fişierul standard de intrare un număr natural n aparţinând N*
şi o mulţime 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 doreşte să introducă n bile numerotate de la 1 la n în n cutii, câte o


bilă în fiecare cutie. Să se afişeze toate posibilităţile 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 număr este
PALINDROM dacă numărul coincide cu imaginea lui în oglindă. Altfel spus, un număr este
PALINDROM dacă citit direct şi invers rezultatul este acelaşi.
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 condiţiilor de continuare : 2 puncte
- afişarea soluţiilor: 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 operaţiile 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 operaţiile 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 înlănţuită având ca elemente cuvinte
citite din fişierul standard de intrare, până la întâlnirea caracterului “ * ”. Să se afişeze 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 citeşte de la tastatură un şir de numere întregi, care se încheie cu citirea
valorii 0. Să se creeze o listă liniară simplu înlănţuită astfel încât, la parcurgerea listei, elementele
să apară în ordinea în care au fost citite.
a). Să se afişeze conţinutul listei;
b). Să se verifice dacă elementele listei sunt ordonate crescător.

Barem:
- declaraţii corecte: 1 punct
- crearea listei: 3 puncte
- vizualizarea conţinutului: 2 puncte
- algoritm de verificare a ordonării crescătoare: 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 înlănţuită formată din numere întregi
introduse de la tastatură. Să se afişeze conţinutul listei, după care să se realizeze transferul
primului element la sfârşitul listei.
Exemplu: Dacă lista conţine iniţial elementele 2, 51, 4, 7, 14, 25, 69 (în această ordine), după
transfer conţinutul va fi: 51, 4, 7, 14, 25, 69, 2 (în această ordine).
Barem:
- declaraţii corecte: 1 punct
- crearea listei: 3 puncte
- vizualizarea conţinutului: 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 operaţia de adăugare a unui nou element la o listă liniară
simplu înlănţuită, implementată dinamic, ce conţine caractere în noduri.
Barem:
- declaraţii corecte: 1 punct
- crearea listei: 3 puncte
- vizualizarea conţinutului: 2 puncte
- adăugarea 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 operaţiile de creare şi vizualizare a unei liste circulare.
Barem:
- declaraţii corecte: 1 punct
- crearea listei: 4 puncte
- vizualizarea conţinutului: 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 operaţia de eliminare a unui element dintr-o listă simplu
înlănţuită, implementată dinamic, ce conţine numere întregi citite de la tastatură. Să se afişeze lista
înainte şi după ştergerea elementului.
Barem:
- declaraţii şi citire: 1 punct
- crearea listei : 3 puncte
- ştergerea unui element: 3 puncte
- afişarea 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 = numărul de vârfuri (n, număr natural pozitiv);
- pentru fiecare vârf se cunosc vârfurile adiacente cu el;
Să se scrie un program prin care să se afişeze:
a). gradul fiecărui vârf (nod);
b). lista tuturor vârfurilor de grad maxim;
c). numărul de vârfuri izolate;
d). numărul de muchii din graf.
Barem:
- declaraţii ş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:
Considerăm următorul graf neorientat:
Graful are 5 noduri (vârfuri), 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” vârfuri, matricea de adiacenţă “A” este o matrice
pătratică de ordinul “n”, simetrică, cu elementele:
1, dacă [i, j] este muchie în graf ; nodurile i şi j sunt extremităţile muchiei
A [i, j] =
0, în caz contrar
Este uşor 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 iniţializarea tuturor elementelor matricii cu zero (în acest fel, anulăm atât elementele
diagonalei principale, cât ş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 cunoaşte numărul muchiilor. Notăm cu [x, y] o muchie din graf, unde x şi y sunt
extremităţile 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. Notând cu “m” numărul de
muchii din graf, vom folosi o structură FOR în care, pentru fiecare muchie “i”, vom introduce
extremităţile “x” şi “y”. Evident, aceste extremităţi sunt vârfuri în graf. Vom scrie:

40
Probleme rezolvate de programare – Subiecte propuse la ATESTAT
For i := 1 to m do
Begin
Writeln (‘Daţi extremităţile muchiei i:’)
Write (‘Daţi vârful x = ‘); readln (x);
Write (‘Daţi vârful y = ‘); readln (y);
A [x, y] := 1;
A [y, x] := 1;{matrice simetrică}
End;
II – B – Dacă NU se cunoaşte numărul muchiilor (este cazul problemei noastre), dar, pentru
fiecare vârf, se cunosc vârfurile adiacente cu el (se cunosc vecinii fiecărui vârf). Notăm cu x,
respectiv cu y două vârfuri din graf. Evident, atât x cât şi y iau valori între 1 şi n (n = numărul total
de vârfuri din graf). Pentru fiecare nod x, trebuie să precizăm numărul vecinilor săi, precum şi care
sunt aceştia. În program vom scrie:
For x := 1 to n do
begin
write (‘Câţi vecini are x, nrvecini = ‘);
readln (nr);
For i := 1 to nrvecini do
begin
write (‘Daţi următorul vecin, y = ‘);
readln (y);
A [x, y] := 1;
A [y, x] := 1
end;
end;

a – Gradul unui vârf “v”, se notează cu d(x) şi este dat de numărul muchiilor incidente cu “v”. În
program vom folosi un vector notat cu “d”, cu 5 elemente (5 = numărul de noduri), fiecare element
reprezentând gradul unui nod (vârf). 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 “i”coincide cu numărul de cifre de 1 de pe linia “i” din
matricea de adiacenţă. Prin urmare, pentru a determina gradul unui nod, numărăm cifrele de 1 de pe
fiecare linie a matricii de adiacenţă şi reţinem aceste numere în elementele vectorului “d”.

b – Determinăm gradul maxim (elementul maxim din vectorul “d”) şi afişăm doar numerele
nodurilor al căror grad = gradul maxim.

c – Un vârf 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 numărul de vârfuri izolate,
numărăm 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ă unităţi (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 vârfuri ş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:
- declaraţii corecte de variabile: 1 punct
- reprezentarea corectă a grafului prin matricea de adiacenţă: 3 puncte
- realizarea algoritmului de prelucrare: 3 puncte
- afişarea 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 conţine n noduri, rezultă că suma
gradelor tuturor nodurilor este = n (n – 1) = 2m.
Prin urmare, problema s-ar putea rezolva foarte simplu verificând dacă n (n – 1) = 2m, având
în vedere că n şi m sunt cunoscute (sunt date de intrare).
Presupunând că nu dorim să verificăm doar relaţia de mai sus, vom face verificări asupra
matricii de adiacenţă A:
a - fie vom număra elementele egale cu 1 din matrice şi vom verifica dacă numărul 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.
Notăm cu [x, y] o muchie din graf, unde x şi y sunt extremităţile 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 cunoaşte numărul muchiilor (m), vom folosi o
structură FOR în care, pentru fiecare muchie “i”, vom introduce extremităţile “x” şi “y”. Evident,
aceste extremităţi sunt vârfuri în graf. Vom scrie:
For i := 1 to m do
Begin
Writeln (‘Daţi extremităţile muchiei i:’)
Write (‘Daţi vârful x = ‘); readln (x);
Write (‘Daţi vârful 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 (‘Daţi extremităţile muchiei i:’)
Write (‘Daţi vârful x = ‘); readln (x);
Write (‘Daţi vârful y = ‘); readln (y);
A [x, y] := 1;
A [y, x] := 1; {matricea este simetrică}
End;
writeln;
-------------------------------------------------------------------------------
{Varianta a - Numărarea 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 - Numărarea 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 numărul de vârfuri şi numărul de muchii
(n, respectiv m, numere naturale introduse de la tastatură). Să se scrie un program care să verifice
dacă graful conţine un ciclu de lungime 4.
Barem:
- declaraţii corecte de variabile: 1 punct
- reprezentarea corectă a grafului prin matricea de adiacenţă: 3 puncte
- realizarea algoritmului de prelucrare: 3 puncte
- afişarea 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ă vârfuri ale sale, cu excepţia primului şi
ultimului, sunt diferite două câte două. Lungimea unui ciclu = numărul de muchii ce apar în ciclu.
Considerând graful din figura de mai jos, se poate observa uşor ciclul 1 – 2 – 3 – 4 – 1 care
are lungimea 4. Matricea de adiacenţă a grafului este următoarea:
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 corespunzătoare nodurilor 1 şi 3 conţin amândouă cifra 1 pe poziţiile k = 2 şi k = 4.
De asemenea, liniile corespunzătoare nodurilor 2 şi 4 conţin amândouă cifra 1 pe poziţiile
k = 1 şi k = 3.
Va trebui să verificăm dacă, pentru fiecare pereche de noduri distincte, liniile (din matricea
de adiacenţă) corespunzătoare acestor noduri conţin cifra 1 pe cel puţin 2 poziţii (coloane) identice.
Notăm cu “i”, respectiv “j” două linii distincte din matricea de adiacenţă, linii
corespunzătoare a două noduri “i” şi “j”. Evident, i = 1 .. n-1, iar j = i + 1 .. n.
Notăm cu “k” indexul de coloană (din matricea de adiacenţă) pentru care se face testarea
perechii A [i, k] şi A [j, k]. Iniţializăm un contor nrcifre care numără cifrele de 1, în condiţia
( 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 (‘Daţi extremităţile muchiei i:’)
Write (‘Daţi vârful x = ‘); readln (x);
Write (‘Daţi vârful 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 vârfuri şi m arce (n şi m numere naturale


citite la intrare) să se scrie un program care să determine matricea drumurilor. Matricea se va afişa
pe ecran linie cu linie.
Barem:
- declaraţii 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
- afişarea matricii drumurilor: 2 puncte
- din oficiu: 1 punct

Rezolvare:
a1 Reamintim câteva noţiuni 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 celălalt nod comun cu ak+1 , pentru orice k din mulţimea {
2, p-1}. NU ARE IMPORTANŢĂ ORIENTAREA ARCELOR.
a3 Exemplu: Pentru graful din figura alăturată, lanţuri cu extremităţile
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 numeşte drum (notat D) dacă toate arcele sale au ACEEAŞI
ORIENTARE, dată de sensul deplasării de la x0 (extremitatea iniţială a lui a1) la xp (extremitatea
finală a lui ap). Vârfurile x0 şi xp = extremităţile lanţului. De observat că, în cazul drumului,
ARE IMPORTANŢĂ ORIENTAREA ARCELOR
Altfel spus, un drum într-un graf orientat este un şir de vârfuri. Un drum se poate scrie fie
ca o succesiune de arce, fie ca o succesiune de vârfuri. Pentru graful alăturat, 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 plecând de la matricea de
adiacenţă astfel:
Un element A [i, j] = 0 din matricea de adiacenţă devine 1 în matricea drumurilor dacă
există un vârf k astfel încât
A [i, k] = 1 şi A [k, j] = 1,
adică atunci când există drum de la xi la xk şi drum de la xk la xj. Această condiţie 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 (’Daţi extremităţile muchiei i:’);
Write (’Daţi vârful x = ’); readln (x);
Write (’Daţi vârful 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 vârfuri şi m arce (n şi m sunt numere
naturale citite la intrare), să se scrie un program care să construiască şi să afişeze listele de adiacenţă
ale succesorilor vârfurilor grafului sub formă de liste liniare simplu înlănţuite.
Barem:
- declaraţii corecte de variabile: 2 puncte
- generarea listelor de adiacenţă: 4 puncte
- afişarea 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 vârf x se construieşte o listă L ( x ) a
succesorilor vârfului x. Liste de adiacenţă pot fi reprezentate folosind tablouri sau structuri
dinamice de date.
Exemplu: pentru graful alăturat, 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
înlănţuite), 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 extremităţile x şi y,
Fiecare element al listei va avea două componente:
- NodSuccesor = y = extremitatea finală a nodului curent
- URM = informaţia de legătură către următorul element al listei de adiacenţă.
Vom face următoarele declaraţii:
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 ;
Iniţializăm toate componentele listei L cu pointerul NIL, scriind:
for i := 1 to n do
L [i] := NIL;
Prezenţa în graf a unui arc (x, y) presupune crearea unei locaţii de memorie cu NEW (P), urmată de
calificarea celor două câmpuri (NodSuccesor şi URM) ale noii locaţii. 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 vârfuri şi m arce, să se scrie un program prin
care:
a) să se calculeze gradul interior, respectiv exterior al fiecărui vârf
b) să se verifice dacă graful are vârfuri izolate
Datele de intrare se preiau din fişierul text INPUT.TXT sub forma următoare :
pe prima linie: n - reprezentând numărul de vârfuri ale grafului ;
pe linia a doua : m - reprezentând numărul de arce ale grafului ;
pe următoarele m linii, câte o pereche de numere, separate printr-un spaţiu, ce reprezintă
extremitatea iniţială, respectiv finală a arcului.
Rezultatele se vor afişa pe ecran.
Barem:
- declaraţii corecte de variabile: 1 punct
- citirea corectă a datelor din fişier: 1 punct
- reprezentarea corectă a grafului prin matricea de adiacenţă: 2 puncte
- realizarea punctului a): 2 puncte
- realizarea punctului b): 2 puncte
- afişarea 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 câte n componente, în care vom memora
gradul exterior şi interior al fiecărui vârf. Dacă pentru un vârf suma celor două grade este zero,
acel vârf este izolat.
1 4 5
Exemplu: pentru graful alăturat, fişierul
GRAF.TXT, de pe discul C:, va avea
conţinutul:
6 {numărul de noduri} 2 3 6
8 {numărul 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ă vârful 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 vârfuri şi m arce, reprezentat în memorie


prin matricea de adiacenţă. Să se scrie un program care, pornind de la matricea drumurilor
corespunzătoare grafului, să verifice dacă:
a). graful are vârfuri izolate;
b). graful conţine circuite (n şi m sunt numere naturale citite la intrare).
Barem:
- declaraţii 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
Considerăm graful din figura alăturată.
Notăm cu GradExt, respectiv GradInt, gradul
exterior şi interior al fiecărui vârf.
 Dacă pentru un vârf suma celor două grade 2 3 6
este zero, acel vârf este izolat.
 De asemenea, un vârf 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
vârfuri. Un drum se poate scrie fie ca o 5 0 2 2
succesiune de arce, fie ca o succesiune de 6 0 0 0
vârfuri.
Dacă toate arcele unui drum sunt distincte, iar primul şi ultimul nod coincid, drumul se numeşte
circuit.
Dacă toate vârfurile unui circuit, cu excepţia primului şi ultimului, sunt distincte, circuitul este
elementar.
Pentru graful alăturat, 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 conţine noduri izolate, declarăm doi vectori zeropelin si zeropecol in
care memorăm numarul de zero-uri de pe fiecare linie, respectiv fiecare coloană. Apoi, pentru fiecare
linie din matricea de ADIACENŢĂ, verificam dacă este îndeplinită condiţia
( 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 conţine elemente
egale cu 1 pe diagonala principală. Din faptul că matricea drumurilor are numai elemente de 1 pe
diagonala principală deducem doar că fiecare vârf aparţine 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.

FUNCŢII ŞI PROCEDURI RECURSIVE

ATESTAT - 2005 - 25 - Să se scrie un program care citeşte de la tastatură un număr natural n şi


apelează o funcţie recursivă, care întoarce valoarea produsului:
p (n) = 1 * 3 * 5 *…* (2n+1).
Exemple: pentru n = 0, se va afişa p (0) = 1, adică 2 * 0 + 1
pentru n = 3, se va afişa p (3) = 105, adică 1 * 3 * 5 * 7
Barem:
- corectitudinea definiţiei recursive: 3 puncte
- declaraţie corectă de funcţie: 2 puncte
- condiţia de ieşire din funcţie: 2 puncte
- corectitudine sintactică: 1 punct
- din oficiu: 1 punct

Rezolvare: Algoritmul recursiv pentru calcularea produsului din enunţ este asemănător 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 citeşte de la tastatură numărul natural n.
Programul trebuie să apeleze o funcţie recursivă, care să întoarcă valoarea sumei S (n), unde
S (n) = 2 + 5 + 8 + ... + (2 + 3*n).
Valoarea pentru numărul n este citită în programul principal. Valoarea calculată de funcţie va fi
afişată pe ecran tot în programul principal.
Exemplu: pentru n = 3, se va afişa valoarea 26 ( S (3) = 2 + 5 + 8 + 11 ).
Barem:
- corectitudinea definiţiei recursive: 3 puncte
- declaraţie corectă de funcţie: 2 puncte
- condiţia de ieşire din funcţie: 2 puncte
- corectitudine sintactică: 1 punct
- din oficiu: 1 punct

Rezolvare: Algoritmul recursiv pentru calcularea sumei din enunţ este asemănător 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 număr natural n introdus de la tastatură. Scrieţi un program care
calculează suma cifrelor acestui număr. Programul trebuie să apeleze o funcţie recursivă care să
întoarcă valoarea sumei.
Barem:
- corectitudinea definiţiei recursive: 3 puncte
- declaraţie corectă de funcţie: 2 puncte
- condiţia de ieşire din funcţie: 2 puncte
- corectitudine sintactică: 1 punct
- din oficiu: 1 punct

Rezolvare: Pentru numărul “x”, trebuie să determinăm, mai întâi, numărul de cifre şi apoi vom
calcula suma cifrelor. Vom defini două funcţii 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 număr natural n în baza 10 şi un număr natural b (2 <= b <= 9).
Să se scrie un program care să convertească numărul n în baza b, utilizând în acest scop un
subprogram recursiv.
Barem:
- apel corect de subprogram: 2 puncte
- declaraţie 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 reţin resturile împărţirii numărului 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 câte un spaţiu. Cuvintele se citesc
de la tastatură din n linii. Să se scrie un program care să afişeze fiecare cuvânt aşa cum s-a citit şi
apoi cu literele inversate. Să se rezolve problema recursiv.
Barem:
- apel corect de subprogram: 2 puncte
- declaraţie corectă de subprogram: 3 puncte
- algoritm corect de inversare recursivă: 3 puncte
- corectitudine sintactică: 1 punct
din oficiu: 1 punct

Rezolvare: Definim o funcţie 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. Scrieţi un program care afişează şirul citit în ordine inversă. Să se rezolve problema
recursiv.
Barem:
- apel corect de subprogram: 2 puncte
- declaraţie corectă de subprogram: 3 puncte
- algoritm corect de inversare recursivă: 3 puncte
- corectitudine sintactică: 1 punct
- din oficiu: 1 punct

Rezolvare: Definim o funcţie 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 fişierul standard de intrare un număr natural x. Să se


creeze un fişier text, numit FACTORI.TXT cu structura :
- pe prima linie se va scrie valoarea lui x;
- pe următoarele linii se vor scrie factorii primi şi puterile lor, în descompunerea lui x în factori
primi (câte un factor pe o linie).
Să se citească fişierul creat şi să se afişeze pe ecran descompunerea numărului x.

65
Probleme rezolvate de programare – Subiecte propuse la ATESTAT
Barem:
- declaraţii şi citire corectă: 1 punct
- algoritmul de descompunere în factori primi: 3 puncte
- crearea fişierului FACTORI.TXT: 2 puncte
- listarea conţinutului fişierului: 3 puncte
- din oficiu: 1 punct

Rezolvare:
 În ipoteza că fişierul text nu există deja pe disc, vom crea acest fişier cu acelaşi program care face
şi celelalte determinări cerute de enunţ.
 După citirea de la tastatură a numărului “x”, îl vom converti într-un şir de caractere, notat “sirx”,
prin apelarea procedurii “STR”. Introducem în fişierul text şirul “sirx” asociat numărului “x”.
 În fişierul text se vor introduce atât factorii primi în care se descompune x, cât şi puterile lor,
astfel:
Transformăm factorii în “sir1”, iar puterile în “sir2”
După fiecare astfel de număr transformat în şir, fie vom lăsa câte un singur spaţiu liber
(blank), fie vom adăuga un comentariu (un şir de caractere). În acest fel, se va crea, prin
CONCATENARE, câte o “linie” în fişierul 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 conţine numere


întregi. Să se determine linia ce conţine cel mai mare element în valoare absolută din matrice.
Datele de intrare se vor prelua dintr-un fişier text MATRICE.TXT cu structura :
- prima linie conţine m şi n (două numere întregi pozitive, separate printr-un spaţiu)
- următoarele m linii conţin fiecare n numere întregi separate printr-un spaţiu.
Rezultatele se vor afişa pe ecran.
Barem :
- crearea fişierului de intrare : 1 punct
- citire din fişier : 3 puncte
- algoritmul pentru determinarea elementului maxim: 4 puncte
- afişare rezultate: 1 punct
din oficiu: 1 punct

67
Probleme rezolvate de programare – Subiecte propuse la ATESTAT
Rezolvare: Folosim funcţia STR pentru conversia unui număr într-un şir, la introducerea
elementelor matricii în fişier.
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 crescător în funcţie de suma liniilor matricii, prin una din metodele învăţate. Se va
menţiona metoda folosită printr-un comentariu în program. Datele de intrare se vor citi dintr-un fişier
text INPUT.TXT, iar matricea ordonată se va afişa pe ecran linie cu linie.
Barem :
- crearea fişierului de intrare: 1 punct
- citire din fişier: 3 puncte
- algoritm de sortare crescătoare a liniilor: 4 puncte
- afişare 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 selecţie.

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 - Scrieţi un program care să realizeze REUNIUNEA a două mulţimi 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 afişa pe ecran.
Barem:
- declaraţii de variabile: 1 punct
- citire corectă a datelor: 2 puncte
- algoritm de prelucrare corect descris: 5 puncte
- afişarea reuniunii: 1 punct
- din oficiu: 1 punct

Rezolvare: Construim două mulţimi Ma şi Mb care conţin, fiecare, elementele vectorilor A,


respectiv B, şi apoi reunim cele două mulţimi.

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 - Scrieţi un program care să realizeze INTERSECŢIA a două mulţimi 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 afişa pe ecran.
Barem:
- declaraţii de variabile: 1 punct
- citire corectă a datelor: 2 puncte
- algoritm de prelucrare corect descris: 5 puncte
- afişarea intersecţiei: 1 punct
- din oficiu: 1 punct

Rezolvare: Construim două mulţimi Ma şi Mb care conţin, fiecare, elementele vectorilor A,


respectiv B, şi apoi intersectăm cele două mulţimi.

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 - Scrieţi un program care să realizeze DIFERENŢA a două mulţimi 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 afişa pe ecran.
Barem:
- declaraţii de variabile: 1 punct
- citire corectă a datelor: 2 puncte
- algoritm de prelucrare corect descris: 5 puncte
- afişarea diferenţei: 1 punct
- din oficiu: 1 punct

Rezolvare: Construim două mulţimi Ma şi Mb care conţin, fiecare, elementele vectorilor A,


respectiv B, şi apoi facem diferenţa celor două mulţimi.

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 - Scrieţi un program care să afişeze elementele care sunt numere prime,
dintr-o matrice pătratică cu n x n elemente întregi pozitive. Dacă în matrice nu sunt astfel de
elemente să se menţioneze acest lucru printr-un mesaj adecvat afişat pe ecran.
Barem:
- declaraţii de variabile: 1 punct
- citire corectă a datelor: 2 puncte
- algoritm de determinare număr prim: 5 puncte
- afişare numere prime, respectiv mesaj: 1 punct
- din oficiu: 1 punct

Rezolvare: Verificăm primalitatea unui număr întreg, definind o funcţie 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 ordonaţi crescător. Vectorii au m, respectiv n componente numere reale. La citire, să se
verifice dacă vectorii sunt ordonaţi crescător. Dacă unul din ei nu satisface această condiţie, să se
facă ordonarea prin una din metodele învăţate.
Barem:
- declaraţii de variabile: 1 punct
- citire corectă a datelor, cu ordonare, când este cazul: 3 puncte
- algoritm de interclasare: 4 puncte
- afişare vector interclasat: 1 punct
- din oficiu: 1 punct

77
Probleme rezolvate de programare – Subiecte propuse la ATESTAT
Rezolvare: Ordonăm vectorii prin metoda bubble sort, după care interclasăm 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