Documente Academic
Documente Profesional
Documente Cultură
ATESTAT - 2003 - 1 - Se citesc numere naturale până la introducerea a două numere consecutive
egale. Afişaţi 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 enunţului, dacă “se citesc numere”, nu se ştie de la început “câte” (nu se dă un “n” =
numărul de numere ce se vor citi), deci va trebui să le numărăm cu un contor “i”.
Numerele pe care le vom introduce vor fi preluate într-un vector X.
Definim o funcţie 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 }
Rezolvare:
Două numere sunt prime între ele dacă CMMDC al celor două numere este 1 (vezi problema anterioară).
Introducem primul număr, notat cu “x”. Verificăm dacă “x” este prim cu 12 şi dacă DA, oprim algoritmul;
dacă nu, verificăm dacă este prim cu suma cifrelor sale.
Pentru că vom introduce mai multe numere, dar nu ştim de la început câte anume, introducerea
următoarelor numere se va face într-un ciclu WHILE.
Definim o funcţie CMMDC pentru a calcula CMMDC al două numere.
Definim o funcţie NUMARACIFRE, pentru a număra cifrele unui număr natural.
Definim o procedură DETCIFRE, care determină cifrele unui număr şi le depune într-un vector.
Definim o funcţie SUMACIFRE, care însumează cifrele unui număr.
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;
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 }
S := SUMACIFRE (x);
ATESTAT - 2003 - 3 - Fie x un număr natural. Stabiliţi care este factorul prim care, în
descompunerea lui x, apare la puterea maximă.
Rezolvare:
Notăm cu “d” un posibil divizor al lui “x”. Evident, d poate lua valori consecutive începând de la
2 până la x, dar nu orice valoare între 2 şi x este şi divizor al lui x.
Contorul “nr” numără de câte ori x se împarte exact la un d >= 2.
După fiecare împărţire exactă a lui x la d, noul x devine x DIV d. Repetăm (într-un ciclu
WHILE) aceste calcule atât timp cât x > 1.
5
Probleme rezolvate de programare – Subiecte propuse la ATESTAT
Plecăm 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 iniţializa d cu 1, în urma atribuirii x := x DIV d, noua valoare a lui x ar
rămâne întotdeauna = x, deci divizorul d = 1 s-ar număra de o infinitate de ori (găsindu-l pe 1 ca
divizor de o infinitate de ori, nu s-ar mai trece niciodată la d = 2, prin atribuirea d := d + 1).
Reţinem în variabila ”max” cel mai mare număr de împărţiri ale lui “x” la un divizor “d”.
Notăm cu ”divizor” divizorul pentru care numărul de împărţiri 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);
while x > 1 do
begin
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 rând n numere naturale. Afişaţi-le pe cele care sunt termeni ai
şirului lui Fibonacci.
Rezolvare:
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;
j := 3;
ATESTAT - 2003 - 5 - Se citesc pe rând n numere naturale. Afişaţi perechile de numere citite
succesiv, care sunt termeni ai şirului lui Fibonacci.
Rezolvare:
Definim funcţia VERIFICA, pentru a testa dacă un număr este termen FIBONACCI.
Numerele pe care le introducem se vor reţine î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;
VERIFICA := OK;
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:
Notăm cu a, b, c, d, e cifrele numărului x.
Verificarea se va face pentru toate numerele x cuprinse între 20000 şi 88888.
Se defineşte o funcţie CIFREPARE, care verifică dacă toate cifrele numărului 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.
Rezolvare:
Notăm cu a, b, c, d, e, f cifrele numărului x.
Definim funcţia VERIFICA (x), care determină cifrele lui x si apoi face verificările 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;
ATESTAT - 2003 - 8 - Să se determine toate cuvintele de 5 litere ce conţin măcar două vocale şi au
a 2-a literă “m”.
Rezolvare:
Generăm cuvintele folosind un şir de caractere “cuvant” de lungime = 5.
Pe poziţia 2 din “cuvant” va fi întotdeauna litera “m”, deci cuvant [2] := 'm'.
Pe celelalte 4 poziţii (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 poziţiile 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 poziţie din şirul “cuvant” testăm dacă pe poziţia respectivă se află o vocală şi dacă
DA, numărăm acea vocală, folosind contorul nrvocale.
După generarea unei combinaţii de vocale şi consoane care compun un cuvânt (la sfârşitul buclei
FOR de la interior), testăm dacă nrvocale >= 2 şi dacă DA, numărăm cuvântul care satisface
condiţiile problemei (majorăm contorul “i”) şi afişăm cuvântul.
La începutul buclei “FOR” situate cel mai interior, trebuie să iniţializăm, de fiecare dată,
contorul care numără vocalele, scriind nrvocale := 0;
Program ATESTAT_2003_8 ;
uses crt;
var
cuvant : string;
i, nrvocale : integer;
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 numără 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 afişeze toate matricile pătratice n x n care conţin pe fiecare linie şi
coloană un singur 1, în rest 0.
Rezolvare:
Această problemă este asemănătoare cu “problema celor n regine”, pe care o vom adapta la
cerinţele 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 încît oricare două regine să nu se atace. Pentru
ca două regine să nu se atace, ele trebuie să nu fie situate pe aceeaşi linie, pe aceeaşi coloană sau pe
aceeaşi diagonală. La noi, rolul reginelor va fi jucat de elementele egale cu 1 din matricea pătratică n x
n. În cazul problemei noastre, vom renunţa la cerinţa ca elementele matricii egale cu 1 să nu fie plasate
pe aceeaşi diagonală. Pe fiecare linie trebuie să fie plasată cîte o regină. Deci, pentru ca poziţia reginelor
să fie complet determinată, este suficient să reţinem, pentru fiecare regină, coloana în care este plasată,
într-un vector soluţie f, de dimensiune n, unde f [i] reprezintă coloana în care este plasată regina de pe
linia i. Generarea matricilor în condiţiile problemei se face apelând la un algoritm “backtracking”.
Observaţii:
Notăm cu x, respectiv i o linie oarecare şi cu f [x], respectiv f [i], coloana pe care se găseşte
regina de pe linia x, respectiv linia i.
Condiţiile interne:
a). f [x] = 1, 2, ..., n, pentru oricare x = 1, 2, ..., n
b). Două regine nu pot fi plasate pe aceeaşi coloană se va exprima analitic astfel:
f [x] ≠ f [y] pentru orice x ≠ y, cu x, y = 1, 2,...,n.
Definim o procedură AFIŞARE astfel:
11
Probleme rezolvate de programare – Subiecte propuse la ATESTAT
În momentul apelării procedurii, este evident că s-a găsit o soluţie pe care o numărăm scriind:
Nrsol := Nrsol + 1
şi apoi afişăm Nrsol.
Vom parcurge toate coloanele de la 1 la n. Pentru aceasta avem nevoie de un contor poziţional
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 găseşte regina de pe linia lin.
Procedura va tipări " * " dacă pe coloana curentă col există o regină, adică atunci când col
= f [lin], şi va tipări "o" dacă această condiţie nu este satisfăcută.
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 }
nrsol:=0;
x := 1; { virful stivei }
f [x] := 0;
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 permutările mulţimii {1, 2,... n} cu condiţia ca orice
două numere alăturate ale unei permutării să fie prime între ele.
Rezolvare:
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 SCRIE ;
begin
sol := sol + 1;
for i := 1 to n do
begin
write ( f [i] : 3 )
end;
writeln
end;
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; {sfârşit WHILE exterior}
end; {sfârşit procedură PERMUTA}
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 aparţin {1, 2,... 10}
obţinute la n examene, astfel încât punctajul obţinut să fie minim.
Rezolvare:
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;
16
Probleme rezolvate de programare – Subiecte propuse la ATESTAT
ATESTAT - 2003 - 12 - Afişaţi numere prime mai mici decât un număr “n” citit de la tastatură,
care rămân prime şi după ce au fost inversate.
Rezolvare:
Definim o funcţie PRIM, cu rezultat de tip BOOLEAN, care testează dacă un număr este prim.
Definim o funcţie INVERS care inversează elementele unui şir.
În programul principal, înainte de a inversa un număr x, îl transformăm mai întâi într-un şir cu
funcţia STR.
După inversare, transformăm şirul obţinut într-un număr cu funcţia VAL.
Testăm dacă numărul obţinut prin inversare este şi el prim.
Program ATESTAT_2003_12 ;
uses crt;
var
inversul, sir : string;
a, b, i, x, n, invx : integer;
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.
Rezolvare:
Definim funcţia CMMDC cu care calculăm CMMDC al două numere.
Calculăm CMMDC al primelor două numere din vector (x1 si x2) şi îl notăm cu C[1].
Începând de la i = 2 până la n, facem atribuirile:
x [i] := C [i-1];
C [i] := CMMDC ( x [i], x [i+1] )
Altfel spus, calculăm CMMDC dintre CMMDC-ul anterior şi următorul 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;
while R <> 0 do
begin
A := B;
B := R;
R := A MOD B
end;
CMMDC := B
end; { sfarsit functie CMMDC }
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;
for i := 2 to n-1 do
begin
x [i] := C [i-1];
C [i] := CMMDC ( x [i], x [i+1] )
end;
readln
end.
Rezolvare:
Definim o funcţie NRCIFRE pentru a număra cifrele unui număr natural.
Definim o funcţie PALINDROM în care:
- determinăm numărul de cifre pentru un număr natural;
- extragem din numărul natural cifrele şi le depunem într-un vector “y”;
- verificăm dacă vectorul “y” este simetric (PALINDROM).
În programul principal, apelăm funcţia PALINDROM pentru toate numerele naturale dintre A
şi B şi le afişăm 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;
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;
readln
end.
ATESTAT - 2003 - 15 - Se citeşte 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 tipări 5.
Rezolvare:
Numerele întregi introduse vor fi reţinute într-un vector x.
Numerele întregi introduse pot fi pozitive, negative sau nule. Evident, suma cea mai mare ce se
poate obţine din întregul şir de numere va rezulta prin însumarea doar a numerelor pozitive.
Notăm cu Spoz suma numerelor strict pozitive. Într-o buclă FOR, vom adăuga la această sumă
câte 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;
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 – Interschimbaţi coloanele unei matrici cu m linii şi n coloane astfel încât,
în linia k, elementele să fie ordonate crescător.
Rezolvare:
Ordonăm linia “k”. În cursul procesului de ordonare, o parte din elementele liniei “k” se
interschimbă între ele.
În paralel cu ordonarea, interschimbăm şi coloanele corespunzătoare elementelor de pe linia “k”
supuse interschimbărilor.
Program ATESTAT_2003_16 ;
uses crt;
VAR
OK, m, n, i, j, k : integer;
A : array [1..100, 1..100] of integer;
aux : integer;
write('Dati m = ');
readln (m);
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;
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 citeşte un text şi o succesiune de caractere. De câte ori întâlnim această
succesiune în cadrul textului ?
Rezolvare:
Apelăm funcţia POS (subşir, şir) şi determinăm poziţia unde apare subşir în şir.
Dacă poziţia determinată este <> 0, atunci majorăm contorul nrapariţii, care numără apariţiile
subşirului în şir.
De asemenea, dacă poziţia determinată este <> 0, ştergem din şirul dat caracterele, de la poziţia
1, pe o lungime = poziţia + LENGTH (subşir) – 1, unde poziţia este valoarea determinată cu
funcţia 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.
Rezolvare:
Problema reginelor cere să se plaseze n regine pe o tablă de şah de dimensiune n x n astfel încît
oricare două regine să nu se atace. Pentru ca două regine să nu se atace, ele trebuie să nu fie situate pe
aceeaşi linie, pe aceeaşi coloană sau pe aceeaşi diagonală. Pe fiecare linie trebuie să fie plasată cîte o
regină. Deci, pentru ca poziţia reginelor să fie complet determinată, este suficient să reţinem, pentru
fiecare regină, coloana în care este plasată, într-un vector soluţie f, de dimensiune n, unde f [i]
reprezintă coloana în care este plasată regina de pe linia i. Generarea matricilor care afişează poziţiile
reginelor, în condiţiile problemei, se va face apelând la un algoritm “backtracking”.
Observaţii:
Notăm cu x, respectiv i o linie oarecare şi cu f [x], respectiv f [i] coloana pe care se găseşte
regina de pe linia x, respectiv linia i.
Condiţiile interne:
a). f [x] = 1, 2, ..., n, pentru oricare x = 1, 2, ..., n
b). Condiţia “două regine nu pot fi plasate pe aceeaşi 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 aceeaşi diagonală. Dacă regina de pe linia i, coloana f [i] este pe
aceeaşi 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ă, condiţia “două regine nu pot fi plasate pe aceeaşi
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ă AFIŞARE astfel încât:
În momentul apelării procedurii, evident s-a găsit o soluţie pe care o numărăm scriind:
Nrsol := Nrsol + 1
şi apoi afişăm Nrsol.
Vom parcurge toate coloanele de la 1 la n. Pentru aceasta avem nevoie de un contor poziţional 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
găseşte regina de pe linia lin.
Procedura va tipări " * " dacă pe coloana curentă col există o regină, adică atunci când
col = f [lin], şi va tipări "o" dacă această condiţie nu este satisfăcută.
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 }
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.
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 = vârful stivei }
f [poz] := 0 ;
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” alăturate. Numărul “n” (0 < n < 13) se citeşte de la
tastatură. Fiecare şir va fi scris pe câte un rând al ecranului fără spaţiu între litere.
Rezolvare:
Problema constă în generarea produsului cartezian al mulţimilor de caractere. Generarea
combinaţiilor 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 mulţimi implicate în acest produs. Cum pe noi ne interesează
combinaţiile de litere “a” şi “m”, vom asocia unui număr din câte o mulţime o literă, astfel:
dacă f [i] = 1, atunci sir [i] = ‘a’
dacă f [i] = 2, atunci sir [i] = ‘m’.
Nu ne interesează decât aceste valori ale lui f [i].
Procedura SCRIE se va apela în mod opţional, pentru a observa modul de generare a produsului
cartezian în varianta sa numerică.
Procedura SCRIETEXT va afişa doar combinaţiile de litere “a” şi “m”.
Funcţia booleană VECINI testează dacă avem litera “a” pe două poziţii vecine.
Funcţia booleană EXISTĂ verifică dacă în şir există şi cifra 1. În acest fel se vor elimina
combinaţiile care nu-l conţin pe 1 (adică acele combinaţii de litere care nu conţin litera “a” şi
care, deci, nu ne interesează).
Vectorul “nrelem” reţine numărul de elemente al fiecărei mulţimi din produsul cartezian.
“Poz” = poziţia unui element într-o mulţime 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 opţională}
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.
Rezolvare:
Aplicând algoritmul BACKTRACKING, vom genera permutările 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;
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 afişeze termenii şirului lui Fibonacci, pentru un “n” dat.
Rezolvare:
Termenii şirului vor fi reţinuţi î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;
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 crescător
folosind metoda bulelor.
Rezolvare:
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;
for i := 1 to n do
begin
write ('a [i] = ');
readln (a [i] )
end;
writeln;
readln;
clrscr;
writeln;
writeln;
readln
end.
ATESTAT - 2003 - 24 - Fie A şi B doi vectori cu câte m, respectiv n elemente numere întregi
(m > 0, n > 0), ordonaţi crescător. 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;
k := 0;
i := 1;
j := 1;
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 găseşte î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}
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);
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 jumătate a vectorului, apoi
pentru cea de-a doua jumătate, 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;
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 crescător
folosind metoda sortării prin numărare.
Rezolvare:
Descrierea metodei:
Iată o situaţie concretă: la ora de educaţie fizică elevii trebuie să se aşeze în ordinea crescătoare a
înălţimii. Fiecare elev va număra câţi colegi sunt mai mici ca înălţime decât el. Astfel, dacă un elev
“E” va şti că are 15 colegi mai mici decât el, atunci elevul “E” se va aşeza pe poziţia 16.
Metoda de sortare prin numărare constă în următoarele:
Fie A un vector cu n elemente. Se va crea un vector NR astfel încât :
NR [i] = "numărul de valori din A mai mici decât 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 poziţia NR [i] + 1. Pentru exemplul de mai sus, pentru elevul “E”,
NR [i] = 15, iar poziţia 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 numără în A câte elemente sunt mai mici
decât A [i]; numărul obţinut în urma numărării 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; { sfârşit for interior}
end; {sfârşit for exterior}
for i := 1 to n do
C [ NR [i] + 1 ] := A [i];
Rezolvare:
Atenţie ! Fişierul VEC.TXT trebuie să existe pe discul C: şi să conţină valori. Dacă nu există, îl
vom crea, ca mai jos, după care îl vom accesa, citind din el întregi, în condiţiile 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);
for i := 1 to n do
begin
write ('Dati un intregul al ', i, ' lea x = ');
readln (x);
write (f, x);
end;
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 sfârşitul fişierului text DIV.TXT toţi divizorii naturali ai
numărului întreg x.
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.
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 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;
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 săritura calului, o tablă de şah, netrecând de două ori
prin aceleaşi poziţii sau omiţând o anumită poziţie.
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) }
readln;
nrsol := nrsol + 1;
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 }
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;
if nrsol = 0 then
writeln ('Nu exista solutie');
writeln;
readln
END.
Rezolvare:
Varianta 1: Algoritmul este descris în lucrarea Cătălin Tănase – Note de curs, Ediţia 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}
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}
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;
for j := 1 to n do
begin
VIZITAT [j] := 0;
end;
VIZITAT [i] := 1;
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;
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 ;
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 încât să se treacă prin toate
punctele grafului, iar costul drumului să fie minim.
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 afişeze toate posibilităţile de aranjare pe o casetă a “n” melodii,
codificate cu numere de la 1 la n, astfel încât 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 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;
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}
48