Sunteți pe pagina 1din 46

Probleme rezolvate de programare Subiecte propuse la ATESTAT - 2003

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');
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;
NUMARACIFRE := nrcif;
end; { sfarsit functie NUMARACIFRE }

4
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 = '); {Introducerea primului numr}
readln ( x );

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 = '); {Introducerea urmtoarelor numere}


readln ( x );
end;
readln;
end.

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.
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.

5
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.
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.

6
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; {iniializarea primilor termeni ai irului}


FIBO [2] := 1;

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; {sfarsit bucla exterioar}


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

7
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.
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.

8
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;
b := v MOD 10;
w := v DIV 10;
a := w MOD 10;

9
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 }


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

10
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:
f [x] f [y] pentru orice x y, cu x, y = 1, 2,...,n.
Definim o procedur AFIARE astfel:

11
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 n = ');
readln (n);

nrsol:=0;
x := 1; { virful stivei }
f [x] := 0;

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;
ok := true;

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

13
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
begin
OK := TRUE;

14
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 PRINCIPAL }


clrscr;

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.

15
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}
end;
readln
end.

16
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 PRINCIPAL }


clrscr;

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

for x := 1 to n do
begin
STR (x, sir);
inversul := INVERS (sir);
VAL (inversul, a, b);
invx := a;

17
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 }


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

18
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 A
i 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;
NRCIFRE := nrcif
end;

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

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

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

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 PRINCIPAL }


clrscr;

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

write ('Dati n = ');


readln (n);
writeln;

write ('Dati linia k = ');


readln (k);
writeln;

21
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.

22
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]|
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

23
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 n = ');
readln (n);
nrsol:=0;
x := 1; { virful stivei }
f [x] := 0;

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
f [x] := f [x] + 1;

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

25
Probleme rezolvate de programare Subiecte propuse la ATESTAT
poz := 1; {poz = vrful stivei }
f [poz] := 0 ;

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.

26
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
write ('Cate elemente are multimea ',i,' : ');
readln ( nrelem [i] );
end;

27
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:
end;

28
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 PRINCIPAL }


clrscr;

sol := 0;

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

writeln;

PERMUTA (n);

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

readln
end.

29
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
k:= 0;
j := 1;

30
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
(m > 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;
vectortot = array [1..2*nmax] of integer;

31
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, m = ');
readln (m);

write ('Dati numarul de elemente ale vectorului b, n = ');


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 <= m do
begin
k := k + 1;
C [k] := A [i];
i := i + 1
end;

WHILE j <= n do
begin
k := k + 1;
C [k] := B [j];
j := j + 1
end;

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

33
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
if sf - incep = 1 then
DIVCOM := CMMDC ( x [incep], x [sf] )

34
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
write ('Dati A [' , i, '] = ');
readln (A [i]);
end;
end;

35
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.
Program ATESTAT_2003_28 ;
VAR
f : file of integer;
Spoz, poz, x, v, n, i : integer;
Med : real;
36
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 x = ');
readln (x);
write (f, x);
end;

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
write ('Dati m = ');
readln (m)
until (m >= 1) AND (m <= nmax);

37
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
write ( f, diviz );
diviz := diviz + 1
end;

38
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


S <= 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;
end
end

39
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;
begin
writeln (s,' lei se platesc cu:');

40
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
matrice = ARRAY [1..mmax, 1..nmax] of integer; { matricea TABLEI DE SAH }

41
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; { (i, j) = pozitia pe tabla de sah }


procedure SCRIE;
begin
writeln;
writeln ('Apasati o tasta ');
writeln;

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, j+1, pas + 1 );
TRASEU (i-1, j+2, pas + 1 );
TRASEU (i+1, j+2, pas + 1 );
TRASEU (i+2, j+1, pas + 1 );
TRASEU (i+2, j-1, pas + 1 );
TRASEU (i+1, j-2, pas + 1 );
TRASEU (i-1, j-2, pas + 1 );
TRASEU (i-2, j-1, pas + 1 );
end;
SOL [i, j] := 0;
end;
end;
end; { sfarsit procedura }

42
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { 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 = ');
readln (n);
writeln;

43
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 }

prim := prim + 1;

end; {end WHILE}

44
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;
readln
end.

45
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.

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

47
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;
write('Dati nr. de melodii ( < 10 ) n = '); 1 2 4 3 5
readln (n); 1 2 5 4 3
write ('Dati melodia nr. x = '); 1 4 3 2 5
readln (x); 1 4 3 5 2
write ('Dati melodia nr. y = '); 1 5 2 4 3
readln (y);
1 5 4 3 2
writeln; 2 1 4 3 5
2 1 5 4 3
PERMUTA (n); 2 4 3 1 5
if sol = 0 then
2 4 3 5 1
writeln ('Nu exista solutie'); 2 5 1 4 3
readln 2 5 4 3 1
end. 4 3 1 2 5
4 3 1 5 2
De exemplu, pentru n = 5 4 3 2 1 5
X=3 4 3 2 5 1
Y=4 4 3 5 1 2
se vor afia pe ecran 4 3 5 2 1
(respectiv se vor scrie n fiierul C:\SOLUTII.TXT) 5 1 2 4 3
soluiile: 5 1 4 3 2
5 2 1 4 3
5 2 4 3 1
5 4 3 2 1

48

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