2004
Pentru anul 2004, am inclus n lucrarea de fa doar problemele noi, care nu au fost propuse i n 2003 la
examenul de atestat.
ATESTAT - 2004 - 4 - Se citesc pe rnd numere naturale pn la introducerea lui 55. Stabilii cte
cifre de zero i cte cifre de 1 sunt necesare pentru reprezentarea n baza 2 a tuturor numerelor
anterioare.
Rezolvare:
Din enun nu rezult, n mod necesar, c numerele naturale introduse sunt consecutive. Prin
urmare, se pot introduce numere naturale la ntmplare, numrul acestor numere nefiind precizat.
Introducerea se va ncheia la ntlnirea numrului 55. O variant simplificat a problemei const
n introducerea tuturor numerelor naturale ntre 1 i 55. Vom lua n consideraie ambele situaii.
Pentru transformarea numrului ZECIMAL n numr BINAR, mprim numrul ZECIMAL la
2 i reinem resturile obinute la mprire ntr-un vector de resturi R. Numrul BINAR
echivalent se obine citind vectorul R de la sfrit ctre nceput. Pe noi ne intereseaz doar cifrele
numrului BINAR, deci este suficient s numrm cifrele de ZERO i de UNU din vectorul R
asociat numrului BINAR.
Definim o procedur TRANSFORMA, care convertete fiecare numr natural (zecimal)
introdus din n numr binar. Procedura va avea ca parametru de ieire vectorul de resturi R, dar
i numrul de cifre n ale numrului binar echivalent, adic numrul de elemente din R.
n procedur, folosim o variabil auxZECIMAL, ale crei valori vor evolua ntre
NRZECIMAL i 1, pe msur ce auxZECIMAL va fi mprit la 2. Folosind auxZECIMAL,
vom conserva (vom pstra neschimbat) valoarea lui NRZECIMAL.
Folosim doi contori zero i unu, care numr cifrele de 0 i de 1 din numrul binar obinut.
Program ATESTAT_2004_4_NUMARA_CIFRE_BINARE;
uses CRT;
Const
nmax = 100;
TYPE
vector = array [1..100] of integer;
VAR
NRZECIMAL, auxZECIMAL, zero, unu, n, i, rest: integer;
R : vector; {vector de resturi}
procedure TRANSFORMA (NRZECIMAL : integer; VAR R : vector; VAR n : integer);
begin
if NRZECIMAL = 0 then
begin
auxZECIMAL := 0;
i:=1;
R[i] := 0
end
else
begin
i := 0;
auxZECIMAL := NRZECIMAL;
while auxZECIMAL <> 1 do
begin
rest := auxZECIMAL MOD 2;
i := i + 1;
R [i] := rest;
auxZECIMAL := auxZECIMAL DIV 2;
end;
i := i + 1;
R [i] := auxZECIMAL;
end;
n := i;
end; {sfarsit procedura}
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Programul principal se va scrie astfel:
Varianta A Dac numerele naturale se introduc ntr-o ordine oarecare, pn la introducerea lui
55, atunci vom folosi o structur REPEAT:
Begin { PROGRAM PRINCIPAL }
clrscr;
zero := 0; {initializare contori care numara cifrele de zero si de unu}
unu := 0;
writeln;
REPEAT
write ('Dati urmatorul numarul zecimal = ');
readln (NRZECIMAL);
writeln;
write ('Numarul binar echivalent lui ', NRZECIMAL,' este ');
for i := n DOWNTO 1 do
write (R[i]);
writeln;
writeln;
for i := 1 to n do
begin
if R [i] = 0 then
zero := zero + 1
else
unu := unu + 1
end;
Varianta B Dac numerele naturale introduse sunt cuprinse ntre 1 i 55, vom folosi o structur
FOR:
begin { PROGRAM PRINCIPAL }
clrscr;
zero := 0; {initializare contori care numara cifrele de zero si de unu}
unu := 0;
writeln;
FOR NRZECIMAL := 1 to 55 do
begin
TRANSFORMA (NRZECIMAL, R, n);
writeln;
write ('Numarul binar echivalent lui ', NRZECIMAL,' este ');
for i := n DOWNTO 1 do
write (R[i]);
writeln;
writeln;
4
Probleme rezolvate de programare Subiecte propuse la ATESTAT
for i := 1 to n do
begin
if R [i] = 0 then
zero := zero + 1
else
unu := unu + 1
end;
Pe fiecare linie vom plasa cte un rege. Pentru ca poziia regilor s fie complet determinat, este
suficient s reinem, pentru fiecare rege, coloana n care este plasat, ntr-un vector soluie f, de
dimensiune n, unde f [i] reprezint coloana n care este plasat regele de pe linia i. Generarea matricilor
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
regele de pe linia x, respectiv linia i.
Condiiile interne:
a). f [x] = 1, 2, ..., n, pentru oricare x = 1, 2, ..., n
b). Doi regi nu pot fi plasai pe aceeai coloan se va exprima analitic astfel:
f [x] f [y] pentru orice x y, cu x, y = 1, 2,...,n.
c). Celelalte condiii interne sunt inserate i comentate direct n program.
Definim o procedur AFIARE astfel:
n momentul apelrii procedurii, este clar 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 regele de pe linia lin.
Procedura va tipri " * " dac pe coloana curent col exist un rege, adic atunci cnd
col = f [lin], i va tipri "o" dac aceast condiie nu este satisfcut.
5
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Program ATESTAT_2004_17_ASEZARE_REGI;
uses crt;
const
nrmaxregi = 8;
type
vectorsolutie = array [0..nrmaxregi] of 0..nrmaxregi;
var
f : vectorsolutie;
n, x, i : 0 .. nrmaxregi;
ok : boolean;
nrsol : word;
cond1, cond2, cond3, cond4, COND : boolean;
procedure AFISARE;
var
i, j : 0 ..nrmaxregi; {i = linie, j = coloana, f[i] = coloana }
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 }
nrsol:=0;
for i := 1 to x do
begin
cond1 := (f[i] = f[x]) and (ABS(x-i) = 1) ;
{Daca sunt pe aceeasi coloana, fi=fx}
{dar pe linii vecine, adica x-i=1}
6
Probleme rezolvate de programare Subiecte propuse la ATESTAT
and (ABS (i-x) =1 ) ;
{Daca sunt pe diagonala, i-x=fi-fx}
{la distanta de 1 casuta, i-x=1}
{ cond2 := ABS (f[i] - f[i-1]) = 1 ; }
{Daca sunt pe diagonala, }
{la distanta de 1 casuta }
{ cond3 := ABS (f[x] - f[x-1]) = 1 ; }
{sau ((ABS (f[i]-f[x]) = 1) and (x=i) ) }
ATESTAT - 2004 - 18 - Se d un fiier text care conine pe prima linie numere naturale. S se
afieze numrul valorilor din fiier i valoarea maxim a acestora.
Rezolvare:
n ipoteza c fiierul text nu exist deja pe disc, vom crea acest fiier cu acelai program care face
i celelalte determinri cerute de enun. Vom introduce n fiierul text n numere naturale,
folosind o bucl FOR, astfel:
Dup citirea de la tastatur a unui numr x, l vom converti ntr-un ir, prin apelarea
procedurii STR.
Dup fiecare astfel de ir, vom lsa un singur spaiu liber (blank). n acest fel, se va crea
o linie n fiierul text. Evident, linie este tot un i de caractere.
Celelalte etape sunt comentate direct n program.
Program ATESTAT_2004_18_FISIER_TEXT_CU_NUMERE_NATURALE;
const
nmax = 100;
type
vector = array [1..nmax] of integer;
var
f : text;
linie, sir : string; {linie = o linie din fisierul text}
{sir = sirul in care se transforma numarul x cu STR }
poz : integer; {pozitie in sirul de caractere "linie"}
ER : integer; {variabila EROARE = parametru al procedurii VAL}
c : char;
max, n, i, x : integer;
V : vector;
7
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
assign (f, 'c:\naturale.txt');
rewrite (f);
n := 10;
for i := 1 to n do
begin
write ('Dati un nou x = ');
readln (x);
STR (x, sir); {procedura STR transforma numarul x in sir}
write (f, sir + ' '); {se lasa un spatiu dupa fiecare sir}
end;
writeln (f); {incheie linia in fisierul f }
writeln;
writeln ('Continutul fisierului f este:');
while poz <= LENGTH (linie) do {cat timp linia nu a fost epuizata}
begin
IF linie [poz] <> ' ' then {daca in pozitia poz nu este un blank}
sir := sir + linie [poz] {reconstituim un numar din cifrele sale}
{folosind un sir in care depunem}
{prin concatenare cifrele numarului}
else {daca s-a ajuns la un blank, inseamna ca s-au parcurs }
{deja cifrele unui numar}
begin
i := i + 1; { numaram sirul care contine numarul}
VAL (sir, x, ER); {convertim sirul in numarul x}
V [i] := x; {preluam numarul x in vectorul V}
writeln ('V[',i,'] = ', V[i] ); {optional, afisam V[i] }
sir := '' ; {reinitializam sir cu sirul vid,}
{in eventualitatea}
{ca inca nu s-a epuizat fisierul si mai sunt }
{numere de extras din fisier}
end; {sfarsit ELSE}
poz := poz + 1 {trecem la urmatoarea pozitie din "linie"}
end; {sfarsit WHILE}
n := i; {retinem in "n" ultima valoare a contorului "i" }
{deci n = numarul total de numere extrase din "linie"}
writeln (Fisierul contine n = , n, numere naturale);
writeln;
writeln ('Vectorul V este: '); {optional, afisam vectorul}
for i := 1 to n do
begin
writeln ('V[',i,'] = ', v[i]);
end;
8
Probleme rezolvate de programare Subiecte propuse la ATESTAT
writeln;
{determinam numarul maxim din vector, deci din fisier}
max := V[1];
for i:= 2 to n do
begin
if max < v[i] then
max := v[i]
end;
writeln;
writeln ('Numarul maxim din fisier este MAX = ', max);
readln
end.
ATESTAT - 2004 - 19 - S se scrie un program recursiv care calculeaz maximul elementelor unui
vector cu n componente.
Rezolvare:
Definim o funcie recursiv denumit MAXIM, cu care vom determina maximul ntr-un interval
din vector cuprins ntre dou valori notate cu ncep, respectiv sf. Funcia va fi apelat iniial
pentru ncep = 1 i sf = n (poziiile extreme din vectorul x).
Dac sf ncep <> 1, se determina mijlocul intervalului sf ncep i se apeleaz funcia
MAXIM pentru jumtatea stng, respectiv dreapt a intervalului al crui mijloc a fost calculat.
Se determin, astfel, dou maxime, notate m1 i m2, pentru cele dou subintervale. n final, va fi
validat cea mai mare dintre valorile determinate.
Program ATESTAT_2004_19_Determinare_MAXIM_RECURSIV_DEI;
uses CRT;
type
vector = array [1..10] of integer;
VAR
x : vector;
MAX, n, i : integer;
function MAXIM ( incep, sf : integer; x : vector ) : integer;
var
m, m1, m2 : integer;
begin
IF sf - incep = 1 then
begin
if x [incep] > x [sf] then
MAXIM := x [incep]
else
MAXIM := x [sf]
end
ELSE
begin
m := (incep + sf) DIV 2;
m1 := MAXIM ( incep, m, x);
m2 := MAXIM ( m, sf, x );
if m1 > m2 then
MAXIM := m1
else
MAXIM := m2
end;
end; { sf. functie }
9
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Begin { PROGRAM PRINCIPAL }
CLRSCR;
write ('n = '); readln (n);
for i := 1 to n do
begin
write ('x [ ',i,' ] = ');
readln (x[i]);
end;
MAX := MAXIM ( 1, n, x);
writeln;
writeln ('MAX = ', MAX);
readln
end.
Rezolvare:
Se definesc funcii i proceduri ale cror nume sugereaz i scopul.
Program ATESTAT_2004_21_Polinom_1;
uses
Crt;
const
GMaxPol = 20; {Gradul MAXim al unui POLinom}
type
polinom = record
GRAD : 0..GMaxPol;
COEF : array [ 0..GMaxPol ] of real;
end;
var
POL1, POL2, POLREZ, PREST : polinom;
NUMAR, A, X, VALOARE : real;
OK, EROARE : boolean;
OPTIUNE, CC : char;
10
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure CitestePol (MESAJ: string; var POL: polinom);
var
i:integer;
begin
repeat
WriteLn;
WriteLn (MESAJ,' :');
Write (' - introduceti gradul: ');
ReadLn (POL.GRAD);
if POL.GRAD > GMaxPol then
begin
WriteLn('Atentie ! Gradul nu poate fi mai mare de ',GMaxPol,' !');
Sound(1200);
Delay(200);
NoSound; {Beep}
end;{if}
if POL.GRAD<0 then
begin
WriteLn('Atentie ! Gradul nu poate fi mai mic decat 0 !');
Sound(1200);
Delay(200);
NoSound; {Beep}
end;{if}
until (0<=POL.GRAD) and (POL.GRAD<=GMaxPol);
for i := POL.GRAD downto 0 do
begin
Write (' - Coeficientul lui X^', i:2,': ');
ReadLn ( POL.COEF [i] );
POL.COEF[i] := RoundR (POL.COEF [i], 5); {cel mult 5 zecimale}
end;{for}
end;{procedure}
11
Probleme rezolvate de programare Subiecte propuse la ATESTAT
for i:=POL.GRAD downto 0 do
begin
if (i>0) and ( Abs (POL.COEF [i]) = 1.0) then
S := '' {nu afiseaza coeficientul +/- 1, dar va afisa 0}
else
S := NrRealSir ( Abs (POL.COEF [i]), False); {end if}
if POL.COEF[I]<0.0 then
S := ' - ' + S
else
if i < POL.GRAD then
S := ' + ' + S
else
S := ' ' + S; {end if}
Write (S);
if i > 9 then
Write ('x^', i:2)
else
if i > 1 then
Write('x^', i:1)
else
if i = 1 then
Write ('x')
else {i=0}
WriteLn; {end if}
end;{for}
end;{procedure}
while KeyPressed do
begin
CC := ReadKey;
if Ord (CC) = 0 then
CC := ReadKey;
end;{while}
writeln;
WriteLn (' PROGRAM TEST');
writeln;
writeln (' Alegeti una dintre optiunile de mai jos:');
writeln; writeln; writeln;
WriteLn(' 1 - Pentru a calcula valoarea unui polinom intr-un punct X dat');
WriteLn;
WriteLn(' <Esc> - Pentru Terminarea programului ');
WriteLn; writeln; WriteLn;
12
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Write (' Introduceti optiunea dvs : ');
{citeste OPTIUNEA solicitata}
repeat
until KeyPressed;
OPTIUNE := ReadKey;
if Ord (OPTIUNE)=0 then
CC := ReadKey;
while KeyPressed do
begin
CC := ReadKey;
if Ord (CC) = 0 then
CC := ReadKey;
end;{while}
OK:=True;
CASE OPTIUNE of
Rezolvare:
Am notat cu inf, respectiv cu sup, o poziie de nceput, respectiv de sfrit, din vectorul de
sortat.
13
Probleme rezolvate de programare Subiecte propuse la ATESTAT
Program ATESTAT_2004_22_QUICK_SORT;
uses CRT;
CONST
nmax = 50;
TYPE
vector = array [1..50] of real;
VAR
x : vector; {x = variabila globala}
i, n : integer;
procedure QUICK (inf, sup : integer);
VAR
i, j : integer;
aux : real;
b : boolean;
begin
if inf < sup then
begin
i := inf;
j := sup;
b := TRUE;
repeat
if x[i] > x[j] then
begin
aux := x[i];
x[i] := x[j];
x[j] := aux;
b := not b;
end;
if b = TRUE then
j := j - 1
else
i := i + 1;
until i = j;
QUICK ( inf, i - 1);
QUICK ( i + 1, sup);
end;
end;
Begin { PROGRAM PRINCIPAL }
CLRSCR;
repeat
write ('n = '); readln (n)
until (n >= 1) and (n <= nmax);
writeln;
write ('Introduceti elementele vectorului');
writeln;
for i := 1 to n do
begin
write ('x[',i,'] = ');
readln ( x[i] );
end;
writeln;
writeln ('Sirul initial :');
writeln;
for i:=1 to n do
write ( x[i],' ');
QUICK (1, n);
writeln;
writeln ('Sirul sortat :');
writeln;
for i:=1 to n do
write (x[i],' ');
readln;
end.
14
Probleme rezolvate de programare Subiecte propuse la ATESTAT
ATESTAT - 2004 - 29 - S se realizeze un program de parcurgere a unui arbore binar.
Rezolvare:
S presupunem c arborele binar bina are configuraia din figura de mai jos.
Observaii:
1
Nodurile terminale sunt 4, 5, 6, 7 (aceste noduri nu mai
2 3 au descendeni sau fii). Prin urmare, subarborii stng i
drept ai nodurilor terminale vor fi reprezentai prin NIL.
Convenim ca, la introducerea datelor, s introducem
4 5 6 7 valoarea 0 (zero) pentru aceti subarbori, pentru a marca
faptul c nodurile terminale 4, 5, 6, 7 nu mai au descendeni.
Pentru crearea arborelui, putem alege oricare dintre
variante: PREordine, Inordine, POSTordine.
Convenim s crem arborele din figura de mai sus introducnd nodurile n
PREordine (Rdcin, subarbore STNG, subarbore DREPT). n acest caz, nodurile se vor
introduce astfel:
1, 2, 4, 0, 0, 5, 0, 0, 3, 6, 0, 0, 7, 0, 0.
Program ATESTAT_2004_29_PARCURGERE_ARBORE_BINAR;
uses CRT;
TYPE
ARBORE = ^NOD;
NOD = Record
Data : integer ; {numarul nodului, care coincide, }
{pentru simplificare, cu data utila}
stg, dr : ARBORE
END;
VAR
Radacina : ARBORE;
15
Probleme rezolvate de programare Subiecte propuse la ATESTAT
procedure PREordine (R : arbore);
begin
IF R <> NIL then
begin
write (' ', R^.Data, ' ');
PREordine (R^.stg);
PREordine (R^.dr)
end
end;
writeln;
writeln;
writeln;
writeln;
writeln;
writeln;
writeln;
readln
end.
16