Sunteți pe pagina 1din 85

Probleme rezolvate de programare Subiecte propuse la ATESTAT

ATESTAT - 2003 - 1 - Se citesc numere naturale pn la introducerea a dou numere consecutive egale.
Afiai toate perechile de numere citite consecutiv, care sunt prime ntre ele.
Rezolvare:
Dou numere naturale A i B, diferite de 0, sunt prime ntre ele dac l au pe 1 ca singur divizor
comun. Altfel spus, CMMDC al celor dou numere este egal cu 1. Nu este obligatoriu ca A i B s
fie ele nsele prime. Exemplu: 15 i 16 NU sunt numere prime, dar sunt
prime ntre
ele, pentru c CMMDC (15, 16) = 1.
Conform enunului, dac se citesc numere, nu se tie de la nceput cte (nu se d un n =
numrul de numere ce se vor citi), deci va trebui s le numrm cu un contor i.
Numerele pe care le vom introduce vor fi preluate ntr-un vector X.
Definim o funcie CMMDC pentru a calcula CMMDC al dou numere consecutive (cele dou
numere vor fi dou elemente consecutive din vectorul X).
Program ATESTAT_2003_1_NUMERE_PRIME_INTRE_ELE ;
CONST
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
VAR
x : vector;
n, i : integer;
function CMMDC (A, B : integer) : integer;
var
aux, R : integer;
begin
if A < B then
begin
aux := A;
A := B;
B := aux
end;
R := A MOD B;
while R <> 0 do
begin
A := B;
B := R;
R := A MOD B
end;
CMMDC := B
end; { sfarsit functie CMMDC }
Begin

{ PROGRAM PRINCIPAL }
i := 1;
{contor care numara numerele introduse}
write ('Dati x [ ', i,' ] = ');
{introducem primul numar}
readln (x [i]);
REPEAT
{introducem urmatoarele numere}
i := i + 1;
write ('Dati x [ ', i,' ] = ');
readln (x [i]);
UNTIL ( x [i] = x [i-1] );
{pana ce apar doua numere consecutive egale}
n := i;
{n = total numere introduse = i}
for i := 1 to n - 1 do
begin
if CMMDC ( x [i], x [i+1] ) = 1 then
writeln ( x [i],' si ', x [i+1],' sunt prime intre ele');

Probleme rezolvate de programare Subiecte propuse la ATESTAT


end;
readln
end.

Probleme rezolvate de programare Subiecte propuse la ATESTAT

ATESTAT - 2003 - 2 - Se citesc numere naturale pn la introducerea unui numr prim cu 12. Afiai
toate numerele care sunt prime cu suma cifrelor lor.
Rezolvare:

Dou numere sunt prime ntre ele dac CMMDC al celor dou numere este 1 (vezi problema anterioar).
Introducem primul numr, notat cu x. Verificm dac x este prim cu 12 i dac DA, oprim algoritmul;
dac nu, verificm dac este prim cu suma cifrelor sale.
Pentru c vom introduce mai multe numere, dar nu tim de la nceput cte anume, introducerea urmtoarelor
numere se va face ntr-un ciclu WHILE.
Definim o funcie CMMDC pentru a calcula CMMDC al dou numere.
Definim o funcie NUMARACIFRE, pentru a numra cifrele unui numr natural.
Definim o procedur DETCIFRE, care determin cifrele unui numr i le depune ntr-un vector.
Definim o funcie SUMACIFRE, care nsumeaz cifrele unui numr.

Program ATESTAT_2003_2_NUMERE_PRIME_CU_SUMA_CIFRELOR_LOR ;
CONST
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
VAR
y : vector;
S, x, n, i : integer;
function CMMDC (A, B : integer) : integer;
var
aux, R : integer;
begin
if A < B then
begin
aux := A;
A := B;
B := aux
end;
R := A MOD B;
while R <> 0 do
begin
A := B;
B := R;
R := A MOD B
end;
CMMDC := B
end; { sfarsit functie CMMDC }
function NUMARACIFRE ( z : integer) : integer;
var
nrcif : integer;
begin
if z = 0 then
nrcif := 1
else
begin
nrcif := 0;
while z > 0 do
begin
z := z DIV 10;
nrcif := nrcif + 1
end;
end;

Probleme rezolvate de programare Subiecte propuse la ATESTAT


NUMARACIFRE := nrcif;
end; { sfarsit functie NUMARACIFRE }

Probleme rezolvate de programare Subiecte propuse la ATESTAT

procedure DETCIFRE ( z : integer; VAR y : vector );


{ determina cifrele lui z si le depune in vectorul y }
begin
n := NUMARACIFRE ( z );
i := n;
while i >= 1 do
begin
y [ i ] := z MOD 10;
z := z DIV 10;
i := i - 1
end;
end; { sfarsit proc. DETCIFRE }
function SUMACIFRE ( z : integer) : integer;
var
s : integer;
begin
DETCIFRE ( z, y );
S := 0;
for i := 1 to n do
begin
S := S + y [i]
end;
SUMACIFRE := S;
end; { sfarsit functie SUMACIFRE }
Begin

{ PROGRAM

PRINCIPAL }

write ('Dati x = ');


readln ( x );

{Introducerea primului numr}

while CMMDC ( x, 12 ) <> 1 do {testm dac x este prim cu 12}


begin
S := SUMACIFRE (x);
if CMMDC (x, S) = 1 then
writeln ('x = ', x,' este prim cu suma cifrelor sale S = ', s)

else
writeln ('x = ', x,' NU este prim cu suma cifrelor sale S = ', s);

write ('Dati x = ');


readln ( x );
end;
readln;
end.

{Introducerea urmtoarelor numere}

ATESTAT - 2003 - 3 - Fie x un numr natural. Stabilii care este factorul prim care, n descompunerea
lui x, apare la puterea maxim.
Rezolvare:
Notm cu d un posibil divizor al lui x. Evident, d poate lua valori consecutive ncepnd de la 2
pn la x, dar nu orice valoare ntre 2 i x este i divizor al lui x.
Contorul nr numr de cte ori x se mparte exact la un d >= 2.
7

Probleme rezolvate de programare Subiecte propuse la ATESTAT

Dup fiecare mprire exact a lui x la d, noul x devine x DIV d. Repetm (ntr-un ciclu WHILE)
aceste calcule att timp ct x > 1.

Probleme rezolvate de programare Subiecte propuse la ATESTAT

Plecm cu d de la valoarea 2 i nu de la 1, pentru a evita un ciclu infinit n urma atribuirii


x
:= x DIV d. Dac s-ar iniializa d cu 1, n urma atribuirii x := x DIV d, noua valoare a lui x ar
rmne ntotdeauna = x, deci divizorul d = 1 s-ar numra de o infinitate de ori (gsindu-l pe 1 ca
divizor de o infinitate de ori, nu s-ar mai trece niciodat la d = 2, prin atribuirea d := d + 1).
Reinem n variabila max cel mai mare numr de mpriri ale lui x la un divizor d.
Notm cu divizor divizorul pentru care numrul de mpriri este max.

Program ATESTAT_2003_3 ; {determin divizorul care apare la puterea maxim }


VAR
x, d, nr, MAX, divizor: integer;
Begin { PROGRAM PRINCIPAL }
write ('Dati x = ');
readln (x);
d := 2;
{primul divizor posibil}
max := 0; {initializare MAX}
nr := 0; {initializare numar de impartiri ale lui x la d}
while x > 1 do
begin
If x MOD d = 0 then {daca x se imparte la d}
begin
nr := nr + 1;
x := x DIV d;
if max < nr then
begin
max := nr;
writeln ('Divizorul ', d,' apare de ', max, ' ori');
divizor := d;
end
end
else
begin
d := d + 1;
nr := 0
end;
end;
writeln;
writeln ('Divizorul ', divizor,' apare la puterea maxima = ', max);
readln
end.

ATESTAT - 2003 - 4 - Se citesc pe rnd n numere naturale. Afiai-le pe cele care sunt termeni ai
irului lui Fibonacci.
Rezolvare:

Presupunem c numerele x NU sunt introduse n ordine.


Folosim o bucl exterioar n care introducem cte un x.
9

Probleme rezolvate de programare Subiecte propuse la ATESTAT

Folosim o bucl interioar n care generm un nou termen FIBONACCI, ct timp numrul x
introdus rmne > termenul FIBONACCI generat.
Termenii irului FIBONACCI se rein n vectorul FIBO.

10

Probleme rezolvate de programare Subiecte propuse la ATESTAT


Program ATESTAT_2003_4_Fibonacci ;
CONST
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
VAR
FIBO : vector;
x, n, i, j : integer;
Begin

{ PROGRAM PRINCIPAL }
write ('Dati nr. de numere naturale, n = ');
readln ( n );
for i := 1 to n do
{bucla exterioar}
begin
write ('Dati x = ');
readln (x);
FIBO [1] := 1;
FIBO [2] := 1;

{iniializarea primilor termeni ai irului}

j := 3;
while x > FIBO [j] do
{bucla interioar}
begin
FIBO [j] := FIBO [j-1] + FIBO [j-2];
j := j + 1
end;
{sfarsit bucla interioar}
if x = FIBO [j] then
writeln ('x = ', x,' este termen FIBO')
else
writeln ('x = ', x,' NU este termen FIBO')
end;
readln

{sfarsit bucla exterioar}

end.

ATESTAT - 2003 - 5 - Se citesc pe rnd n numere naturale. Afiai perechile de numere citite succesiv,
care sunt termeni ai irului lui Fibonacci.
Rezolvare:
Definim funcia VERIFICA, pentru a testa dac un numr este termen FIBONACCI.
Numerele pe care le introducem se vor reine ntr-un vector x.
Pentru introducerea vectorului, definim procedura CITESTEVECTOR.
Program ATESTAT_2003_5_Fibonacci ;
CONST
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
VAR
x, FIBO : vector;
n, i, j : integer;

