2005
BACKTRACKING
ATESTAT - 2005 - 1 - Se citesc de la tastatur dou numere naturale n i k (0 < k < n < 12). S se
afieze toate irurile formate din k litere distincte, litere alese dintre primele n ale alfabetului
englez. Exemplu: pentru k = 2 i n = 4, se afieaz, nu neaprat n aceast ordine, irurile: AB, BA,
AC, CA, AD, DA, BC, CB, BD, DB, CD, DC.
Rezolvare:
Aplicm algoritmul BACKTRACKING pentru generarea aranjamentelor.
program ATESTAT_2005_1_ARANJAMENTE_1;
uses CRT;
CONST
Kmax = 20; { nr. max al elementelor din A }
Nmax = 50; { nr. max al elementelor din B sau nr. valorilor functiei }
TYPE
functie = array [ 1..Kmax ] of 0..Nmax;
VAR
k, poz, i : 1 .. Kmax; { se considera k <= n }
n : 0 .. Nmax;
f : functie; {sau f : array [1..Kmax] of [1..Nmax];}
IMAG : set of 1 .. Nmax; { IMAG = multimea imaginilor elementelor din A }
{ adica f [poz] }
Begin { PROGRAM PRINCIPAL }
clrscr;
repeat
write ('k = ');
readln (k);
until ( k >= 1 ) AND ( k <= Kmax );
repeat
write ('Introduceti un n >= ', k,' n = ');
readln (n);
if n < k then
writeln ('Pentru acest n = ', n,' Nu exista solutii')
until ( n >= k ) AND ( n >= 1 ) AND ( n <= Nmax );
writeln;
writeln ('Apasati ENTER pentru urmatoarea solutie');
writeln;
readln;
ATESTAT - 2005 - 2 - Civa copii cu vrste ntre 2 si 7 ani trebuie s fie vizitai de Mo Crciun.
Scriei un program care determin toate modurile diferite n care pot ei s fie aezai n lista lui Mo
Crciun, astfel nct s fie vizitai toi copiii i vizitele s se fac n ordinea cresctoare a vrstei
lor. Se citesc de la tastatur: n = numrul de copii (0 < n < 10), apoi numele i vrsta fiecruia dintre
cei n copii. Se scriu, pe linii diferite, liste cu numele copiilor, n ordinea n care vor fi vizitai de Mo
Crciun. O list este format din toate cele n nume ale copiilor, ntr-o anumit ordine, oricare dou
nume succesive fiind desprite prin spaii.
Exemplu:
Pentru datele de intrare: n = 4, Dan 6, Cristina 4, Corina 2, Iulia 4
se scriu urmtoarele soluii:
Corina Iulia Cristina Dan
Corina Cristina Iulia Dan
Rezolvare:
Definim o procedur ORDONEAZ, pentru ordonarea numelor copiilor.
program ATESTAT_2005_2_MOS_CRACIUN_SI_COPIII;
uses crt;
const
nmax = 100;
type
vector = array [1..nmax] of integer;
vector_nume = array [1..nmax] of string;
vector_virsta = array [1..nmax] of integer;
var
f : vector;
sol, n, i : integer;
incep, sf : integer;
NUME : vector_nume;
VIRSTA : vector_virsta;
EGAL : boolean;
t : integer;
k : integer; {contor care numara elementele vecine egale in vectorul VIRSTA }
pozitie : integer; {pozitia incepind de la care apar elemente egale}
{in vectorul VIRSTA}
4
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure ORDONEAZA (VAR v1:vector_virsta; VAR v2 : vector_nume; q:integer);
var
k1, j, aux: integer;
siraux : string;
begin
repeat
k1:= 0;
j := 1;
repeat
if v1[j] > v1 [j+1] then
begin
aux := v1 [j];
v1 [j] := v1 [j+1];
v1 [j+1] := aux;
siraux := v2 [j];
v2 [j] := v2 [j+1];
v2 [j+1] := siraux;
k1 := 1
end;
j := j + 1
until (j > q-1)
until (k1 = 0);
end;
procedure VERIFICA ( pozitia : integer; f : vector ; VAR CONTIN : boolean );
LABEL
10;
VAR
j : integer;
begin
CONTIN := TRUE;
for j := 1 to pozitia - 1 do
begin
if f [j] = f [pozitia] then
begin
CONTIN := FALSE;
GOTO 10
end;
end;
10:
end;
procedure SCRIE ;
var
j : integer;
begin
sol := sol + 1;
write ('Solutia nr. ',sol,' ');
for t := 1 to incep - 1 do
begin
write ( NUME [t],' ');
end;
for j := 1 to sf - incep + 1 do
begin
write ( NUME [ f [j] + incep - 1 ],' ' )
end;
for t := sf + 1 to n do
begin
write ( NUME [t],' ');
end;
writeln;
readln;
end;
5
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure PERMUTA ( incep, sf : integer );
LABEL
20;
var
m : integer;
poz : integer;
CONTIN : boolean;
begin
m := sf - incep + 1;
poz := 1;
f [poz] := 0;
while poz > 0 do
begin
CONTIN := FALSE;
while f [poz] < m do
begin
f [poz] := f [poz] + 1;
VERIFICA (poz, f, CONTIN);
if CONTIN = TRUE then
GOTO 20
end;
20: if ( CONTIN = TRUE ) AND (poz = m) then
SCRIE;
if ( CONTIN = TRUE ) and (poz < m) then
begin
poz := poz + 1;
f [poz] := 0;
end;
if CONTIN = FALSE then
poz := poz - 1
end; {sf. WHILE exterior}
end;
sol := 0;
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;
if sol = 0 then
writeln ('Nu exista solutie');
readln
END.
Rezolvare:
Completm acest algoritm cu cerinele enunului de mai sus.
Mulimile care se nmulesc cartezian vor avea "nrcif" elemente.
Numrul de mulimi care se vor nmuli cartezian = k. Altfel spus, numerele generate vor avea
cte k cifre.
Exemplu, pentru n = 216 (nrcif = 3) i k = 2, vom obine:
(1,2,6) x (1,2,6) = (1,1), (1,2), (1,6), (2,1), (2,2), (2,6), (6,1), (6,2), (6,6)
program ATESTAT_2005_3_Produs_cartezian;
uses CRT;
type
vector = array [1..20] of integer;
var
k, nrcif, i, x, n : integer;
w, m, f : vector;
sir : string;
a, er : integer;
7
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure SCRIE;
begin
for i := 1 to k - 1 do
begin
write (w [ f[i] ]);
end;
write ( w [ f[k] ]);
writeln;
end;
8
Probleme rezolvate de programare Subiecte propuse la ATESTAT
x := 1;
f [x] := 0;
while x > 0 do
begin
if f [x] < nrcif then
begin
f [x] := f[x] + 1;
if x = k then
begin
SCRIE;
readln;
end
else
begin
x := x + 1; {PAS INAINTE}
f [x] := 0
end
end
else
x := x 1 {PAS INAPOI}
end;
readln
END.
ATESTAT - 2005 - 4 - S se genereze toate irurile de n (n < 6, numr natural dat de la tastatur)
note muzicale din mulimea {do, re, mi, fa, sol, la, si}. Orice not poate s nu apar sau se poate
repeta n cadrul unui ir. Fiecare ir va fi afiat pe cte o linie, n cadrul liniei, notele fiind separate
prin cte un spaiu.
Exemplu: pentru n = 5, unul dintre irurile generate este:
mi do do si mi
Rezolvare:
program ATESTAT_2005_4_Produs_cartezian;
uses CRT;
type
vector = array [1..20] of integer;
var
p, i, x, n : integer;
f : vector;
nota : array [1..7] of string;
procedure SCRIE;
begin
write ('{ ');
for i := 1 to n - 1 do
begin
write (nota [ f[i] ],' , ');
end;
write ( nota [ f[n] ],' ');
write ('} ');
writeln;
end;
9
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
CLRSCR;
writeln ('Precizati cite note trebuie sa contina sirul, de exemplu n = 6');
write ('Dati n = ');
readln (n);
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 - 5 - S se genereze toate cuvintele de lungime n (n < 10) ale alfabeltului Morse
(formate doar din caracterele '-' i '.'), care nu ncep i nu se termin cu caracterul '-'. Fiecare cuvnt
va fi afiat pe cte o linie.
Rezolvare:
Vom genera produsul cartezian M x M x M ...x M, de n ori, n care mulimea M este format
doar din caracterele . i -.
Asociem: cifrei 1, caracterul "-" cu codul ASCII 45
i cifrei 2, caracterul "." cu codul ASCII 46.
10
Probleme rezolvate de programare Subiecte propuse la ATESTAT
program ATESTAT_2005_5_Codul_Morse_produs_cartezian;
uses CRT;
type
vector = array [1..20] of integer;
var
p, i, x, n : integer;
m, f : vector;
procedure SCRIE;
begin
for i := 1 to n do
write (CHR (44 + f[i] ),' ');
writeln;
end;
Begin { PROGRAM PRINCIPAL }
CLRSCR;
writeln ('Precizati de cite ori trebuie inmultita multimea M cu ea insasi');
write ('Dati n = '); readln (n);
ATESTAT - 2005 - 6 - Se citete un cuvnt format din maxim 20 de litere distincte. S se afieze
toate anagramele cuvntului respectiv. Un cuvnt A este anagrama unui cuvnt C dac A
este format din aceleai litere ca i cuvntul C, dar aezate n alt ordine.
Exemplu: Pentru cuvntul "car", trebuie afiate, nu neaprat n aceast ordine, anagramele:
car -> cra, acr, arc, rca, rac.
Rezolvare:
11
Probleme rezolvate de programare Subiecte propuse la ATESTAT
program ATESTAT_2005_6_PERMUTARI_ITERATIV;
uses crt;
const
nmax = 100;
type
vector = array [1..nmax] of integer;
var
f : vector;
sir : string;
lungime_sir : integer;
sol, n, i : integer;
procedure VERIFICA ( k : integer; f : vector ; VAR CONTIN : boolean );
LABEL
10;
begin
CONTIN := TRUE;
for i := 1 to k - 1 do
begin
if f [i] = f [k] then
begin
CONTIN := FALSE;
GOTO 10
end;
end;
10: end;
procedure SCRIE ;
begin
sol := sol + 1;
write ('Solutia nr. ',sol,' ');
for i := 1 to n do
write ( sir [f [i] ] )
readln; writeln {optionale}
end;
procedure PERMUTA ( m : integer );
LABEL
20;
var
k : integer;
CONTIN : boolean;
begin
k := 1;
f [k] := 0;
while k > 0 do
begin
CONTIN := FALSE;
while f [k] < m do
begin
f [k] := f [k] + 1;
VERIFICA (k, f, CONTIN);
if CONTIN = TRUE then
GOTO 20
end;
20: if ( CONTIN = TRUE ) AND (k = n) then
SCRIE;
if ( CONTIN = TRUE ) and (k < n) then
begin
k := k + 1; {PAS INAINTE}
f [k] := 0
end;
if CONTIN = FALSE then
k := k 1 {PAS INAPOI}
end; {sf. WHILE exterior}
end;
12
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
clrscr;
sol := 0;
writeln;
n := lungime_sir;
writeln;
writeln;
PERMUTA (n);
if sol = 0 then
writeln ('Nu exista solutie');
readln
END.
ATESTAT - 2005 - 7 - Se citete din fiierul standard de intrare un numr natural n aparinnd N*
i o mulime M cu p elemente numere ntregi. S se determine i s se scrie elementele produsului
cartezian M x M x...x M (de n ori).
Rezolvare:
program ATESTAT_2005_7_produs_cartezian;
uses CRT;
type
vector = array [1..20] of integer;
var
p, i, x, n : integer;
m, f : vector;
procedure SCRIE;
begin
write ('{ ');
for i := 1 to n - 1 do
begin
write (f[i],' , ');
end;
write ( f[n],' ');
write (' ');
writeln;
end;
13
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
CLRSCR;
writeln ('Precizati de cite ori trebuie inmultita multimea M cu ea insasi');
write ('Dati n = '); readln (n);
write ('Dati numarul de elemente ale multimii M, p = '); readln (p);
writeln;
writeln ('Apasati ENTER dupa fiecare solutie');
readln;
x := 1;
f [x] := 0;
while x > 0 do
begin
if f [x] < p then
begin
f [x] := f[x] + 1;
if x = n then
begin
SCRIE;
readln;
end
else
begin
x := x + 1; {PAS INAINTE}
f [x] := 0
end
end
else
x := x 1 {PAS INAPOI}
end;
readln
END.
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;
15
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 9 - S se genereze toate PALINDROAMELE care au n cifre, iar cifrele au
valori ntre 0 i p. Se citesc de la tastatur n i p (0 < n < 10, 0 < p < 5). Reamintim c un numr este
PALINDROM dac numrul coincide cu imaginea lui n oglind. Altfel spus, un numr este
PALINDROM dac citit direct i invers rezultatul este acelai.
Exemplu: 121 este PALINDROM.
Barem :
- declararea variabilelor: 0.5 puncte
- citirea datelor de intrare: 1 punct
- un algoritm de generare principial corect: 3 puncte
- verificarea condiiilor de continuare : 2 puncte
- afiarea soluiilor: 2 puncte
- corectitudinea sintactic a programului : 0.5 puncte
- din oficiu 1 punct.
Rezolvare:
program ATESTAT_2005_9_ PALINDROAME;
uses CRT;
type
vector = array [1..20] of integer;
var
m, f : vector;
p, poz, A, B, x, n, nrcif, i : integer;
OK : boolean;
y : array [1..100] of integer;
function PUTERE (z: integer; t : integer): integer;
var
p1, j: integer;
begin
p1 := 1;
for j := 1 to t do
p1 := p1 * z;
PUTERE := p1
end;
function NRCIFRE (x : integer) : integer;
begin
if x = 0 then
nrcif := 1
else
begin
nrcif := 0;
while x <> 0 do
begin
nrcif := nrcif + 1;
x := x DIV 10
end;
end;
NRCIFRE := nrcif
end;
function PALINDROM ( x : integer ) : boolean;
begin
n := NRCIFRE (x);
for i := n DOWNTO 1 do
begin
y [i] := x MOD 10;
x := x DIV 10;
end;
16
Probleme rezolvate de programare Subiecte propuse la ATESTAT
OK := TRUE;
for i := 1 to n DIV 2 do
begin
if y [i] <> y [n-i+1] then
OK := FALSE
end;
PALINDROM := OK
end; { sfarsit functie PALINDROM }
procedure SCRIE;
begin
write ('{ ');
for i := 1 to n - 1 do
begin
write (f[i],' , ');
end;
write ( f[n],' ');
write (' ');
writeln; writeln;
end;
Begin { PROGRAM PRINCIPAL }
CLRSCR;
writeln ('Precizati numarul de cifre al viitorului numar');
write ('Dati n = '); readln (n);
{n = nr de multimi ale produsului cartezian }
writeln;
repeat
writeln ('Precizati care este cea mai mare cifra din viitorul numar');
write ('Dati p = '); readln (p);
until (p > 0) AND (p<=5);
writeln;
{este acelasi lucru cu a cere numarul de elemente din fiecare multime }
{implicata in calculul produsului cartezian }
poz := 1;
f [poz] := 0;
while poz > 0 do
begin
if f [poz] < p then
begin
f [poz] := f[poz] + 1;
if poz = n then
begin
x := 0;
for i := n downto 1 do
begin
x := x + PUTERE (10, n-i) * f [i];
end;
if PALINDROM (x) = TRUE then
begin
writeln ('x = ', x, ' este PALINDROM');
SCRIE;
end;
end
else
begin
poz := poz + 1; {PAS INAINTE}
f [poz] := 0
end
end
else
poz := poz 1 {PAS INAPOI}
end;
readln
END.
17
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ALOCARE DINAMICA
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;
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;
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;
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;
if j<=n then
begin
write('dati cheia nodului ', j,' : ');
readln(q^.cheie);
CITDATA;
q^.data:=data;
p:=q
end
21
Probleme rezolvate de programare Subiecte propuse la ATESTAT
else
begin
q^.cheie:=N+1;
{ q^.data:='ACEST NOD NU SE VA STERGE SI NU SE ADAUGA NIMIC DUPA EL'; }
p:=q
end
end;
procedure CAUTA ; { cauta un nod dupa cheie }
var
b:boolean;
begin
b:=false;
write('DATI CHEIA X = ');
readln(x);
writeln;
p:=baza;
while (p<>nil) and not b do
begin
if p^.cheie=x then
b:=true
else
p:=p^.urm
end;
if not b then
writeln('NODUL ( CHEIA ) NU EXISTA ')
else
begin
writeln('PRIMUL NOD CARE ARE CHEIA ',X,' ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln
end
end;
procedure STERGE ;{ sterge un nod indicat printr-o cheie }
begin
q:=p^.urm;
p^:=q^
end;
Begin { PROGRAM PRINCIPAL }
write('Dati numarul de noduri N = '); readln(n);
writeln;
if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');
INSEREAZAPRIMUL;
writeln
end;
if n > 1 then
begin
for j:=2 to n do
begin
INSEREAZAREST;
writeln
end
end;
j:=j+1;
writeln('INTRODUCETI NODUL F A N I O N ');
INSEREAZAREST;
writeln;
22
Probleme rezolvate de programare Subiecte propuse la ATESTAT
writeln(' LISTA ESTE : ');
TRAVLISTA;
writeln;
10: write('DORITI SA CAUTATI UN NOD ? APASATI D SAU N ');
readln(c);
if (c='d') or (c='D') then
CAUTA
writeln;
write('DORITI SA STERGETI UN NOD ? APASATI D SAU N ');
readln(c);
writeln;
if (c='d') or ( c='D') then
begin
CAUTA;
writeln('CONTINUT NOD CU CHEIA ',X,' INAINTE DE STERGERE ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln;
STERGE;
writeln;
writeln('CONTINUTUL NODULUI DUPA STERGERE ESTE :');
writeln(p^.cheie,' ',p^.data);
writeln;
writeln('LISTA DUPA STERGEREA NODULUI CU CHEIA ',X,' ESTE :');
TRAVLISTA;
writeln
end;
write('DORITI SA RELUATI PROGRAMUL ? APASATI D SAU N ');
readln(c);
writeln;
if ( c='d') or ( c='D') then goto 10;
500: readln
END.
ATESTAT - 2005 - 12 - S se creeze o list liniar dublu nlnuit avnd ca elemente cuvinte
citite din fiierul standard de intrare, pn la ntlnirea caracterului * . S se afieze cuvintele n
ordine invers citirii i apoi n ordinea n care s-au citit.
Barem:
- declararea corect a variabilelor: 1 punct
- crearea: 4 puncte
- vizualizarea: 4 puncte
- din oficiu: 1 punct
Rezolvare:
program ATESTAT_2005_12_LISTA_DUBLU_INLANTUITA;
uses CRT;
label
10, 500;
type
LISTA = ^nod;
nod = record
cheie : integer;
data : string;
urm, preced : LISTA
end;
23
Probleme rezolvate de programare Subiecte propuse la ATESTAT
var
q,r,baza,p: LISTA;
n,x,i,j:integer;
data:string;
c:char;
procedure CITDATA; { introducere date utile }
begin
write ('Introduceti datele nodului : ');
readln (data);
end;
procedure TRAVLISTA_INCEP_SFARSIT ; { traversare lista inceput -> sfirsit }
begin
p:=baza;
writeln ('--------------------------------------');
writeln ('Traversare in sens direct');
writeln ('--------------------------------------');
while ( p<>nil ) AND ( p^.data <> '*' ) do
begin
writeln ('NODUL cu cheia= ',p^.cheie,' data= ',p^.data);
p:=p^.urm;
end;
writeln('Ultimul NOD (FANION): cheia= ',p^.cheie,' data= ',p^.data);
end;
procedure TRAVLIST_SFARSIT_INCEP; { traversare lista sfirsit -> inceput }
begin
p:=baza;
q:=p;
p:=p^.urm;
p^.preced := q;
q := p;
p:=p^.urm;
p^.preced := q;
end;
writeln ('--------------------------------------');
writeln ('Traversare in sens invers');
writeln ('--------------------------------------');
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:='*';
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.
Barem:
- declaraii corecte: 1 punct
- crearea listei: 3 puncte
- vizualizarea coninutului: 2 puncte
- algoritm de verificare a ordonrii cresctoare: 3 puncte
- din oficiu: 1 punct
26
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare:
program ATESTAT_2005_13_LISTA_LINIARA_SIMPLU_INLANTUITA_INTREGI;
uses CRT;
label
10,500;
const
nmax = 50;
type
LISTA = ^Nod;
Nod = record
cheie : integer;
data : integer;
urm : LISTA
end;
vector = array [1..nmax] of integer;
var
q, r, baza, p : LISTA;
n, x, i, j : integer;
data : integer;
c : char;
v : vector;
function VERIFICA ( v : vector; q:integer) : boolean;
var
j : integer;
begin
VERIFICA := TRUE;
j := 1;
repeat
if v[j] > v [j+1] then
VERIFICA := FALSE;
j := j + 1
until (j > q-1)
end;
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;
500: readln
END.
ATESTAT - 2005 - 14 - S se creeze o list liniar simplu nlnuit format din numere ntregi
introduse de la tastatur. S se afieze coninutul listei, dup care s se realizeze transferul
primului element la sfritul listei.
Exemplu: Dac lista conine iniial elementele 2, 51, 4, 7, 14, 25, 69 (n aceast ordine), dup
transfer coninutul va fi: 51, 4, 7, 14, 25, 69, 2 (n aceast ordine).
Barem:
- declaraii corecte: 1 punct
- crearea listei: 3 puncte
- vizualizarea coninutului: 2 puncte
- realizarea transferului cerut: 3 puncte
- din oficiu: 1 punct
28
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare:
program ATESTAT_2005_14_LISTA_SIMPLU_INLANTUITA;
uses CRT;
label
10, 500;
type
LISTA = ^NOD;
NOD = record
cheie : integer;
data : integer;
urm : LISTA
end;
var
q,r,baza,p: LISTA;
n,x,i,j:integer;
data:integer;
primul, ultimul : integer;
c:char;
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;
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;
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;
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;
31
Probleme rezolvate de programare Subiecte propuse la ATESTAT
p^.data := ultimul;
writeln;
TRAVLISTA_INCEP_SFIRSIT ;
500: readln
END.
ATESTAT - 2005 - 15 - S se descrie operaia de adugare a unui nou element la o list liniar
simplu nlnuit, implementat dinamic, ce conine caractere n noduri.
Barem:
- declaraii corecte: 1 punct
- crearea listei: 3 puncte
- vizualizarea coninutului: 2 puncte
- adugarea unui element: 3 puncte
- din oficiu: 1 punct
Rezolvare:
program ATESTAT_2005_15_LISTA_LINIARA_SIMPLU_INLANTUITA;
label
10,500;
type
LISTA = ^NOD;
NOD = record
cheie: integer;
data: CHAR;
urm: LISTA
end;
var
p, q, r, baza : LISTA;
n, x, i, j:integer;
data: CHAR;
c: char;
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;
33
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
write('dati nr.de noduri N = ');
readln(n);
writeln;
if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');
INSEREAZAPRIMUL;
writeln
end;
if n > 1 then
begin
for j:=2 to n do
begin
INSEREAZAREST;
writeln
end
end;
j:=j+1;
writeln('INTRODUCETI NODUL F A N I O N ');
INSEREAZAREST;
writeln;
writeln(' LISTA ESTE : ');
TRAVLISTA;
writeln;
10: write('DORITI SA CAUTATI UN NOD ? APASATI D SAU N ');
readln(c);
if (c='d') or (c='D') then
begin
CAUTA
end;
writeln;
write('DORITI SA STERGETI UN NOD ? APASATI D SAU N ');
readln(c);
writeln;
if (c='d') or ( c='D') then
begin
CAUTA;
writeln('CONTINUT NOD CU CHEIA ',X,' INAINTE DE STERGERE ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln;
STERGE;
writeln;
writeln('CONTINUTUL NODULUI DUPA STERGERE ESTE :');
writeln(p^.cheie,' ',p^.data);
writeln;
writeln('LISTA DUPA STERGEREA NODULUI CU CHEIA ',X,' ESTE :');
TRAVLISTA;
writeln
end; { sfarsit IF }
write('DORITI SA RELUATI PROGRAMUL ? APASATI D SAU N ');
readln(c);
writeln;
if ( c='d') or ( c='D') then goto 10;
500: readln
END.
34
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 16 - S se realizeze operaiile de creare i vizualizare a unei liste circulare.
Barem:
- declaraii corecte: 1 punct
- crearea listei: 4 puncte
- vizualizarea coninutului: 4 puncte
- din oficiu: 1 punct
Rezolvare:
program ATESTAT_2005_16_LISTA_CIRCULARA;
label
10,500;
type
LISTA = ^NOD;
NOD = record
cheie : integer;
data : integer;
urm : LISTA
end;
var
q, r, baza, p : LISTA;
n, x, i, j : integer;
data : integer;
c : char;
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;
if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');
INSEREAZAPRIMUL;
writeln
end;
36
Probleme rezolvate de programare Subiecte propuse la ATESTAT
if n > 1 then
begin
for j:=2 to n do
begin
INSEREAZAREST;
writeln
end
end;
q^.urm := baza;
{ j:=j+1;}
writeln ('INTRODUCETI NODUL F A N I O N ');
INSEREAZAREST;
writeln;
writeln (' LISTA ESTE : ');
TRAVLISTA;
writeln;
500: readln
END.
ATESTAT - 2005 - 17 - S se realizeze operaia de eliminare a unui element dintr-o list simplu
nlnuit, implementat dinamic, ce conine numere ntregi citite de la tastatur. S se afieze lista
nainte i dup tergerea elementului.
Barem:
- declaraii i citire: 1 punct
- crearea listei : 3 puncte
- tergerea unui element: 3 puncte
- afiarea listei: 2 punct
- din oficiu: 1 punct
Rezolvare:
program ATESTAT_2005_17_LISTA SIMPLU INLANTUITA;
label
10,500;
type
LISTA = ^NOD;
NOD = record
cheie : integer;
data : integer;
urm : LISTA
end;
var
q, r, baza, p : LISTA;
n, x, i, j : integer;
data : integer;
c : char;
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
Rezolvare:
Considerm urmtorul graf neorientat:
Graful are 5 noduri (vrfuri), 2 5
notate cu 1, 2, 3, 4, 5 i 1
4 muchii, notate cu
[2,3], [2,4], [3,4] i [4,5]. 3 4
n general, la un graf neorientat cu n vrfuri, matricea de adiacen A este o matrice
ptratic de ordinul n, simetric, cu elementele:
1, dac [i, j] este muchie n graf ; nodurile i i j sunt extremitile muchiei
A [i, j] =
0, n caz contrar
Este uor de observat c elementele de pe diagonala principal sunt nule (A [i, i] = 0), deoarece [i,
i] NU este muchie n graf..
Matricea de adiacen asociat grafului de mai sus este:
1 2 3 4 5
1 0 0 0 0 0
2 0 0 1 1 0
A (5, 5) = 3 0 1 0 1 0
4 0 1 1 0 1
5 0 0 0 1 0
n program, matricea de adiacen se va construi astfel:
I - Se face iniializarea tuturor elementelor matricii cu zero (n acest fel, anulm att elementele
diagonalei principale, ct i elementele matricii care nu se asociaz muchiilor). Vom scrie:
For i := 1 to n do
For j := 1 to n do
A [i, j] := 0;
II A Dac se cunoate numrul muchiilor. Notm cu [x, y] o muchie din graf, unde x i y sunt
extremitile muchiei (dou noduri ale grafului). n matricea de adiacen, elementul A [x, y] = 1.
Cum matricea de adiacen este i simetric, rezult cu i A [y, x] = 1. Notnd cu m numrul de
muchii din graf, vom folosi o structur FOR n care, pentru fiecare muchie i, vom introduce
extremitile x i y. Evident, aceste extremiti sunt vrfuri n graf. Vom scrie:
40
Probleme rezolvate de programare Subiecte propuse la ATESTAT
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:)
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1;
A [y, x] := 1;{matrice simetric}
End;
II B Dac NU se cunoate numrul muchiilor (este cazul problemei noastre), dar, pentru
fiecare vrf, se cunosc vrfurile adiacente cu el (se cunosc vecinii fiecrui vrf). Notm cu x,
respectiv cu y dou vrfuri din graf. Evident, att x ct i y iau valori ntre 1 i n (n = numrul total
de vrfuri din graf). Pentru fiecare nod x, trebuie s precizm numrul vecinilor si, precum i care
sunt acetia. n program vom scrie:
For x := 1 to n do
begin
write (Ci vecini are x, nrvecini = );
readln (nr);
For i := 1 to nrvecini do
begin
write (Dai urmtorul vecin, y = );
readln (y);
A [x, y] := 1;
A [y, x] := 1
end;
end;
a Gradul unui vrf v, se noteaz cu d(x) i este dat de numrul muchiilor incidente cu v. n
program vom folosi un vector notat cu d, cu 5 elemente (5 = numrul de noduri), fiecare element
reprezentnd gradul unui nod (vrf). Pentru cazul particular al grafului de mai sus, avem:
d (1) = 0 d (2) = 2 d (3) = 2 d (4) = 3 d (5) = 1
Se observ c gradul unui nod icoincide cu numrul de cifre de 1 de pe linia i din
matricea de adiacen. Prin urmare, pentru a determina gradul unui nod, numrm cifrele de 1 de pe
fiecare linie a matricii de adiacen i reinem aceste numere n elementele vectorului d.
b Determinm gradul maxim (elementul maxim din vectorul d) i afim doar numerele
nodurilor al cror grad = gradul maxim.
c Un vrf izolat are gradul zero. n matricea de adiacen, unui nod izolat i corespunde o linie,
respectiv o coloan cu toate elementele egale cu zero. Pentru a determina numrul de vrfuri izolate,
numrm liniile din matricea de adiacen care au toate elementele nule.
d Fiecare muchie [x, y] contribuie cu o unitate (1) la gradul nodului x i cu o unitate (1) la gradul
nodului y, deci cu dou uniti (2) la suma gradelor tuturor nodurilor. Cum n graf sunt m muchii,
rezult c suma gradelor tuturor nodurilor = 2m. De aici rezult m.
program ATESTAT_2005_18_GRAF_NEORIENTAT;
uses CRT;
CONST
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
matrice = array [1..nmax, 1..nmax] of integer;
41
Probleme rezolvate de programare Subiecte propuse la ATESTAT
VAR
n : integer; {n = numarul nodurilor}
i, j : integer;
x, y : integer; {noduri in graf, extremiti ale unei muchii}
A : matrice; {matricea de adiacenta}
d : vector; {vectorul care contine "gradele" fiecarui nod din graf}
nrvecini : integer; {numarul de vecini ai unui nod}
nrcifre1 : integer; {numarul de cifre egale cu 1 din matricea de adiacenta}
gradmax : integer; {gradul maxim al unui nod}
nrcifrezero : integer; {numarul cifrelor egale cu zero din matricea de
adiacenta}
nrnodurigradzero : integer; {numarul nodurilor cu gradul zero}
sumagrade : integer; {suma gradelor tuturor nodurilor}
m : integer; {numarul de muchii din graf}
for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0
end;
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;
Rezolvare:
Un graf este complet dac oricare dou noduri sunt adiacente (sunt legate ntre ele printr-o
muchie). Altfel spus, n matricea de adiacen, notat cu A, doar elementele de pe diagonala
principal sunt nule, celelalte elemente sunt egale cu 1, adic matricea are n2 n = n (n 1)
elemente egale cu 1.
43
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Altfel spus, fiecare nod are gradul n 1. Cum graful conine n noduri, rezult c suma
gradelor tuturor nodurilor este = n (n 1) = 2m.
Prin urmare, problema s-ar putea rezolva foarte simplu verificnd dac n (n 1) = 2m, avnd
n vedere c n i m sunt cunoscute (sunt date de intrare).
Presupunnd c nu dorim s verificm doar relaia de mai sus, vom face verificri asupra
matricii de adiacen A:
a - fie vom numra elementele egale cu 1 din matrice i vom verifica dac numrul total de elemente
egale cu 1 este egal cu n (n 1),
b - fie vom verifica dac, n matricea de adiacen, numai elementele diagonalei principale sunt nule.
Notm cu [x, y] o muchie din graf, unde x i y sunt extremitile muchiei (dou noduri ale
grafului). n matricea de adiacen, elementul A [x, y] = 1. Cum matricea de adiacen este i
simetric, rezult cu i A [y, x] = 1. Deoarece se cunoate numrul muchiilor (m), vom folosi o
structur FOR n care, pentru fiecare muchie i, vom introduce extremitile x i y. Evident,
aceste extremiti sunt vrfuri n graf. Vom scrie:
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:)
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1;
A [y, x] := 1;{matrice simetric}
End;
program ATESTAT_2005_19_GRAF_NEORIENTAT;
uses CRT;
CONST
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
matrice = array [1..nmax, 1..nmax] of integer;
VAR
n : integer; {n = numarul nodurilor}
m : integer; {numarul de muchii din graf}
x, y : integer; {noduri in graf, extremiti ale unei muchii}
A : matrice; {matricea de adiacenta}
nrcifre1 : integer; {numarul de cifre egale cu 1 din matricea de adiacenta}
nrcifrezero : integer; {numarul cifrelor egale cu zero din matricea de
adiacenta}
i, j : integer;
for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0
end;
end;
writeln;
44
Probleme rezolvate de programare Subiecte propuse la ATESTAT
{Completare matrice de adiacenta}
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:)
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1;
A [y, x] := 1; {matricea este simetric}
End;
writeln;
-------------------------------------------------------------------------------
{Varianta a - Numrarea cifrelor de 1 din matricea de adiacen}
nrcifre1 := 0;
if nrcifre1 = n (n 1) then
writeln (Graful este complet)
else
writeln (Graful este incomplet);
-------------------------------------------------------------------------------
{Varianta b - Numrarea cifrelor de zero din matricea de adiacen}
nrcifrezero := 0;
for i:= 1 to n do {i = index linie in matricea de adiacenta}
begin
for j := 1 to n do {j = index coloana in matricea de adiacenta}
begin
if A [i, j] = 0 then
nrcifrezero := nrcifrezero + 1;
end;
end;
writeln;
if nrcifrezero = n then
writeln (Graful este complet)
else
writeln (Graful este incomplet);
-------------------------------------------------------------------------------
readln
end.
ATESTAT - 2005 - 20 - Fie G un graf neorientat dat prin numrul de vrfuri i numrul de muchii
(n, respectiv m, numere naturale introduse de la tastatur). S se scrie un program care s verifice
dac graful conine un ciclu de lungime 4.
Barem:
- declaraii corecte de variabile: 1 punct
- reprezentarea corect a grafului prin matricea de adiacen: 3 puncte
- realizarea algoritmului de prelucrare: 3 puncte
- afiarea rezultatului : 2 puncte
- din oficiu: 1 punct
45
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare:
Un ciclu elementar are proprietatea c oricare dou vrfuri ale sale, cu excepia primului i
ultimului, sunt diferite dou cte dou. Lungimea unui ciclu = numrul de muchii ce apar n ciclu.
Considernd graful din figura de mai jos, se poate observa uor ciclul 1 2 3 4 1 care
are lungimea 4. Matricea de adiacen a grafului este urmtoarea:
k
2 Nod 1 2 3 4 5
i=1 0 1 0 1 0
1 2 1 0 1 0 1
3 j=3 0 1 0 1 0
4 1 0 1 0 0
5 4
5 0 1 0 0 0
Trebuie doar s se verifice dac exist cicluri de lungime 4 (NU se cere generarea acestora).
Pentru ciclul de lungime 4 identificat n graf (1 2 3 4 1), n matricea de adiacen,
liniile corespunztoare nodurilor 1 i 3 conin amndou cifra 1 pe poziiile k = 2 i k = 4.
De asemenea, liniile corespunztoare nodurilor 2 i 4 conin amndou cifra 1 pe poziiile
k = 1 i k = 3.
Va trebui s verificm dac, pentru fiecare pereche de noduri distincte, liniile (din matricea
de adiacen) corespunztoare acestor noduri conin cifra 1 pe cel puin 2 poziii (coloane) identice.
Notm cu i, respectiv j dou linii distincte din matricea de adiacen, linii
corespunztoare a dou noduri i i j. Evident, i = 1 .. n-1, iar j = i + 1 .. n.
Notm cu k indexul de coloan (din matricea de adiacen) pentru care se face testarea
perechii A [i, k] i A [j, k]. Iniializm un contor nrcifre care numr cifrele de 1, n condiia
( A [i, k] = 1 ) AND ( A [j, k] = 1 ).
program ATESTAT_2005_20_GRAF_CU_UN_CICLU_DE_LUNGIME_PATRU ;
uses CRT;
LABEL
sfarsit;
CONST
nmax = 100;
TYPE
matrice = array [1..nmax, 1..nmax] of integer;
VAR
n : integer; {n = numarul nodurilor}
m : integer; {numarul de muchii din graf}
x, y : integer; {noduri in graf, extremiti ale unei muchii}
A : matrice; {matricea de adiacenta}
i, j, k : integer;
nrcifre : integer; {numara cifrele de 1, in conditiile problemei}
GASIT : boolean; {GASIT = TRUE daca s-a gasit un ciclu de lungime 4}
Begin { PROGRAM PRINCIPAL }
CLRSCR;
write ('Dati numarul de noduri, n = ');
readln (n);
write ('Dati numarul de muchii, m = ');
readln (m);
{Initializarea tuturor elementelor matricii de adiacenta cu zero}
for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0
end;
end;
writeln;
46
Probleme rezolvate de programare Subiecte propuse la ATESTAT
{Completare matrice de adiacenta}
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:)
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1;
A [y, x] := 1; {matricea este simetric}
End;
writeln;
-------------------------------------------------------------------------------
GASIT := FALSE; {presupunem ca nu exista un ciclu de lungime 4}
for i := 1 to n 1 do {i = index elemente de pe una din liniile testate}
begin
for j := i + 1 to n do {j = index elemente de pe alta linie testata}
begin
nrcifre := 0; {initializare contor pt. fiecare pereche testata}
for k := 1 to n do {k = index de coloana}
begin
if ( A [i, k] = 1 ) AND ( A [j, k] = 1 ) then
nrcifre := nrcifre + 1;
if nrcifre >= 2 then
begin
GASIT := TRUE;
GOTO sfarsit
end;
end;
end;
end;
sfarsit: if GASIT = TRUE then
writeln (Graful contine cicluri de lungime 4)
else
writeln (Graful NU contine cicluri de lungime 4);
readln
END.
Rezolvare:
a1 Reamintim cteva noiuni din teoria grafurilor orientate.
Un lan ( L ) ntr-un graf orientat = un ir de arce L = [a1 , a2 ,
1 2 ak , , ap], cu proprietatea c oricare arc ak are un nod comun cu
a4
a5 a2 ak-1 i cellalt nod comun cu ak+1 , pentru orice k din mulimea {
2, p-1}. NU ARE IMPORTAN ORIENTAREA ARCELOR.
a3 Exemplu: Pentru graful din figura alturat, lanuri cu extremitile
4 3 n nodurile 1 i 4 sunt:
L1 = (a1, a2, a3), L2 = (a1, a4, a5, a3), L3 = (a5, a3) se observ c
nu are importan orientarea arcelor.
47
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Un lan ntr-un graf orientat se numete drum (notat D) dac toate arcele sale au ACEEAI
ORIENTARE, dat de sensul deplasrii de la x0 (extremitatea iniial a lui a1) la xp (extremitatea
final a lui ap). Vrfurile x0 i xp = extremitile lanului. De observat c, n cazul drumului,
ARE IMPORTAN ORIENTAREA ARCELOR
Altfel spus, un drum ntr-un graf orientat este un ir de vrfuri. Un drum se poate scrie fie
ca o succesiune de arce, fie ca o succesiune de vrfuri. Pentru graful alturat, avem drumurile:
D1 = (1, 2, 3), D2 = (1, 2, 1, 3).
Matricea drumurilor unui graf G este o matrice B definit astfel:
1, dac exist drum n G
B [i, j] = de la nodul xi la nodul xj
0, n caz contrar.
Pentru graful anterior, avem:
Matricea de ADIACEN: Matricea DRUMURILOR:
Nod 1 2 3 4 Nod 1 2 3 4
1 0 1 1 0 1 1 1 1 0
A = 2 1 0 1 0 B = 2 1 1 1 0
3 0 0 0 0 3 0 0 0 0
4 0 0 1 0 4 0 0 1 0
Algoritmul Roy-Warshall determin matricea drumurilor plecnd de la matricea de
adiacen astfel:
Un element A [i, j] = 0 din matricea de adiacen devine 1 n matricea drumurilor dac
exist un vrf k astfel nct
A [i, k] = 1 i A [k, j] = 1,
adic atunci cnd exist drum de la xi la xk i drum de la xk la xj. Aceast condiie se poate exprima
i astfel:
A [i, j] = MIN ( A[i, k], A [k, j] )
sau
A [i, j] = A[i, k] * A [k, j].
Transformarea propriu-zis pe care o presupune algoritmul Roy-Warshall poate fi
exprimat astfel:
for k := 1 to n do
begin
for i := 1 to n do
begin
if i <> k then
begin
for j := 1 to n do
begin
if j <> k then
begin
IF A [i, j] = 0 then
A [i, j] := A [i, k] * A [k, j]
end
end
end
end
end;
48
Probleme rezolvate de programare Subiecte propuse la ATESTAT
program ATESTAT_2005_21_MATRICEA_DRUMURILOR_ALGORITMUL_ROY_WARSHALL;
uses CRT;
CONST
nmax = 100;
TYPE
matrice = array [1..nmax, 1..nmax] of integer;
VAR
n, m : integer; {n = numarul nodurilor; m = numarul de muchii din graf }
x, y : integer; {extremitati ale unei muchii}
A : matrice; {matricea de adiacenta}
B : matrice; {matricea drumurilor}
i, j, k : integer;
function MIN ( alfa, beta : integer) : integer;
begin
if alfa <= beta then
MIN := alfa
else
MIN := beta
end;
Begin { PROGRAM PRINCIPAL }
CLRSCR;
write ('Dati numarul de noduri, n = ');
readln (n);
write ('Dati numarul de muchii, m = ');
readln (m);
{Initializarea tuturor elementelor matricii de adiacenta cu zero}
for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0
end;
end;
writeln;
{Completare matrice de adiacenta}
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:);
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1; {matricea NU este simetric}
End;
writeln;
writeln ('Matricea de ADIACENTA este:');
for i := 1 to n do
begin
writeln;
for j := 1 to n do
begin
write ( A [i, j] : 3 ); {se lasa 3 pozitii pentru fiecare }
{element al matricii }
end;
end;
writeln;
{ Deoarece se pleaca de la matricea de ADIACENTA A, si pentru a nu afecta }
{aceasta matrice, Initializam matrice DRUMURI B, cu matricea de ADIACENTA - A}
for i := 1 to n do
begin
for j := 1 to n do
begin
B [i, j] := A [i, j];
end;
end;
49
Probleme rezolvate de programare Subiecte propuse la ATESTAT
{Transformarea propriu-zisa - Algoritmul Roy-Warshall}
{VARIANTA 1}
for k := 1 to n do
begin
for i := 1 to n do
begin
if i <> k then
begin
for j := 1 to n do
begin
if j <> k then
begin
IF B [i, j] = 0 then
B [i, j] := MIN (B [i, k], B [k, j])
end
end
end
end
end;
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;
50
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 22 - Pentru un graf orientat G cu n vrfuri i m arce (n i m sunt numere
naturale citite la intrare), s se scrie un program care s construiasc i s afieze listele de adiacen
ale succesorilor vrfurilor grafului sub form de liste liniare simplu nlnuite.
Barem:
- declaraii corecte de variabile: 2 puncte
- generarea listelor de adiacen: 4 puncte
- afiarea listelor: 3 puncte
- din oficiu: 1 punct
Rezolvare:
Pentru reprezentarea grafurilor orientate se pot folosi
a matricea de adiacen
b listele de adiacen.
La reprezentarea prin liste de adiacen, pentru orice vrf x se construiete o list L ( x ) a
succesorilor vrfului x. Liste de adiacen pot fi reprezentate folosind tablouri sau structuri
dinamice de date.
Exemplu: pentru graful alturat, listele de adiacen L vor fi:
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 }
NEW (P);
P^.NodSuccesor := y ;
P^.URM := L [x];
L [x] := P;
End;
writeln;
52
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 23 - Dat un graf orientat G cu n vrfuri i m arce, s se scrie un program prin
care:
a) s se calculeze gradul interior, respectiv exterior al fiecrui vrf
b) s se verifice dac graful are vrfuri izolate
Datele de intrare se preiau din fiierul text INPUT.TXT sub forma urmtoare :
pe prima linie: n - reprezentnd numrul de vrfuri ale grafului ;
pe linia a doua : m - reprezentnd numrul de arce ale grafului ;
pe urmtoarele m linii, cte o pereche de numere, separate printr-un spaiu, ce reprezint
extremitatea iniial, respectiv final a arcului.
Rezultatele se vor afia pe ecran.
Barem:
- declaraii corecte de variabile: 1 punct
- citirea corect a datelor din fiier: 1 punct
- reprezentarea corect a grafului prin matricea de adiacen: 2 puncte
- realizarea punctului a): 2 puncte
- realizarea punctului b): 2 puncte
- afiarea rezultatelor: 1 punct
- din oficiu: 1 punct
Rezolvare:
Vom reprezenta graful prin listele de adiacen (vezi problema anterioar ATESTAT_2005_22).
Folosim 2 vectori GradExt, respectiv GradInt, fiecare cu cte n componente, n care vom memora
gradul exterior i interior al fiecrui vrf. Dac pentru un vrf suma celor dou grade este zero,
acel vrf este izolat.
1 4 5
Exemplu: pentru graful alturat, fiierul
GRAF.TXT, de pe discul C:, va avea
coninutul:
6 {numrul de noduri} 2 3 6
8 {numrul de arce}
1 2 NOD GradExt GradInt Suma grade
1 3 1 2 1 3
2 3 2 2 1 3
2 4 3 2 2 4
3 4 4 2 2 4
3 5 5 0 2 2
4 1 6 0 0 0
4 5
De asemenea, se observ c vrful 6 este izolat.
program ATESTAT_2005_23_GRADE_INT_SI_EXT_CU_LISTE_DE_ADIACENTA ;
uses CRT;
CONST
nmax = 100;
TYPE
LISTA = ^ELEMENT;
ELEMENT = RECORD
NodSuccesor : integer;
URM : LISTA {pointer de legatura spre urmatorul nod din lista}
END;
VAR
L : array [1..nmax] of LISTA;
m, n, i : integer; { n = nr. de NODURI; m = nr. de ARCE }
P : LISTA ; { P = pointer de lucru}
x, y : integer; { x, y = extremitatile unui arc }
GradInt, GradExt : array [1..nmax] of integer ;
S : integer ; { S = suma gradele interior si exterior pt. un varf }
53
Probleme rezolvate de programare Subiecte propuse la ATESTAT
f : TEXT; {fisier in care memoram informatiile despre GRAF }
linie : STRING ; { "linie" = o linie din fisierul text GRAF.TXT }
ER : integer; { variabila eroare din apelul procedurii VAL }
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;
55
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare:
1 4 5
Considerm graful din figura alturat.
Notm cu GradExt, respectiv GradInt, gradul
exterior i interior al fiecrui vrf.
Dac pentru un vrf suma celor dou grade 2 3 6
este zero, acel vrf este izolat.
De asemenea, un vrf este izolat dac i NOD GradExt GradInt Suma grade
numai dac linia i i coloana i din 1 2 1 3
matricea de ADIACEN au toate 2 2 1 3
elementele NULE. 3 2 2 4
Un drum ntr-un graf orientat este un ir de 4 2 2 4
vrfuri. Un drum se poate scrie fie ca o 5 0 2 2
succesiune de arce, fie ca o succesiune de 6 0 0 0
vrfuri.
Dac toate arcele unui drum sunt distincte, iar primul i ultimul nod coincid, drumul se numete
circuit.
Dac toate vrfurile unui circuit, cu excepia primului i ultimului, sunt distincte, circuitul este
elementar.
Pentru graful alturat, avem circuitele:
C1 = (1, 2, 3, 4, 1, 3, 4, 1), C2 = (1, 3, 4, 1, 2, 3, 4, 1)
precum i circuitele elementare:
C3 = (1, 2, 4, 1), C4 = (1, 3, 4, 1), C5 = (1, 2, 3, 4, 1)
Pentru graful de mai sus, avem:
Matricea de ADIACEN: Matricea DRUMURILOR:
Nod 1 2 3 4 5 6 Nod 1 2 3 4 5 6
1 0 1 1 0 0 0 1 1 1 1 1 1 0
A = 2 0 0 1 1 0 0 B = 2 1 1 1 1 1 0
3 0 0 0 1 1 0 3 1 1 1 1 1 0
4 1 0 0 0 1 0 4 1 1 1 1 1 0
5 0 0 0 0 0 0 5 0 0 0 0 0 0
6 0 0 0 0 0 0 6 0 0 0 0 0 0
Pentru a verifica dac graful conine noduri izolate, declarm doi vectori zeropelin si zeropecol in
care memorm numarul de zero-uri de pe fiecare linie, respectiv fiecare coloan. Apoi, pentru fiecare
linie din matricea de ADIACEN, verificam dac este ndeplinit condiia
( zeropelin [ i ] = n) AND (zeropecol [ i ] = n)
adic, simultan pe linia i i coloana i avem numai zero-uri (n zero-uri).
Se observ c, n matricea de ADIACEN linia 6 i coloana 6 au toate elementele nule. Rezult
c nodul 6 este nod izolat.
Pentru a verifica dac graful are circuite, se verific dac matricea drumurilor conine elemente
egale cu 1 pe diagonala principal. Din faptul c matricea drumurilor are numai elemente de 1 pe
diagonala principal deducem doar c fiecare vrf aparine unui circuit; NU rezult c exist un
circuit care trece prin toate nodurile grafului.
program ATESTAT_2005_24_CIRCUITE_MATRICEA_DRUMURILOR_ALGORITMUL_ROY_WARSHALL;
uses CRT;
CONST
nmax = 100;
TYPE
matrice = array [1..nmax, 1..nmax] of integer;
56
Probleme rezolvate de programare Subiecte propuse la ATESTAT
VAR
n : integer; {n = numarul nodurilor}
m : integer; {numarul de muchii din graf}
x, y : integer; { extremitati ale unei muchii}
A : matrice; {matricea de adiacenta}
B : matrice; {matricea drumurilor}
i, j, k : integer;
zeropelin : array [1..nmax] of integer;
{vector in care memoram numarul zero-urile gasite pe o linie }
zeropecol : array [1..nmax] of integer;
{vector in care memoram numarul zero-urile gasite pe o coloana }
GASIT : boolean ; {testeaza daca exista circuite in graf }
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;
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;
Rezolvare: Algoritmul recursiv pentru calcularea produsului din enun este asemntor cu cel pentru
calcularea lui xn n variant recursiv.
program ATESTAT_2005_25_PRODUS_RECURSIV;
var
i, n, p : integer;
function PRODUS (m : integer) : integer;
begin
if m = 0 then
PRODUS := 1
else
PRODUS := (2*m + 1) * PRODUS (m - 1)
end;
59
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
write ('Dati n = ');
readln (n);
p := PRODUS (n);
ATESTAT - 2005 - 26 - S se scrie un program prin care se citete de la tastatur numrul natural n.
Programul trebuie s apeleze o funcie recursiv, care s ntoarc valoarea sumei S (n), unde
S (n) = 2 + 5 + 8 + ... + (2 + 3*n).
Valoarea pentru numrul n este citit n programul principal. Valoarea calculat de funcie va fi
afiat pe ecran tot n programul principal.
Exemplu: pentru n = 3, se va afia valoarea 26 ( S (3) = 2 + 5 + 8 + 11 ).
Barem:
- corectitudinea definiiei recursive: 3 puncte
- declaraie corect de funcie: 2 puncte
- condiia de ieire din funcie: 2 puncte
- corectitudine sintactic: 1 punct
- din oficiu: 1 punct
Rezolvare: Algoritmul recursiv pentru calcularea sumei din enun este asemntor cu cel pentru
calcularea, n variant recursiv, a sumei S = 1 + 2 + 3 + + n.
program ATESTAT_2005_26_SUMA_RECURSIVA;
var
i, n, s : integer;
s := SUMA (n);
60
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 27 - Se d un numr natural n introdus de la tastatur. Scriei un program care
calculeaz suma cifrelor acestui numr. Programul trebuie s apeleze o funcie recursiv care s
ntoarc valoarea sumei.
Barem:
- corectitudinea definiiei recursive: 3 puncte
- declaraie corect de funcie: 2 puncte
- condiia de ieire din funcie: 2 puncte
- corectitudine sintactic: 1 punct
- din oficiu: 1 punct
Rezolvare: Pentru numrul x, trebuie s determinm, mai nti, numrul de cifre i apoi vom
calcula suma cifrelor. Vom defini dou funcii NRCIFRE i SUMACIFRE, n acest scop
program ATESTAT_2005_27_SUMA_CIFRE_NUMAR_X;
{Folosind o functie recursiva, sa se calculeze suma cifrelor unui nr. natural x}
const
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
var
s, x, x1, n, i : integer;
y : vector;
k : BOOLEAN;
function NRCIFRE (y : integer) : integer;
var
m : integer;
begin
if y = 0 then
m := 1
else
begin
m := 0;
while y <> 0 do
begin
y := y DIV 10;
m := m + 1
end
end;
NRCIFRE := m
end;
function SUMACIFRE ( nr : integer) : integer;
var
s1, i : integer;
begin
s1 := 0;
for i := 1 to NRCIFRE (nr) do
begin
S1 := s1 + y [i] ;
end;
SUMACIFRE := s1
end;
n := NRCIFRE (x);
writeln ('Numarul ',x,' are ',n,' cifre');
writeln;
61
Probleme rezolvate de programare Subiecte propuse la ATESTAT
x1 := x; {conservam valoarea numarului initial x, folosind auxiliarul x1}
for i := 1 to n do
begin
y [ i ] := x1 MOD 10;
writeln ('y [',i,'] = ', y [i]);
x1 := x1 DIV 10;
end;
s := SUMACIFRE (x);
writeln ('Suma cifrelor numarului ', x, ' = ', s);
readln
END.
ATESTAT - 2005 - 28 - Se d un numr natural n n baza 10 i un numr natural b (2 <= b <= 9).
S se scrie un program care s converteasc numrul n n baza b, utiliznd n acest scop un
subprogram recursiv.
Barem:
- apel corect de subprogram: 2 puncte
- declaraie corect de subprogram: 3 puncte
- algoritm pentru conversia n baza b (algoritm corect): 3 puncte
- corectitudine sintactic: 1 punct
- din oficiu: 1 punct
Rezolvare: Folosim un vector R n care se rein resturile mpririi numrului zecimal nr10 la b
(de exemplu, b = 2).
program ATESTAT_2005_28_TRANSFORMARE_BAZA_10_IN_BAZA_2_VARIANTA_ITERATIVA_1;
uses CRT;
type
vector = array [1..100] of integer;
VAR
ZECIMAL, BINAR, nr10 : integer; {numarul zecimal}
nr2inversat, nr2 : integer; {numar binar inversat respectiv nr binar final}
R : vector;
n, i, j, k, rest : integer;
Begin { PROGRAM PRINCIPAL }
clrscr;
write ('Dati numarul zecimal = ');
readln (nr10);
if nr10 = 0 then
begin
ZECIMAL := 0;
i:=1;
R[i] := 0
end
else
begin
i := 0;
ZECIMAL := nr10;
while nr10 <> 1 do
begin
rest := nr10 MOD 2;
i := i + 1;
R [i] := rest;
nr10 := nr10 DIV 2;
end;
i := i + 1;
r [i] := nr10;
end;
n := i;
62
Probleme rezolvate de programare Subiecte propuse la ATESTAT
writeln;
write ('Numarul binar echivalent lui ', ZECIMAL,' este ');
for i := n downto 1 do
begin
write ( R[i] );
end;
readln
END.
program ATESTAT_2005_28_TRANSFORMARE_BAZA_10_IN_BAZA_B_VARIANTA_ITERATIVA_2;
uses CRT;
type
vector = array [1..100] of integer;
VAR
ZECIMAL, BINAR, nr10 : integer; {numarul zecimal}
nr2inversat, nr2 : integer; {numar binar inversat respectiv nr binar final}
R : vector;
baza, n, i, j, k, rest : integer;
Begin { PROGRAM PRINCIPAL }
clrscr;
write ('Dati numarul zecimal nr10 = ');
readln (nr10);
write ('Dati noua baza = ');
readln (baza);
i := 0;
ZECIMAL := nr10;
while nr10 <> 0 do
begin
rest := nr10 MOD baza;
i := i + 1;
R [i] := rest;
nr10 := nr10 DIV baza;
end;
n := i;
program ATESTAT_2005_28_TRANSFORMARE_BAZA_10_IN_BAZA_2_VARIANTA_RECURSIVA;
var
n: integer;
b: byte;
63
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
write ('Dati n = ');
readln (n);
write ('Dati noua baza de numeratie, b = ');
readln (b);
writeln ('Reprezentarea numarului ',n,' in baza ',b,' este:');
conversie (n,b);
readln;
end.
ATESTAT - 2005 - 29 - Se citesc n cuvinte terminate fiecare cu cte un spaiu. Cuvintele se citesc
de la tastatur din n linii. S se scrie un program care s afieze fiecare cuvnt aa cum s-a citit i
apoi cu literele inversate. S se rezolve problema recursiv.
Barem:
- apel corect de subprogram: 2 puncte
- declaraie corect de subprogram: 3 puncte
- algoritm corect de inversare recursiv: 3 puncte
- corectitudine sintactic: 1 punct
din oficiu: 1 punct
64
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 30 - Se d un ir de caractere citit de la tastatur, ir ce se termin cu caracterul
punct. Scriei un program care afieaz irul citit n ordine invers. S se rezolve problema
recursiv.
Barem:
- apel corect de subprogram: 2 puncte
- declaraie corect de subprogram: 3 puncte
- algoritm corect de inversare recursiv: 3 puncte
- corectitudine sintactic: 1 punct
- din oficiu: 1 punct
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)
65
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Barem:
- declaraii i citire corect: 1 punct
- algoritmul de descompunere n factori primi: 3 puncte
- crearea fiierului FACTORI.TXT: 2 puncte
- listarea coninutului fiierului: 3 puncte
- din oficiu: 1 punct
Rezolvare:
n ipoteza c fiierul text nu exist deja pe disc, vom crea acest fiier cu acelai program care face
i celelalte determinri cerute de enun.
Dup citirea de la tastatur a numrului x, l vom converti ntr-un ir de caractere, notat sirx,
prin apelarea procedurii STR. Introducem n fiierul text irul sirx asociat numrului x.
n fiierul text se vor introduce att factorii primi n care se descompune x, ct i puterile lor,
astfel:
Transformm factorii n sir1, iar puterile n sir2
Dup fiecare astfel de numr transformat n ir, fie vom lsa cte un singur spaiu liber
(blank), fie vom aduga un comentariu (un ir de caractere). n acest fel, se va crea, prin
CONCATENARE, cte o linie n fiierul text. Evident, linie este tot un ir de caractere.
Celelalte etape sunt comentate direct n program.
program ATESTAT_2005_31_FACTORI_PRIMI_SI_PUTERILE_LOR;
{ Fie x un numar natural. Afisati factorii primi ai lui x si puterile lor }
CONST
nmax = 1000;
TYPE
vector = array [1..nmax] of integer;
VAR
f : TEXT;
linie : string;
sirx, sir1, sir2 : string;
putere : vector; {retinem in vectorul "putere" puterea unui factor prim}
divizor : vector; {"divizor" = vector in care se retin factorii primi}
x, d : integer;
divmax : integer; {divizorul sau factorul prim maxim}
{d = un divizor oarecare, curent}
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;
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');
RESET (f);
while NOT EOF (f) do
begin
readln (f, linie);
writeln (linie)
end;
readln
end.
67
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare: Folosim funcia STR pentru conversia unui numr ntr-un ir, la introducerea
elementelor matricii n fiier.
program ATESTAT_2005_32_ELEMENT_MAX_IN_MATRICE;
uses CRT;
LABEL
100;
CONST
nmax = 100;
TYPE
matrice = array [1..nmax, 1..nmax] of integer;
VAR
m, n, i, j, MAX : integer;
f : TEXT;
A : matrice;
sir, sir1, sir2, linie : STRING;
begin
CLRSCR;
ASSIGN (f, 'C:\MATRICE.txt');
rewrite (f); {generam fisierul text}
{ ---------------------------------------------------------------------- }
{ scriem pe prima linie din fisierul TEXT cele doua valori "m" si "n" }
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" }
{ 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;
end;
writeln ;
writeln ('Continutul fisierului TEXT este :');
writeln;
RESET (f);
RESET (f);
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);
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.
Rezolvare: Pentru ordonare, vom defini dou proceduri: BUBBLE care apeleaz la algoritmul
bubble sort, i ORDONEAZ, bazat pe sortarea prin selecie.
program ATESTAT_2005_33_ORDONARI;
uses CRT;
const
nmax = 30;
type
vector = array [1..nmax] of integer;
matrice = array [1..nmax, 1..nmax] of integer;
var
f : file of integer;
A : matrice;
linia : vector;
n, j, i, m : integer;
t, suma, index : integer;
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;
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;
end;
end;
1 : begin
for i := 1 to m do
begin
for j := 1 to n do
begin
linia [j] := a[i, j];
end;
end;
end;
writeln;
readln
END.
72
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2005 - 34 - Scriei un program care s realizeze REUNIUNEA a dou mulimi A i B
introduse prin doi vectori ce au m, respectiv n elemente numere ntregi, distincte. Datele de intrare
se vor citi de la tastatur. Rezultatele se vor afia pe ecran.
Barem:
- declaraii de variabile: 1 punct
- citire corect a datelor: 2 puncte
- algoritm de prelucrare corect descris: 5 puncte
- afiarea reuniunii: 1 punct
- din oficiu: 1 punct
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.
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.
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;
75
Probleme rezolvate de programare Subiecte propuse la ATESTAT
writeln ('Dati elementele multimii A');
for i := 1 to m do
begin
write ('A [ ', i,' ] = ');
readln ( A [i] );
end;
writeln;
writeln ('Dati elementele multimii B');
for i := 1 to n do
begin
write ('B [ ', i,' ] = ');
readln ( B [i] );
end;
Ma := [];
for i := 1 to m do
begin
Ma := Ma + [ A[i] ]; {construiesc Ma prin reuniune }
end;
Mb := [];
for i := 1 to n do
begin
Mb := Mb + [ B[i] ]; {construiesc Ma prin reuniune }
end;
DIFER := Ma - Mb;
writeln;
writeln ('Elementele multimii DIFER sunt :');
for elem := 0 to 255 do
begin
if elem IN DIFER then
write (elem,' , ');
end;
readln
END.
ATESTAT - 2005 - 37 - Scriei un program care s afieze elementele care sunt numere prime,
dintr-o matrice ptratic cu n x n elemente ntregi pozitive. Dac n matrice nu sunt astfel de
elemente s se menioneze acest lucru printr-un mesaj adecvat afiat pe ecran.
Barem:
- declaraii de variabile: 1 punct
- citire corect a datelor: 2 puncte
- algoritm de determinare numr prim: 5 puncte
- afiare numere prime, respectiv mesaj: 1 punct
- din oficiu: 1 punct
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.
77
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Rezolvare: Ordonm vectorii prin metoda bubble sort, dup care interclasm vectorii.
program ATESTAT_2005_38_INTERCLASARE;
uses CRT;
const
Nmax = 30;
type
vector = array [1 .. Nmax] of integer;
var
A, B : vector;
C : array [1 .. 2 * Nmax] of REAL;
i, j, m, n, k : integer;
procedure ORDONEAZA (VAR v : vector; q:integer);
var
k1, t: integer;
aux : integer;
begin
repeat
k1:= 0;
t := 1;
repeat
if v [t] > v [t+1] then
begin
aux := v [t];
v [t] := v [t+1];
v [t+1] := aux;
k1 := 1
end;
t := t + 1
until (t > q-1)
until ( k1 = 0);
end;
Begin { PROGRAM PRINCIPAL }
clrscr;
REPEAT
write ('Dati nr. de elemente pentru vectorul A, m = ');
readln (m);
UNTIL (m >=1) AND (m <= Nmax);
writeln;
REPEAT
write ('Dati nr. de elemente pentru vectorul B, n = ');
readln (n);
UNTIL (n >=1) AND (n <= Nmax);
writeln;
writeln ('Dati elementele vectorului A');
for i := 1 to m do
begin
write ('A [i] = ');
readln (A [i] )
end;
writeln;
ORDONEAZA (A, m);
78
Probleme rezolvate de programare Subiecte propuse la ATESTAT
{ Algoritmul de INTERCLASARE }
k := 0;
i := 1;
j := 1;
writeln;
79