11

Probleme rezolvate de programare Subiecte propuse la ATESTAT


function VERIFICA ( z : integer) : BOOLEAN;
var
OK : BOOLEAN;
begin
OK := FALSE;
FIBO [1] := 1;
FIBO [2] := 1;
if (z = 1) then
OK := TRUE;
j := 3;
while z > FIBO [j] do
begin
FIBO [j] := FIBO [j-1] + FIBO [j-2];
j := j + 1
end;
if z = FIBO [j] then
OK := TRUE;
VERIFICA := OK;
end; { sfarsit functie VERIFICA }
procedure CITESTEVECTOR ( VAR v : vector; n : integer);
begin
for i:= 1 to n do
begin
write ('Dati x [ ', i, ' ] = ');
readln ( v [i] );
end;
end;
Begin { PROGRAM PRINCIPAL }
write ('Dati nr. de numere naturale, n = ');
readln ( n );
CITESTEVECTOR (x, n);
for i := 1 to n-1 do
begin
if ( VERIFICA ( x[i] ) = TRUE ) AND ( VERIFICA ( x[i+1] ) = TRUE ) then
writeln (x [ i ] ,' si ', x [ i + 1 ] ,' sunt termeni FIBO')
else
writeln (x [ i ] ,' si ', x [ i + 1 ] ,' NU sunt termeni FIBO');
end;
readln
end.

ATESTAT - 2003 - 6 - S se genereze toate numerele de 5 cifre care au doar cifre pare i sunt
divizibile cu 13.
Rezolvare:
Notm cu a, b, c, d, e cifrele numrului x.
12

Probleme rezolvate de programare Subiecte propuse la ATESTAT

Verificarea se va face pentru toate numerele x cuprinse ntre 20000 i 88888.


Se definete o funcie CIFREPARE, care verific dac toate cifrele numrului x sunt pare.

13

Probleme rezolvate de programare Subiecte propuse la ATESTAT


Program ATESTAT_2003_6 ;
VAR
x, y, z, t, u, v, a, b, c, d, e : longint;
function CIFREPARE( z : integer) : BOOLEAN;
begin
e := x MOD 10;
y := x DIV 10;
d := y MOD 10;
z := y DIV 10;
c := z MOD 10;
t := z DIV 10;
b := t MOD 10;
v := t DIV 10;
a := v MOD 10;
if
(a MOD 2 = 0) AND (b MOD 2 = 0) AND (c MOD 2 = 0)
AND (d MOD 2 = 0) AND (e MOD 2 = 0) then
CIFREPARE := TRUE
ELSE
CIFREPARE := FALSE;
end; { sfarsit functie CIFREPARE }
Begin { PROGRAM PRINCIPAL }
for x := 20000 to 88888 do
begin
if ( CIFREPARE (x) = TRUE ) AND ( x MOD 13 = 0 ) then
begin
writeln ('x = ', x, ' are toate cifrele pare si se divide la 13');
writeln ('Apasati ENTER');
readln
end;
end;
readln
end.

ATESTAT - 2003 - 7 - S se genereze toate numerele de 6 cifre, care au cifrele ordonate descresctor,
prima i ultima cifr fiind impare.
Rezolvare:
Notm cu a, b, c, d, e, f cifrele numrului x.
Definim funcia VERIFICA (x), care determin cifrele lui x si apoi face verificrile impuse de
problem.
Numerele testate sunt cuprinse ntre 987653 i 654321.
Program ATESTAT_2003_7 ;
VAR
x, y, z, t, u, v, w, a, b, c, d, e, f : longint;
function VERIFICA ( z : longint) : BOOLEAN;
begin
f := x MOD 10;
{determinarea cifrelor lui x}
y := x DIV 10;
e := y MOD 10;
z := y DIV 10;
d := z MOD 10;
t := z DIV 10;
c := t MOD 10;
v := t DIV 10;

14

Probleme rezolvate de programare Subiecte propuse la ATESTAT


b := v MOD 10;
w := v DIV 10;
a := w MOD 10;

15

Probleme rezolvate de programare Subiecte propuse la ATESTAT


if (a > b) AND (b >c) AND (c >d)
AND (d >e) AND (e >f) then
begin
if (a MOD 2 <> 0 ) AND (f MOD 2 <> 0) then
VERIFICA := TRUE
else
VERIFICA := FALSE
end
else
VERIFICA := FALSE;
end; { sfarsit functie VERIFICA }
Begin

{ PROGRAM

PRINCIPAL }

for x := 987653 downto 654321 do


begin
if VERIFICA (x) = TRUE then
begin
writeln ('x = ', x );
writeln ('Apasati ENTER');
readln
end;
end;
readln
end.

ATESTAT - 2003 - 8 - S se determine toate cuvintele de 5 litere ce conin mcar dou vocale i au a
2-a liter m.
Rezolvare:
Generm cuvintele folosind un ir de caractere cuvant de lungime = 5.
Pe poziia 2 din cuvant va fi ntotdeauna litera m, deci cuvant [2] := 'm'.
Pe celelalte 4 poziii (1, 3, 4, 5) din cuvant vom plasa consoane i vocale. Pentru aceasta, folosim
4 bucle FOR n care contorii de tip CHAR vor fi chiar elementele irului cuvant de pe poziiile
1, 3, 4, 5 (cuvant [1], cuvant [3], cuvant [4], cuvant [5]), care vor lua valori de tip CHAR de la a
la z.
Pentru fiecare poziie din irul cuvant testm dac pe poziia respectiv se afl o vocal i dac
DA, numrm acea vocal, folosind contorul nrvocale.
Dup generarea unei combinaii de vocale i consoane care compun un cuvnt (la sfritul buclei
FOR de la interior), testm dac nrvocale >= 2 i dac DA, numrm cuvntul care satisface
condiiile problemei (majorm contorul i) i afim cuvntul.
La nceputul buclei FOR situate cel mai interior, trebuie s iniializm, de fiecare dat, contorul
care numr vocalele, scriind nrvocale := 0;
Program ATESTAT_2003_8 ;
uses crt;
var
cuvant : string;
i, nrvocale : integer;
Begin

{ PROGRAM

PRINCIPAL }

16

Probleme rezolvate de programare Subiecte propuse la ATESTAT


i := 0;
{i = contor care numr cuvintele pe care le vom genera}
cuvant [2] := 'm';

17

Probleme rezolvate de programare Subiecte propuse la ATESTAT


for cuvant [1] := 'a' to 'z' do
begin
for cuvant [3] := 'a' to 'z' do
begin
for cuvant [4] := 'a' to 'z' do
begin
for cuvant [5] := 'a' to 'z' do
begin
nrvocale := 0; {contor ce numr vocalele din cuvant}
if cuvant [1] IN ['a','e','o','i','u'] then
nrvocale := nrvocale + 1;
if cuvant [3] IN ['a','e','o','i','u'] then
nrvocale := nrvocale + 1;
if cuvant [4] IN ['a','e','o','i','u'] then
nrvocale := nrvocale + 1;
if cuvant [5] IN ['a','e','o','i','u'] then
nrvocale := nrvocale + 1;
if nrvocale >= 2 then
begin
i := i + 1;
writeln ('i = ', i);
writeln ('cuvantul = ', cuvant [1], cuvant[2],
cuvant[3], cuvant[4], cuvant[5]);
end;
readln
end
end;
end;
end;
readln
end.

ATESTAT - 2003 - 9 - S se afieze toate matricile ptratice n x n care conin pe fiecare linie i
coloan un singur 1, n rest 0.
Rezolvare:
Aceast problem este asemntoare cu problema celor n regine, pe care o vom adapta la
cerinele de mai sus. Asociem unei regine o cifr de 1. Problema reginelor cere s se plaseze n regine pe
o tabl de ah de dimensiune n x n, astfel nct oricare dou regine s nu se atace. Pentru ca dou
regine s nu se atace, ele trebuie s nu fie situate pe aceeai linie, pe aceeai coloan sau pe aceeai
diagonal. La noi, rolul reginelor va fi jucat de elementele egale cu 1 din matricea ptratic n x n. n cazul
problemei noastre, vom renuna la cerina ca elementele matricii egale cu 1 s nu fie plasate pe aceeai
diagonal. Pe fiecare linie trebuie s fie plasat cte o regin. Deci, pentru ca poziia reginelor s fie complet
determinat, este suficient s reinem, pentru fiecare regin, coloana n care este plasat, ntr-un vector
soluie f, de dimensiune n, unde f [i] reprezint coloana n care este plasat regina de pe linia i. Generarea
matricilor n condiiile problemei se face apelnd la un algoritm backtracking.
Observaii:
Notm cu x, respectiv i o linie oarecare i cu f [x], respectiv f [i], coloana pe care se gsete
regina de pe linia x, respectiv linia i.
Condiiile interne:
a). f [x] = 1, 2, ..., n, pentru oricare x = 1, 2, ..., n
b). Dou regine nu pot fi plasate pe aceeai coloan se va exprima analitic astfel:
18

Probleme rezolvate de programare Subiecte propuse la ATESTAT

f [x] f [y] pentru orice x y, cu x, y = 1, 2,...,n.


Definim o procedur AFIARE astfel:

19

Probleme rezolvate de programare Subiecte propuse la ATESTAT

n momentul apelrii procedurii, este evident c s-a gsit o soluie pe care o numrm scriind:
Nrsol := Nrsol + 1
i apoi afim Nrsol.
Vom parcurge toate coloanele de la 1 la n. Pentru aceasta avem nevoie de un contor poziional col
care va lua valori de la 1 la n.
n procedur, col este o coloan curent, iar f [lin] este tot o coloan, i anume coloana pe care
se gsete regina de pe linia lin.
Procedura va tipri " * " dac pe coloana curent col exist o regin, adic atunci cnd
col = f
[lin], i va tipri "o" dac aceast condiie nu este satisfcut.
Program ATESTAT_2003_9 ;
uses crt;
const
nrmaxregine = 8; {8 sau alt valoare}
type
vectorsolutie = array [0..nrmaxregine] of 0..nrmaxregine;
var
f : vectorsolutie;
n, x, i : 0 .. nrmaxregine;
ok : boolean;
nrsol : word;
procedure AFISARE;
var
i, j : 0 ..nrmaxregine;
begin
nrsol := nrsol + 1;
writeln;
writeln ('Solutia nr. ',nrsol);
for i := 1 to n do
begin
for j := 1 to n do
begin
if j = f [i] then
write (' 1 ')
else
write (' o ')
end;
writeln;
end;
writeln;
readln
end; { sfarsit procedura }
Begin { PROGRAM PRINCIPAL }
clrscr;
write ('Introduceti numarul de patratele
readln (n);
nrsol:=0;
x := 1;
f [x] := 0;

n = ');

{ virful stivei }

while x > 0 do
{ cit timp stiva nu este vida }
begin
while f [x] < n do
{ cit timp exista valori disponibile }
begin
f [x] := f [x] + 1;

20

Probleme rezolvate de programare Subiecte propuse la ATESTAT


ok := true;

21

Probleme rezolvate de programare Subiecte propuse la ATESTAT


for i := 1 to x - 1 do
begin
if ( f[i] = f [x] ) then
begin
ok := false;
end
end;
if ok = true then { valoarea este valida }
begin
if x = n then
{ stiva este plina }
AFISARE
else
begin
x := x + 1;
{PAS INAINTE}
f [x] := 0
end;
end;
end; { sfarsit WHILE interior }
x := x 1
{PAS INAPOI}
end; { sfarsit WHILE exterior }
readln
end.

ATESTAT - 2003 - 10 - S se genereze toate permutrile mulimii {1, 2,... n} cu condiia ca orice
dou numere alturate ale unei permutrii s fie prime ntre ele.
Rezolvare:

Definim o funcie CMMDC pentru a calcula CMMDC al dou numere.


Funcia CMMDC va fi apelat n procedura PERMUT, pentru a se testa dac dou numere
alturate ale unei permutri sunt prime ntre ele. Cu excepia acestei verificri impuse de enunul
problemei de fa, procedura PERMUT are acelai coninut ca i cel de la generarea permutrilor
de ordinul n.

Program ATESTAT_2003_10_PERMUTARI ;
uses crt;
const
nmax = 100;
type
vector = array [1..nmax] of integer;
var
f : vector;
sol, n, i : integer;
OK : boolean;
function CMMDC (A, B : integer) : integer;
var
aux, R : integer;
begin
if A < B then
begin
aux := A;
A := B;
B := aux
end;

22

Probleme rezolvate de programare Subiecte propuse la ATESTAT


R := A MOD B;
while R <> 0 do
begin
A := B;
B := R;
R := A MOD B
end;
CMMDC := B
end; { sfarsit functie CMMDC }
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
begin
write ( f [i] : 3 )
end;
writeln
end;
procedure PERMUTA ( m : integer );
LABEL
20;
var
k : integer;
CONTIN : boolean;
Begin
{nceput procedur PERMUTA}
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

23

Probleme rezolvate de programare Subiecte propuse la ATESTAT


begin
OK := TRUE;

24

Probleme rezolvate de programare Subiecte propuse la ATESTAT


for i := 1 to n - 1 do
begin
if CMMDC ( f[i], f[i-1] ) <> 1 then
OK := FALSE
end;
if OK = TRUE then
SCRIE;
end;
if ( CONTIN = TRUE ) and (k < n) then
begin
k := k + 1;
f [k] := 0
end;
if CONTIN = FALSE then
k := k - 1
end; {sfrit WHILE exterior}
end;
{sfrit procedur PERMUTA}
Begin

{ PROGRAM
clrscr;

PRINCIPAL }

sol := 0;
write('Dati n = ');
readln (n);
writeln;
PERMUTA (n);
if sol = 0 then
writeln ('Nu exista solutie');
readln
end.

ATESTAT - 2003 - 11 - S se genereze toate variantele de punctaje ce aparin {1, 2,... 10} obinute la
n examene, astfel nct punctajul obinut s fie minim.
Rezolvare:
Generarea combinaiilor de note se face dup algoritmul BACKTRACKING.
Folosim un vector max n care memorm nota maxim obinut la fiecare din cele n examene. Evident,
vectorul max va avea n elemente.
n algoritmul de generare a produsului cartezian din lucrarea amintit, am notat cu f [x] o valoare
numeric dintr-o poziie x. Adaptm aceste notaii la problema noastr: n loc de x notm cu poz
poziia n care se gsete o not n combinaia de note care va fi generat i cu nota [poz], nota de pe
poziia poz. Poziia poz va lua valori de la 1 la n (n = total examene). Evident, nota va fi un vector
cu max [i] elemente, unde i este numrul de ordine al unui examen.

25

Probleme rezolvate de programare Subiecte propuse la ATESTAT


Program ATESTAT_2003_11_Produs_cartezian_EXAMENE;
uses CRT;
type
vector = array [1..20] of integer;
{20 = nr. de examene}
var
i, poz, n : integer;
max, nota : vector;
S, min : integer;
procedure SCRIE;
begin
write ('{ ');
for i := 1 to n - 1 do
begin
write ( nota[i],' , ');
end;
write ( nota[n],' ');
write ('} ');
writeln;
end;
Begin { PROGRAM PRINCIPAL }
CLRSCR;
write ('Introduceti numarul de EXAMENE, n = ');
readln (n);
writeln;
writeln (Pentru fiecare examen, precizati care este nota MAXIMA);
writeln ('Scrieti 10 pt. note de la 1 la 10 :
');
writeln;
for i:= 1 to n do
begin
write ('Pentru examenul ', i, ' Care este nota MAXIMA ? ');
readln ( max [i] );
end;
writeln;
Writeln ('Punctajul minim = suma notelor la fiecare examen');
write ('Precizati punctajul MINIM pe care vreti sa-l obtineti, Min = ');
readln (min);
poz := 1;
{nceput algoritm BACKTRACKING}
nota [poz] := 0;
while poz > 0 do
begin
if nota [poz] < max [poz] then
begin
nota [poz] := nota [poz] + 1;
if poz = n then
begin
S := 0;
for i := 1 to n do
S := S + nota [i] ;
if S = min then
SCRIE;
end
else
begin
poz := poz + 1; {PAS NAINTE}
nota [poz] := 0
end
end
else
poz := poz 1
{PAS NAPOI}

26

Probleme rezolvate de programare Subiecte propuse la ATESTAT


end;
readln
end.

27

Probleme rezolvate de programare Subiecte propuse la ATESTAT

ATESTAT - 2003 - 12 - Afiai numere prime mai mici dect un numr n citit de la tastatur, care
rmn prime i dup ce au fost inversate.
Rezolvare:
Definim o funcie PRIM, cu rezultat de tip BOOLEAN, care testeaz dac un numr este prim.
Definim o funcie INVERS care inverseaz elementele unui ir.
n programul principal, nainte de a inversa un numr x, l transformm mai nti ntr-un ir cu
funcia STR.
Dup inversare, transformm irul obinut ntr-un numr cu funcia VAL.
Testm dac numrul obinut prin inversare este i el prim.
Program ATESTAT_2003_12 ;
uses crt;
var
inversul, sir : string;
a, b, i, x, n, invx : integer;
function PRIM (x : integer ) : boolean;
var
nrdiv, diviz : integer;
begin
nrdiv := 0;
diviz := 1;
while diviz <= x do
begin
if x MOD diviz = 0 then
nrdiv := nrdiv + 1;
diviz := diviz + 1
end;
if nrdiv = 2 then
PRIM := TRUE
else
PRIM := FALSE;
end;
function INVERS (s : string) : string;
var
inv : string;
begin
inv := '';
for i := LENGTH (s) DOWNTO 1 do
begin
inv := inv + s [i]
end;
INVERS := inv ;
end;
Begin

{ PROGRAM
clrscr;

PRINCIPAL }

write('Dati n = ');
readln (n);
writeln;
for x := 1 to n do
begin
STR (x, sir);

28

Probleme rezolvate de programare Subiecte propuse la ATESTAT


inversul := INVERS (sir);
VAL (inversul, a, b);
invx := a;

29

Probleme rezolvate de programare Subiecte propuse la ATESTAT


if PRIM (x) = TRUE then
begin
if PRIM (invx) = TRUE then
begin
writeln ('x = ', x,' = prim');
writeln ('invx = ', invx,' = prim');
end;
end;
end;
readln
end.

ATESTAT - 2003 - 13 - Se citete un vector cu n componente numere ntregi. S se determine


CMMDC al valorilor din vector.
Rezolvare:
Definim funcia CMMDC cu care calculm CMMDC al dou numere.
Calculm CMMDC al primelor dou numere din vector (x1 si x2) i l notm cu C[1].
ncepnd de la i = 2 pn la n, facem atribuirile:
x [i] := C [i-1];
C [i] := CMMDC ( x [i], x [i+1] )
Altfel spus, calculm CMMDC dintre CMMDC-ul anterior i urmtorul element al vectorului.
Program ATESTAT_2003_13 ;
uses crt;
const
nmax = 100;
type
vector = array [1..nmax] of integer;
var
x, C : vector;
sol, n, i : integer;
function CMMDC (A, B : integer) : integer;
var
aux, R : integer;
begin
if A < B then
begin
aux := A;
A := B;
B := aux
end;
R := A MOD B;
while R <> 0 do
begin
A := B;
B := R;
R := A MOD B
end;
CMMDC := B
end; { sfarsit functie CMMDC }
Begin

{ PROGRAM

PRINCIPAL }

30

Probleme rezolvate de programare Subiecte propuse la ATESTAT


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

31

Probleme rezolvate de programare Subiecte propuse la ATESTAT


writeln ('Dati vectorul');
writeln;
for i := 1 to n do
begin
write ('Dati x [ ', i, ' ] = ');
readln ( x [i] );
end;
C [1] := CMMDC ( x[1], x [2] );
for i := 2 to n-1 do
begin
x [i] := C [i-1];
C [i] := CMMDC ( x [i], x [i+1] )
end;
writeln ('CMMDC = ', C [n-1] );
readln
end.

ATESTAT - 2003 - 14 - Se citesc 2 numere naturale A < B. S se tipreasc toate numerele


PALINDROAME dintre A i B. Un numr este PALINDROM dac, citit direct i invers, rezultatul
este acelai (dac este egal cu inversul su). Exemplu: 323 este PALINDROM.
Rezolvare:
Definim o funcie NRCIFRE pentru a numra cifrele unui numr natural.
Definim o funcie PALINDROM n care:
- determinm numrul de cifre pentru un numr natural;
- extragem din numrul natural cifrele i le depunem ntr-un vector y;
- verificm dac vectorul y este simetric (PALINDROM).
n programul principal, apelm funcia PALINDROM pentru toate numerele naturale dintre
B i le afim doar pe acelea care sunt palindroame.
Program ATESTAT_2003_14 ;
uses crt;
VAR
A, B, x, n, nrcif, i : integer;
OK : boolean;
y : array [1..100] of integer;
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;

32

A i

Probleme rezolvate de programare Subiecte propuse la ATESTAT


NRCIFRE := nrcif
end;

33

Probleme rezolvate de programare Subiecte propuse la ATESTAT


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;
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;
Begin

{ PROGRAM PRINCIPAL }
clrscr;
write ('Dati A = ');
readln (A);
writeln;
write ('Dati B = ');
readln (B);
writeln;
clrscr;
for x := A to B do
begin
if PALINDROM (x) = TRUE then
writeln ('x = ', x, ' este PALINDROM');
{ else
writeln ('x = ', x, ' NU este palindrom'); }
{readln;}
end;
readln

end.

ATESTAT - 2003 - 15 - Se citete un vector cu n componente ntregi. Care este cea mai mare sum care
se poate forma cu ele?
Exemplu: n = 4, iar numerele citite sunt 1, 3, 2, -7. Se va tipri 5.
Rezolvare:
Numerele ntregi introduse vor fi reinute ntr-un vector x.
Numerele ntregi introduse pot fi pozitive, negative sau nule. Evident, suma cea mai mare ce se poate
obine din ntregul ir de numere va rezulta prin nsumarea doar a numerelor pozitive.
Notm cu Spoz suma numerelor strict pozitive. ntr-o bucl FOR, vom aduga la aceast sum cte
un termen, doar dac acest termen este strict > 0.
Program ATESTAT_2003_15 ;
uses crt;

34

Probleme rezolvate de programare Subiecte propuse la ATESTAT


VAR
Spoz, n, i : integer;
x : array [1..100] of integer;

35

Begin

{ PROGRAM
clrscr;

Probleme rezolvate de programare Subiecte propuse la ATESTAT


PRINCIPAL }

write ('Dati n = ');


readln (n);
writeln;
writeln ('Dati vectorul');
for i := 1 to n do
begin
write ('Dati x [ ', i, ' ] = ');
readln ( x [i] );
end;
writeln;
Spoz := 0;
for i := 1 to n do
begin
if x [i] > 0 then
Spoz := Spoz + x [i];
end;
writeln ('Spoz = ', Spoz);
readln
end.

ATESTAT - 2003 - 16 Interschimbai coloanele unei matrici cu m linii i n coloane astfel nct, n
linia k, elementele s fie ordonate cresctor.
Rezolvare:
Ordonm linia k. n cursul procesului de ordonare, o parte din elementele liniei k se
interschimb ntre ele.
n paralel cu ordonarea, interschimbm i coloanele corespunztoare elementelor de pe linia k
supuse interschimbrilor.
Program ATESTAT_2003_16 ;
uses crt;
VAR
OK, m, n, i, j, k : integer;
A : array [1..100, 1..100] of integer;
aux : integer;
Begin

{ PROGRAM
clrscr;

PRINCIPAL }

write('Dati m = ');
readln (m);
writeln;
write ('Dati n = ');
readln (n);
writeln;
write ('Dati linia

k = ');

36

Probleme rezolvate de programare Subiecte propuse la ATESTAT


readln (k);
writeln;

37

Probleme rezolvate de programare Subiecte propuse la ATESTAT


writeln ('Dati matricea');
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;
REPEAT
{Ordonm linia k, prin metoda BUBBLE-SORT}
OK := 0;
j := 1;
REPEAT
if A [k, j] > A [k, j+1] then
begin
for i := 1 to m do
begin
aux := A [i, j];
A [i, j] := A [i, j+1];
A [i, j+1] := aux;
OK := 1;
end;
end;
j := j + 1;
UNTIL (j > n - 1) ;
UNTIL (OK = 0);
writeln;
writeln ('Matricea ordonata este');
for i := 1 to m do
begin
for j := 1 to n do
begin
write ('A [ ', i, ',', j, ' ] = ', A [i,j],'
end;
writeln;
end;
readln

' );

end.

ATESTAT - 2003 - 17 - Se citete un text i o succesiune de caractere. De cte ori ntlnim aceast
succesiune n cadrul textului ?
Rezolvare:
Apelm funcia POS (subir, ir) i determinm poziia unde apare subir n ir.
Dac poziia determinat este <> 0, atunci majorm contorul nrapariii, care numr apariiile
subirului n ir.
De asemenea, dac poziia determinat este <> 0, tergem din irul dat caracterele, de la poziia 1, pe
o lungime = poziia + LENGTH (subir) 1, unde poziia este valoarea determinat cu funcia
POS.

38

Probleme rezolvate de programare Subiecte propuse la ATESTAT

39

Probleme rezolvate de programare Subiecte propuse la ATESTAT


Program ATESTAT_2003_17 ;
uses crt;
var
sir, subsir : string;
pozitia, nraparitii : integer;
OK : boolean;
Begin { PROGRAM PRINCIPAL }
clrscr;
write('Dati sirul = ');
readln (sir);
writeln;
writeln ('Dati subsirul = ');
readln (subsir);
writeln;
nraparitii := 0;
OK := TRUE;
{ presupun ca subsirul exista }
while (sir <> '' ) AND ( OK = TRUE ) do
begin
pozitia := POS (subsir, sir);
if pozitia <> 0 then
begin
nraparitii := nraparitii + 1 ;
DELETE (sir, 1, pozitia + LENGTH (subsir) - 1 )
end
else
OK := FALSE
end;
writeln ('nraparitii = ', nraparitii);
readln
end.

ATESTAT - 2003 - 18 - Problema celor 8 regine. S se afieze toate posibilitile de a se aeza, pe o


tabl de ah, 8 regine fr s se atace ntre ele.
Rezolvare:
Problema reginelor cere s se plaseze n regine pe o tabl de ah de dimensiune n x n astfel nct
oricare dou regine s nu se atace. Pentru ca dou regine s nu se atace, ele trebuie s nu fie situate pe
aceeai linie, pe aceeai coloan sau pe aceeai diagonal. Pe fiecare linie trebuie s fie plasat cte o
regin. Deci, pentru ca poziia reginelor s fie complet determinat, este suficient s reinem, pentru fiecare
regin, coloana n care este plasat, ntr-un vector soluie f, de dimensiune n, unde f [i] reprezint coloana
n care este plasat regina de pe linia i. Generarea matricilor care afieaz poziiile reginelor, n condiiile
problemei, se va face apelnd la un algoritm backtracking.
Observaii:
Notm cu x, respectiv i o linie oarecare i cu f [x], respectiv f [i] coloana pe care se gsete
regina de pe linia x, respectiv linia i.
Condiiile interne:
a). f [x] = 1, 2, ..., n, pentru oricare x = 1, 2, ..., n
b). Condiia dou regine nu pot fi plasate pe aceeai coloan se va exprima analitic astfel:
f [x] f [y] pentru orice x y, cu x, y = 1, 2,...,n.
c). Dou regine nu pot fi plasate pe aceeai diagonal. Dac regina de pe linia i, coloana f [i] este pe aceeai
diagonal cu regina de pe linia x, coloana f [x], atunci triunghiul dreptunghic care se formeaz are
unghiurile de 45 grade, este deci isoscel (catetele sale vor fi egale), ceea ce se poate scrie astfel:
|i-x|=|f[i]-f[x]|
40

Probleme rezolvate de programare Subiecte propuse la ATESTAT

Cum acest lucru nu este permis de problem, condiia dou regine nu pot fi plasate pe aceeai
diagonal se va exprima astfel:
| f [i] - f [x] | <> | i - x | pentru orice i, x = 1, 2, ..., n

41

Probleme rezolvate de programare Subiecte propuse la ATESTAT

Definim o procedur AFIARE astfel nct:


n momentul apelrii procedurii, evident s-a gsit o soluie pe care o numrm scriind:
Nrsol := Nrsol + 1
i apoi afim Nrsol.
Vom parcurge toate coloanele de la 1 la n. Pentru aceasta avem nevoie de un contor poziional col care
va lua valori de la 1 la n.
n procedur, col este o coloan curent, iar f [lin] este tot o coloan, i anume coloana pe care se
gsete regina de pe linia lin.
Procedura va tipri " * " dac pe coloana curent col exist o regin, adic atunci cnd
col = f [lin], i va tipri "o" dac aceast condiie nu este satisfcut.
Program ATESTAT_2003_18_REGINE ;
uses crt;
const
nrmaxregine = 8;
type
vectorsolutie = array [0..nrmaxregine] of 0..nrmaxregine;
var
f : vectorsolutie;
n, x, i : 0 .. nrmaxregine;
ok : boolean;
nrsol : word;
procedure AFISARE;
var
i, j : 0 ..nrmaxregine;
begin
nrsol := nrsol + 1;
writeln;
writeln ('Solutia nr. ',nrsol);
for i := 1 to n do
begin
for j := 1 to n do
begin
if j = f [i] then
write (' * ')
else
write (' o ')
end;
writeln;
end;
writeln;
readln
end; { sfarsit procedura }
Begin { PROGRAM PRINCIPAL }
clrscr;
write ('Introduceti numarul de patratele
readln (n);
nrsol:=0;
x := 1;
{ virful stivei }
f [x] := 0;

n = ');

while x > 0 do
{ ct timp stiva nu este vid nceput algoritm }
begin
{ backtracking }
while f [x] < n do
{ ct timp exist valori disponibile }
begin

42

Probleme rezolvate de programare Subiecte propuse la ATESTAT


f [x] := f [x] + 1;

43

Probleme rezolvate de programare Subiecte propuse la ATESTAT


ok := true;
for i := 1 to x - 1 do
begin
if (f[i] = f [x]) OR (ABS (i-x) = ABS (f[i] - f[x])) then
begin
ok := false;
end
end;
if ok = true then { valoarea este valid }
begin
if x = n then
{ stiva este plin }
AFISARE
else
begin
x := x + 1;
{PAS NAINTE}
f [x] := 0
end;
end;
end; { sfarsit WHILE interior }
x := x 1
{PAS NAPOI}
end; { sfarsit WHILE exterior }
readln
end.

ATESTAT - 2003 - 19 - Se dau dou numere naturale n i k. S se genereze toate combinrile de n


elemente luate cte k.
Rezolvare: Aplicm algoritmul BACKTRACKING pentru generarea combinrilor.
Program ATESTAT_2003_19_COMBINARI_BACKTRACKING_1 ;
uses CRT;
CONST
Kmax = 20; { nr. max a lui k }
Nmax = 50; { nr. max a lui n }
TYPE
functie = array [ 1 .. Kmax ] of 0 .. Nmax;
VAR
k, poz, i : 1 .. Kmax;
{ se considera k <= n }
n : 0 .. Nmax;
f : functie;
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;

44

poz := 1;
f [poz] := 0 ;

Probleme rezolvate de programare Subiecte propuse la ATESTAT


{poz = vrful stivei }

while poz > 0 do


{ ct timp stiva nu este vid }
begin
while f [poz] < n - k + poz do { a doua condiie intern }
begin
f [poz] := f [poz] + 1;
if poz = k then
{ dac stiva este plin }
begin
for i := 1 to k do
begin
write ( 'f [',i,'] = ',f[i] , ' ');
end;
writeln;
writeln
end
else
begin
poz := poz + 1 ; { INSERARE in STIVA }
f [poz] := f [poz - 1]
end;
end; { sfarsit WHILE interior }
poz := poz - 1; { EXTRAGERE din STIVA = PAS INAPOI}
end; { sfarsit WHILE exterior }
readln
end.

ATESTAT - 2003 - 20 - S se genereze toate irurile de lungime n formate numai din literele A i
M, iruri care s nu aib dou litere A alturate. Numrul n (0 < n < 13) se citete de la
tastatur. Fiecare ir va fi scris pe cte un rnd al ecranului fr spaiu ntre litere.
Rezolvare:
Problema const n generarea produsului cartezian al mulimilor de caractere. Generarea combinaiilor
de litere se face dup algoritmul BACKTRACKING.
Algoritmul de generare a produsului cartezian va genera valori numerice cuprinse ntre 1 i
elementul maxim al unei mulimi implicate n acest produs. Cum pe noi ne intereseaz combinaiile
de litere a i m, vom asocia unui numr din cte o mulime o liter, astfel:
dac f [i] = 1, atunci sir [i] = a
dac f [i] = 2, atunci sir [i] = m.
Nu ne intereseaz dect aceste valori ale lui f [i].
Procedura SCRIE se va apela n mod opional, pentru a observa modul de generare a produsului
cartezian n varianta sa numeric.
Procedura SCRIETEXT va afia doar combinaiile de litere a i m.
Funcia boolean VECINI testeaz dac avem litera a pe dou poziii vecine.
Funcia boolean EXIST verific dac n ir exist i cifra 1. n acest fel se vor elimina
combinaiile care nu-l conin pe 1 (adic acele combinaii de litere care nu conin litera a i care,
deci, nu ne intereseaz).
Vectorul nrelem reine numrul de elemente al fiecrei mulimi din produsul cartezian.
Poz = poziia unui element ntr-o mulime a produsului cartezian.
45

Probleme rezolvate de programare Subiecte propuse la ATESTAT


Program ATESTAT_2003_20_Produs_cartezian_AMA ;
uses CRT;
type
vector = array [1..20] of integer;
var
i, poz, n : integer;
nrelem, f : vector;
sir : string;
procedure SCRIE; {procedura opional}
begin
write ('{ ');
for i := 1 to n - 1 do
begin
write (f[i],' , ');
end;
write ( f[n],' ');
write ('} ');
writeln;
end;
procedure SCRIETEXT;
begin
for i := 1 to n do
begin
if f [i] = 1 then
sir [i] := 'a';
if f [i] = 2 then
sir [i] := 'm';
write ( sir [i], ' ' );
end;
writeln;
end;
function VECINI: boolean;
var
OK : boolean;
begin
OK := FALSE;
for i:= 1 to n - 1 do
begin
if (f [i] = 1 ) AND (f [i + 1] = 1) then
OK := TRUE
end;
VECINI := OK
end;
function EXISTA : boolean; { verifica daca in sir exista si cifra 1 }
var
OK : boolean;
begin
OK := FALSE;
for i:= 1 to n do
begin
if f [i] = 1 then
OK := TRUE
end;
EXISTA := OK;
end;
Begin { PROGRAM PRINCIPAL }
CLRSCR;
write ('Stabiliti numarul de multimi, n = ');
readln (n);
for i:= 1 to n do
begin

46

Probleme rezolvate de programare Subiecte propuse la ATESTAT


write ('Cate elemente are multimea ',i,'
: ');
readln ( nrelem [i] );
end;

47

Probleme rezolvate de programare Subiecte propuse la ATESTAT


poz := 1;
f [poz] := 0;
while poz > 0 do
begin
if f [poz] < nrelem [poz] then
begin
f [poz] := f[poz] + 1;
if poz = n then
begin
if (NOT VECINI) AND (EXISTA) then
begin
{SCRIE;} {apel optional al acestei proceduri}
SCRIETEXT;
End;
end
else
begin
poz := poz + 1; {PAS INAINTE}
f [poz] := 0
end
end
else
poz := poz 1
{PAS INAPOI}
end;
readln
end.

ATESTAT - 2003 - 21 - Generarea permutrilor de n elemente, n > 0.


Rezolvare:
Aplicnd algoritmul BACKTRACKING, vom genera permutrile de ordinul n n variant iterativ.
Program ATESTAT_2003_21_PERMUTARI_ITERATIV;
uses crt;
const
nmax = 100;
type
vector = array [1..nmax] of integer;
var
f : vector;
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:

48

Probleme rezolvate de programare Subiecte propuse la ATESTAT


end;

49

Probleme rezolvate de programare Subiecte propuse la ATESTAT


procedure SCRIE ;
begin
sol := sol + 1;
write ('Solutia nr. ',sol,'
');
for i := 1 to n do
begin
write ( f [i] : 3 )
end;
writeln
end;
procedure PERMUTA ( m : integer );
LABEL
20;
var
poz : integer;
CONTIN : boolean;
begin
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;
{sfarsit WHILE interior}
20:

if ( CONTIN = TRUE ) AND (poz = n) then


SCRIE;
if ( CONTIN = TRUE ) and (poz < n) then
begin
poz := poz + 1; {PAS INAINTE}
f [poz] := 0
end;
if CONTIN = FALSE then
poz := poz 1
{PAS INAPOI}
end; {sfarsit WHILE exterior}
end;
{sfarsit procedura PERMUTA}

Begin

{ PROGRAM
clrscr;

PRINCIPAL }

sol := 0;
write('Dati n = ');
readln (n);
writeln;
PERMUTA (n);
if sol = 0 then
writeln ('Nu exista solutie');

50

Probleme rezolvate de programare Subiecte propuse la ATESTAT


readln
end.

51

Probleme rezolvate de programare Subiecte propuse la ATESTAT

ATESTAT - 2003 - 22 - S se afieze termenii irului lui Fibonacci, pentru un n dat.


Rezolvare:
Termenii irului vor fi reinui ntr-un tablou FIBO. Generarea termenilor se va face n variant
iterativ.
Program ATESTAT_2003_22 ;
CONST
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
VAR
FIBO : vector;
n, i : integer;
Begin { PROGRAM PRINCIPAL }
write ('Dati numraul de termeni, n = ');
readln (n);
FIBO [1] := 1;
FIBO [2] := 1;
for i := 3 to n do
begin
FIBO [i] := FIBO [i-1] + FIBO[i-2];
end;
for i := 1 to n do
begin
writeln ( FIBO [ i ] ,' = ', FIBO [ i ] )
end;
readln
end.

ATESTAT - 2003 - 23 - Fie A un ir cu n elemente ntregi, n > 0. S se ordoneze cresctor folosind


metoda bulelor.
Rezolvare:

Definim procedura ORDONEAZA, bazat pe algoritmul de sortare BUBBLE-SORT.


Definim procedura TIPARESTE, care afieaz vectorul sortat.

Program ATESTAT_2003_23_BUBBLE_SORT ;
uses CRT;
const
nmax = 30;
type
vector = array [1..nmax] of integer;
var
a : vector;
i, n : integer;
procedure ORDONEAZA (var x:vector; m:integer);
var
k, j, aux: integer;
begin
repeat

52

Probleme rezolvate de programare Subiecte propuse la ATESTAT


k:= 0;
j := 1;

53

Probleme rezolvate de programare Subiecte propuse la ATESTAT


repeat
if x[j] < x [j+1] then
begin
aux := x[j];
x[j] := x[j+1];
x[j+1] := aux;
k := 1
end;
j := j + 1
until (j > m - 1)
until (k = 0);
end;
procedure TIPARESTE (x:vector; m:integer);
begin
for i := 1 to m do
begin
writeln ('x [i] = ', x [i])
end
end;
Begin { PROGRAM PRINCIPAL }
clrscr;
write ('Introduceti n = ');
readln (n);
writeln;
for i := 1 to n do
begin
write ('a [i] = ');
readln (a [i] )
end;
writeln;
readln;
clrscr;
writeln;
ORDONEAZA (a, n);
TIPARESTE (a, n);
writeln;
readln
end.

ATESTAT - 2003 - 24 - Fie A i B doi vectori cu cte m, respectiv n elemente numere ntregi
0, n > 0), ordonai cresctor. S se interclaseze, n vectorul C, vectorii A i B.
Rezolvare:
Program ATESTAT_2003_24_INTERCLASARE ;
uses CRT;
CONST
nmax = 50;
TYPE
vector = array [1..nmax] of integer;

54

(m >

Probleme rezolvate de programare Subiecte propuse la ATESTAT


vectortot = array [1..2*nmax] of integer;

55

Probleme rezolvate de programare Subiecte propuse la ATESTAT


var
m, n, i, j, k : integer;
A, B : vector;
C : vectortot;
Begin { PROGRAM PRINCIPAL }
clrscr;
write ('Dati numarul de elemente ale vectorului a,
readln (m);
write ('Dati numarul de elemente ale vectorului b,
readln (n);
writeln;
writeln ('Dati primul vector SORTAT :');
writeln;
for i := 1 to m do
begin
write ('A [',i,'] = ');
readln ( A [i] );
end;
writeln;
writeln ('Dati al doilea vector SORTAT');
writeln;
for j := 1 to n do
begin
write ('B [',j,'] = ');
readln (B [j]);
end;
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 <=
begin
k
C
i
end;

m do
:= k + 1;
[k] := A [i];
:= i + 1

WHILE j <= n do
begin
k := k + 1;

56

m = ');

n = ');

Probleme rezolvate de programare Subiecte propuse la ATESTAT


C [k] := B [j];
j := j + 1
end;

57

Probleme rezolvate de programare Subiecte propuse la ATESTAT


writeln;
writeln ('Vectorul rezultat in urma interclasarii este:');
writeln;
for k := 1 to m + n do
begin
writeln ('C [',k,'] = ', C [k] );
end;
readln
end.

ATESTAT - 2003 - 25 - Fie X un vector ordonat cu n elemente numere ntregi, n > 0 i elem o
valoare ntreag, citit de la tastatur. S se decid dac elem se gsete n vectorul X, folosind
metoda Divide et Impera.
Rezolvare:
Program ATESTAT_2003_25_Cautare_Binara_Recursiva ;
uses CRT;
type
vector = array [1..20] of integer;
VAR
x : vector;
elem, n, i : integer;
GASIT : boolean; {GASIT = TRUE daca elementul a fost gasit si FALSE daca nu}
procedure CAUTA ( incep, sf : integer; VAR GASIT : boolean );
var
m : integer;
begin
IF incep <= sf then
begin
m := (incep + sf) DIV 2;
if elem = x [m] then
GASIT := true
else
if elem < x [m] then
CAUTA ( incep, m-1, GASIT)
else
CAUTA (m+1, sf, GASIT)
end
ELSE
GASIT := false
end; {sfarsit procedura}
Begin { PROGRAM PRINCIPAL }
CLRSCR;
write ('n = ');
readln (n);
for i := 1 to n do
begin
write ('x [ ',i,' ] = ');
readln (x[i]);
end;

58

Probleme rezolvate de programare Subiecte propuse la ATESTAT


writeln;
write ('Dati elementul cautat, elem = ');
readln (elem);
CAUTA (1, n, GASIT);
if GASIT = true then
writeln (elem,' exista')
else
writeln (elem,' nu exista');
readln
end.

ATESTAT - 2003 - 26 - Fie n numere ntregi a1, a2, ... an, cu n > 0. S se determine CMMDC al celor
n numere, prin metoda DEI.
Rezolvare:
Prin metoda DEI (Divide-Et-Impera) se determin CMMDC pentru prima jumtate a vectorului, apoi
pentru cea de-a doua jumtate, dup care vom reuni rezultatele.
Program ATESTAT_2003_26_CMMDC_DEI ;
CONST
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
VAR
x : vector;
C, n, i : integer;
function CMMDC (A, B : integer) : integer;
var
aux, R : integer;
begin
if A < B then
begin
aux := A;
A := B;
B := aux
end;
R := A MOD B;
while R <> 0 do
begin
A := B;
B := R;
R := A MOD B
end;
CMMDC := B
end; { sfarsit functie CMMDC }
function DIVCOM (incep, sf : integer): integer;
{ determina CMMDC prin DEI }
VAR
mij, C1, C2 : integer;
begin
if incep = sf then
DIVCOM := x [incep]
else
begin

59

Probleme rezolvate de programare Subiecte propuse la ATESTAT


if sf - incep = 1 then
DIVCOM := CMMDC ( x [incep], x [sf] )

60

Probleme rezolvate de programare Subiecte propuse la ATESTAT


else
begin
mij := (incep + sf) DIV 2;
C1 := DIVCOM (incep, mij);
C2 := DIVCOM (mij + 1, sf);
DIVCOM := CMMDC (C1, C2)
end
end
end; { sfarsit functie DIVCOM }
Begin { PROGRAM PRINCIPAL }
write ('Dati nr. de elemente ale vectorului, n = ');
readln (n);
for i:= 1 to n do
begin
write ('Dati x [ ', i,' ] = ');
readln (x [i])
end;
C := DIVCOM (1, n);
writeln ('C = ', C);
readln
end.

ATESTAT - 2003 - 27 - Fie A un ir cu n numere ntregi, n > 0. S se ordoneze cresctor folosind


metoda sortrii prin numrare.
Rezolvare:
Descrierea metodei:
Iat o situaie concret: la ora de educaie fizic elevii trebuie s se aeze n ordinea cresctoare a
nlimii. Fiecare elev va numra ci colegi sunt mai mici ca nlime dect el. Astfel, dac un elev E
va ti c are 15 colegi mai mici dect el, atunci elevul E se va aeza pe poziia 16.
Metoda de sortare prin numrare const n urmtoarele:
Fie A un vector cu n elemente. Se va crea un vector NR astfel nct :
NR [i] = "numrul de valori din A mai mici dect A[i]".

Folosim un vector auxiliar C, n care vom prelua elementele sortate ale vectorului A. Fiecare
element A[i] va fi trecut n C n poziia NR [i] + 1. Pentru exemplul de mai sus, pentru elevul E, NR
[i] = 15, iar poziia pe care trebuie s-o ocupe E n vectorul sortat va fi 16, deci NR [i] + 1.
Program ATESTAT_2003_27_SORTARE_PRIN_NUMARARE ;
uses CRT;
const
nmax = 100;
type
vector = array [1..10] of integer;
var
A: vector;
i, n: integer;
procedure CITIRE (var A: vector; n: integer);
var
i:integer;
begin
for i:=1 to n do
begin

61

Probleme rezolvate de programare Subiecte propuse la ATESTAT


write ('Dati A [' , i, '] = ');
readln (A [i]);
end;
end;

62

Probleme rezolvate de programare Subiecte propuse la ATESTAT


procedure AFISARE (v: vector; m: integer);
begin
for i := 1 to m do
begin
writeln ('A [ ', i, ' ] = ', v [i])
end
end;
procedure ORDONARE (var A: vector; n: integer);
var
NR, C: vector;
j, i: integer;
begin
{Pentru fiecare element A[i] se numr n A cte elemente sunt mai mici dect
A [i]; numrul obinut n urma numrrii se trece n NR [i]}
for i := 1 to n do
NR [i] := 0;
for i := 2 to n do
begin
for j := 1 to i - 1 do
begin
if A [i] > A [j] then
NR [i] := NR [i] + 1
ELSE
NR [j] := NR [j] + 1;
End; { sfrit for interior}
end; {sfrit for exterior}
{Vom crea vectorul temporar C, n care se rein elementele n ordine cresctoare, i
apoi l vom copia n A. Dac A [i] are NR[i] elemente mai mici dect el, atunci, n
vectorul ordonat, A [i] va fi n poziia NR [i] + 1}.
for i := 1 to n do
C [ NR [i] + 1 ] := A [i];
{copiem n A elementele lui C}
for i:=1 to n do
A [i] := C [i];
end; {sfarsit procedura ORDONARE}
Begin

{ PROGRAM PRINCIPAL }
clrscr;
write ('Dati numarul de elemente ale vectorului, n = ');
readln (n);
CITIRE (A, n);
ORDONARE (A, n);
AFISARE (A, n);

end.

ATESTAT - 2003 - 28 - S se citeasc din fiierul VEC.TXT, vectorul V de ntregi i s se calculeze


apoi media aritmetic a elementelor pozitive.
Rezolvare:
Atenie ! Fiierul VEC.TXT trebuie s existe pe discul C: i s conin valori. Dac nu exist, l vom
crea, ca mai jos, dup care l vom accesa, citind din el ntregi, n condiiile problemei.
63

Probleme rezolvate de programare Subiecte propuse la ATESTAT


Program ATESTAT_2003_28 ;
VAR
f : file of integer;
Spoz, poz, x, v, n, i : integer;
Med : real;

64

Probleme rezolvate de programare Subiecte propuse la ATESTAT


Begin { PROGRAM PRINCIPAL }
ASSIGN (f, 'C:\VEC.TXT');
rewrite (f);
{ CREAREA lui VEC.TXT }
write ('Dati numarul de intregi din fisier, n = ');
readln (n);
writeln ('Introduceti elementele fisierului (pozitive si negative) ');
for i := 1 to n do
begin
write ('Dati un intregul al ', i, ' lea
readln (x);
write (f, x);
end;

x = ');

RESET (f);
{pregatire fisier pentru citire}
Spoz := 0; { initializare suma pozitive }
poz := 0;
while not EOF (f) do
begin
READ (f, v); { citesc o componenta din f }
if v > 0 then
begin
poz := poz + 1;
Spoz := Spoz + v;
end;
end;
if poz > 0 then
begin
Med := Spoz / poz;
writeln ('Media pozitivelor = ', Med);
end
else
writeln ('Nu exista numere pozitive');
readln
end.

ATESTAT - 2003 - 29 - S se calculeze maximul elementelor matricii A (m, n) i s se adauge la


sfritul fiierului text MAT.TXT.
Rezolvare: Vom folosi un algoritm cunoscut pentru determinarea maximului dintr-un ir de numere.
Program ATESTAT_2003_29 ;
CONST
nmax = 30;
TYPE
matrice = array [1..nmax, 1..nmax] of real;
VAR
A : matrice;
f : file of real;
m, n, i, j : integer;
x, Max : real;
Begin { PROGRAM PRINCIPAL }
ASSIGN (f, 'C:\MAT.TXT');
rewrite (f);
repeat

65

Probleme rezolvate de programare Subiecte propuse la ATESTAT


write ('Dati m = ');
readln (m)
until (m >= 1) AND (m <= nmax);

66

Probleme rezolvate de programare Subiecte propuse la ATESTAT


repeat
write ('Dati n = ');
readln (n)
until (n >= 1) AND (n <= nmax);
writeln ('Dati matricea');
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;
max := A [1,1];
for i := 1 to m do
begin
for j := 1 to n do
begin
if max < A [i, j] then
Max := A [i, j]
end;
end;
writeln ('Max = ', Max);
RESET (f);
while not EOF (f) do
begin
read (f, x)
end;
write (f, max);
RESET (f);
READ (f, x);
Max := x;
writeln ('Max citit din fisier este = ', max);
readln
end.

ATESTAT - 2003 - 30 - S se scrie la sfritul fiierului text DIV.TXT toi divizorii naturali ai
numrului ntreg x.
Rezolvare: Folosim algoritmul de verificare a primalitii unui numr ntreg.
Program ATESTAT_2003_30 ;
VAR
f : file of integer;
x, d, diviz : integer;
Begin { PROGRAM PRINCIPAL }
ASSIGN (f, 'C:\DIV.TXT');
rewrite (f);
write ('Dati x = ');
readln (x);
x := ABS (x); {daca x este negativ il facem > 0 }
diviz := 1;
while diviz <= x do
begin
if x MOD diviz = 0 then

67

Probleme rezolvate de programare Subiecte propuse la ATESTAT


write ( f, diviz );
diviz := diviz + 1
end;

68

Probleme rezolvate de programare Subiecte propuse la ATESTAT


RESET (f);
writeln ('Citim fisierul');
while not EOF (f) do
begin
read (f, d);
writeln ('Divizor = ', d)
end;
readln
end.

ATESTAT - 2003 - 31 - S se determine toate modalitile de plat a unei sume S (S >= 0 i


<= 1.000.000) cu bancnote de valoare dat: b1 = 1000, b2 = 5000, b3 = 10.000, b4 = 100.000.
Rezolvare:
Varianta 1
Program ATESTAT_2003_31_Bancnote_1_Platile_unei_sume_BackTracking ;
uses CRT;
VAR
s : array [0..20] of integer;
f, b : array [1..20] of integer;
{f [poz] = numarul de bancnote de tipul b [poz]}
nrsol, Suma, m, poz, i, j : integer; {m = numarul de tipuri de bancnote }
{poz = pozitia unei bancnote in suma}
Begin { PROGRAM PRINCIPAL }
clrscr;
nrsol := 0;
write ('Dati o suma < 1.000.000,
Suma = ');
readln (Suma);
write ('Cite tipuri de bancnote folositi, (la noi m = 4) m = ');
readln (m);
for i := 1 to m do
begin
write ('Dati valoarea bancnotei de tipul ',i, '
b [ ',i,' ] =');
readln (b[i])
end;
s[0] := 0;
f[1] := 0;
poz := 1;
while poz > 0 do
begin
while ( poz <= m ) AND ( f[poz] * b[poz] < Suma - s[poz-1] ) do
begin
f[poz] := f[poz] + 1;
s[poz] := s[poz-1] + f[poz] * b[poz];
IF s[poz] = Suma then
begin
if poz > 1 then
begin
nrsol := nrsol + 1;
writeln ('Solutia nr. ',nrsol);
write ( Suma,' = ',f[1],' * ',b[1]);
for j := 2 to poz do
begin
write (' + ', f[j],' * ',b[j])
end;

69

Probleme rezolvate de programare Subiecte propuse la ATESTAT


end
end

70

Probleme rezolvate de programare Subiecte propuse la ATESTAT


ELSE
begin
poz := poz + 1; {PAS INAINTE}
f[poz] := 0;
{f [poz] := f[poz-1] - 1; }
end
{ f[poz] >= f [poz-1] }
end; {sfarsit WHILE interior}
poz := poz-1;
{PAS INAPOI}
end; { sfarsit WHILE exterior}
readln
end.

Varianta 2
Program ATESTAT_2003_31_Bancnote_2_Platile_unei_sume_BackTracking;
type
stiva = array[1..100] of longint;
var
st, a, b: stiva;
n, k, s, i: Longint;
as, ev: boolean;
Procedure Init (k: integer; var st : stiva);
begin
st [k] := -1
End;
Procedure Succesor (var as: boolean; var st: stiva; k: integer);
var
s1, i: longint;
begin
if (st[k] < b[k]) and (k <= n) then
begin
s1 := 0;
for i:=1 to k do
s1 := s1 + st[i] * a[i];
as := (s1 < s)
end
else
as := false;
if as then
st[k] := st[k] + 1
End;
Procedure Valid (var ev: boolean; st: stiva; k: integer);
var i: integer;
begin
ev := true
End;
Function Solutie( k:integer): boolean;
var i, s1: longint;
begin
s1 := 0;
for i := 1 to k do
s1 := s1 + st[i]*a[i];
solutie := (s=s1)
End;
Procedure Scrie;
var i: integer;

71

Probleme rezolvate de programare Subiecte propuse la ATESTAT


begin
writeln (s,' lei se platesc cu:');

72

Probleme rezolvate de programare Subiecte propuse la ATESTAT


for i := 1 to k do
begin
if st [i]>0 then
writeln ( st [i]:2,' de ', a[i],' lei');
end;
writeln ('---------------------------------');
readln
End;
Begin

{ PROGRAM PRINCIPAL }
n := 4;
a[1] := 1000;
a[2] := 5000;
a[3] := 10000;
a[4] := 100000;
write ('Suma = ');

readln (s);

for i := 1 to n do
begin
b[i] := s div a[i]
end;
k := 1;
Init (k, st);
while (k > 0) do
begin
repeat
succesor (as, st, k);
if as then
valid (ev, st, k);
until (not as) or (as and ev);
if as then
if solutie (k) then
SCRIE
else
begin
k := k+1;
init (k, st);
end
else
k := k-1
end;
readln
END.

ATESTAT - 2003 - 32 - S se parcurg, prin sritura calului, o tabl de ah, netrecnd de dou ori prin
aceleai poziii sau omind o anumit poziie.
Rezolvare:
Program ATESTAT_2003_32_SARITURA_CALULUI ;
uses CRT;
CONST
mmax = 8; { nr. de linii }
nmax = 8; { nr. de coloane }
TYPE

73

Probleme rezolvate de programare Subiecte propuse la ATESTAT


matrice = ARRAY [1..mmax, 1..nmax] of integer; { matricea TABLEI DE SAH }

74

Probleme rezolvate de programare Subiecte propuse la ATESTAT


VAR
SOL : matrice; { SOL = matricea solutiilor }
{ SOL [i, j] = 0 daca nu s-a trecut prin pozitia (i, j) }
{
<> 0 daca s-a trecut prin pozitia (i, j) }
m, n, nrsol, i, j : integer;
procedure SCRIE;
begin
writeln;
writeln ('Apasati o tasta ');
writeln;

(i, j) = pozitia pe tabla de sah }

readln;
nrsol := nrsol + 1;
writeln ('Solutia ', nrsol, ' : ');
writeln;
for i := 1 to m do
begin
for j := 1 to n do
begin
write ( ' ', SOL [i, j] : 3,' ');
end;
writeln;
writeln;
end;
readln;
CLRSCR
end; { sfarsit procedura SCRIE }
procedure TRASEU (i, j, pas : integer);
begin
IF (i IN [1..m])
AND (j IN [1..n]) then
begin
if SOL [i, j] = 0 then
begin
SOL [i, j] := pas ;
if pas = m * n

then

SCRIE
else
begin
TRASEU (i-2,
TRASEU (i-1,
TRASEU (i+1,
TRASEU (i+2,
TRASEU (i+2,
TRASEU (i+1,
TRASEU (i-1,
TRASEU (i-2,
end;
SOL [i, j] := 0;
end;

75

j+1,
j+2,
j+2,
j+1,
j-1,
j-2,
j-2,
j-1,

pas
pas
pas
pas
pas
pas
pas
pas

+
+
+
+
+
+
+
+

1
1
1
1
1
1
1
1

);
);
);
);
);
);
);
);

Probleme rezolvate de programare Subiecte propuse la ATESTAT


end;
end; { sfarsit procedura }

76

Begin

Probleme rezolvate de programare Subiecte propuse la ATESTAT


{ PROGRAM PRINCIPAL }
CLRSCR;
write ('Dati numarul de linii ( cel putin 5),
m = ');
readln (m);
write ('Dati numarul de coloane ( egal cu numarul de linii ), n = ');
readln (n);
for i := 1 to m do
begin
for j := 1 to n do
begin
SOL [i, j] := 0
end;
end;
nrsol := 0;
CLRSCR;
TRASEU (1, 1, 1);
if nrsol = 0 then
writeln ('Nu exista solutie');
writeln;
readln

END.

ATESTAT - 2003 - 33 - S se parcurg n lime un graf neorientat.


Rezolvare:
Varianta 1: Algoritmul este descris n lucrarea Ctlin Tnase Note de curs, Ediia II, 2008.
Program ATESTAT_2003_33_Parcurgere_graf_in_latime_BF_Breadth_First ;
uses CRT;
VAR
VIZITAT : array [1..20] of 0..1;
{elementele vectorului VIZITAT sunt: }
{ = 1, daca un varf a fost vizitat}
{ = 0, in caz contrar}
A : array [1..20, 1..20] of integer; { A = matricea de adiacenta}
n : integer; { n = nr. de noduri }
m : integer; { m = nr. de muchii }
i, j : integer ; { i, j = indecsi }
v : integer; { v = varf curent }
x, y : integer; { x, y = extremitati ale unei muchii}
prim, ultim : integer;
{ pointeri catre "primul" / "ultimul" elem. al cozii}
C : array [1..20] of integer;
{ C = coada in care depunem varfurile nevizitate, vecine ale unui varf }
begin
CLRSCR;
writeln;
write ('Dati numarul de varfuri, n = ');

77

Probleme rezolvate de programare Subiecte propuse la ATESTAT


readln (n);
writeln;

78

Probleme rezolvate de programare Subiecte propuse la ATESTAT


write ('Dati numarul de muchii, m = ');
readln (m);
writeln;
for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0 {initializare elemente matrice de adiacenta cu 0}
end;
end;
writeln;
writeln ('Dati extremitatile muchiilor');
writeln;
for i := 1 to m do
begin
writeln ('Pentru muchia ', i,', dati extremitatile');
write ('Prima extremitate, x = ');
readln (x);
write ('A doua extremitate, y = ');
readln (y);
writeln;
A [x, y] := 1;
A [y, x] := 1;
end;
writeln;
write ('Dati varful de plecare, i = ');
readln (i);
writeln;
C [1] := i; {primul element din coada este varful de plecare}
for j := 1 to n do
begin
VIZITAT [j] := 0;
end;
prim := 1; {pointare catre primul element al cozii}
ultim := 1; {pointare catre ultimul element al cozii}
VIZITAT [i] := 1;
while prim <= ultim do
begin
v := C [prim] ;
for j := 1 to n do
begin
if (A [v, j] = 1) AND (VIZITAT [j] = 0) then
begin
ultim := ultim + 1;
{se depune un varf in coada in pozitia "ultim"}
C [ ultim ] := j;
VIZITAT [ j ] := 1;
end; {end IF }
end; {end FOR }

79

Probleme rezolvate de programare Subiecte propuse la ATESTAT


prim := prim + 1;
end;

{end WHILE}

80

Probleme rezolvate de programare Subiecte propuse la ATESTAT


writeln ('Lista nodurilor, in parcurgere BF, plecand din nodul ', i,', este :');
for j := 2 to ultim do
begin
write ( C [j],'
');
end;
readln
end.

Varianta 2:
Program ATESTAT_2003_33_Parcurgere_graf_in_latime_cu_procedura_recursiva ;
type mat = array [1..20, 1..20] of integer;
vect = array [1..20] of integer;
var v : mat;
t, coada : vect;
n, k, j, i, p : integer;

procedure PBF (i:integer); { Parcurgere Breadth First }


{procedura recursiva}
var j : integer;
begin
for j:=1 to n do
if ( v [coada [i],j] = 1 ) and ( t [j] = 0) then
begin
k := k+1;
coada [k] := j;
t[j] := 1 ;
end;
if i<n then
PBF (i+1);
end;
Begin

{ PROGRAM PRINCIPAL }
write('n = ');
readln(n);
for i := 1 to n do
begin
t[i] := 0;
for j := i+1 to n do
begin
write ('Legatura intre ',i,' si ',j,' = ');
readln (v[i,j]);
v[j,i] := v[i,j];
end;
end;
write ('Dati Nodul de plecare, p = ');
readln (p);
coada [1] := p;
t[p] := 1;
k := 1;

PBF (p);
for i:=1 to n do
write (coada[i],'->');
writeln;

81

Probleme rezolvate de programare Subiecte propuse la ATESTAT


readln
end.

82

Probleme rezolvate de programare Subiecte propuse la ATESTAT

ATESTAT - 2003 - 34 - S se determine un ciclu ntr-un graf astfel nct s se treac prin toate
punctele grafului, iar costul drumului s fie minim.
Rezolvare: Se folosete algoritmul cunoscut de determinare a unui ciclu ntr-un graf.
Program ATESTAT_2003_34_Graf_cost_minim ;
var
A: array [1..20,1..20] of integer; {matricea de adiacenta}
s: array [1..20] of integer;
n, i, j, v, v1, v2, min, cost: integer;
Begin

{ PROGRAM PRINCIPAL }
Write ('Dati numarul de noduri, n = ');
Readln (n);
writeln (Dati matricea de adiacenta A);
for i := 1 to n - 1 do
for j := i + 1 to n do
begin
write ('Dati A [ ', i, ', ',j,' ] = ');
readln ( A [i, j]);
A [j, i] := A [i, j]
end;
for i:=1 to n do
begin
S [i] := 0;
{matricea de adiacenta este patratica, avand toate}
A [i, i]:= 0
{elementele diagonalei principale egale cu zero }
end;
write ('Dati Nodul de pornire, v = ');
readln (v);
S [v] := 1;
v2 := v;
cost := 0;
writeln (v);
for i := 1 to n-1 do
begin
min := 30000;
for j := 1 to n do
if (A [v2, j] <> 0) and ( S [j] = 0) and ( min > A [v2, j]) then
begin
min := A [i, j];
v1 := j
end;
v2 := v1;
S [v2] := 1;
cost := cost + min;
write (v1, ' -> ');
end;
cost := cost + A [v2, v];
writeln (v);
writeln ('Cost total = ',cost);
readln

end.

83

Probleme rezolvate de programare Subiecte propuse la ATESTAT

84

Probleme rezolvate de programare Subiecte propuse la ATESTAT

ATESTAT - 2003 - 35 - S se afieze toate posibilitile de aranjare pe o caset a n melodii,


codificate cu numere de la 1 la n, astfel nct melodia X s urmeze dup melodia Y (x i y sunt dou
valori citite). Se consider n < 10.
Rezolvare:
Program ATESTAT_2003_35_Caseta_cu_melodii ;
uses crt;
const nmax = 100;
type
vector = array [1..nmax] of integer;
var
f : vector;
SOLUTII : TEXT; {fisier text de pe disc in care vom retine solutiile}
sol, n, i, x, y : 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
begin write ( f [i] : 3 ); write (SOLUTII, f [i] : 3 ); end;
writeln (SOLUTII);
writeln
{Linie de spatiere}
end;
function POZMELODIE (x, y : integer) : BOOLEAN;
Var
OK : boolean;
begin
OK := FALSE;
for i := 1 to n - 1 do
begin
if (f [i] = y) AND ( f [ i + 1 ] = x ) then
OK := TRUE;
end;
POZMELODIE := OK
end;
procedure PERMUTA ( m : integer );
LABEL
20;
var
k : integer;
CONTIN : boolean;

85

Probleme rezolvate de programare Subiecte propuse la ATESTAT


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; {sfarsit WHILE interior}
20:
if ( CONTIN = TRUE ) AND (k = n) then
begin
if POZMELODIE (x, y) = TRUE then
SCRIE;
end;
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; {sfarsit WHILE exterior}
end; {sfarsit procedura PERMUTA}
Begin

{ PROGRAM PRINCIPAL }
clrscr;
assign (SOLUTII, 'C:\SOLUTII.txt');
{Solutiile se vor scrie si in fisierul C:\SOLUTII.TXT}
rewrite (SOLUTII);
sol := 0;
1 2 4 3
write('Dati nr. de melodii ( < 10 )
n = ');
1 2 5 4
readln (n);
write ('Dati melodia nr. x = ');
1 4 3 2
readln (x);
1 4 3 5
write ('Dati melodia nr. y = ');
1 5 2 4
readln (y);
writeln;
PERMUTA (n);
if sol = 0 then
writeln ('Nu exista solutie');
readln

end.

De exemplu, pentru n = 5
X=3
Y=4
se vor afia pe ecran
(respectiv se vor scrie n fiierul C:\SOLUTII.TXT)
soluiile:

86

1
2
2
2
2
2
2
4
4
4
4
4
4
5
5
5
5
5

5
1
1
4
4
5
5
3
3
3
3
3
3
1
1
2
2
4

4
4
5
3
3
1
4
1
1
2
2
5
5
2
4
1
4
3

3
3
4
1
5
4
3
2
5
1
5
1
2
4
3
4
3
2

5
3
5
2
3
2
5
3
5
1
3
1
5
2
5
1
2
1
3
2
3
1
1

Probleme rezolvate de programare Subiecte propuse la ATESTAT

87

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