2005
BACKTRACKING
ATESTAT - 2005 - 1 - Se citesc de la tastatur dou numere naturale n i k (0 < k < n
< 12). S se afieze toate irurile formate din k litere distincte, litere alese dintre
primele n ale alfabetului englez. Exemplu: pentru k = 2 i n = 4, se afieaz, nu
neaprat n aceast ordine, irurile: AB, BA, AC, CA, AD, DA, BC, CB, BD, DB, CD,
DC.
Rezolvare:
Aplicm algoritmul BACKTRACKING pentru generarea aranjamentelor.
program ATESTAT_2005_1_ARANJAMENTE_1;
uses CRT;
CONST
Kmax = 20; { nr. max al elementelor din A }
Nmax = 50; { nr. max al elementelor din B sau nr.
valorilor functiei }
TYPE
functie = array [ 1..Kmax ] of 0..Nmax;
VAR
k, poz, i : 1 .. Kmax;
{ se considera k <= n }
n : 0 .. Nmax;
f : functie;
{sau f : array [1..Kmax] of
[1..Nmax];}
IMAG : set of 1 .. Nmax; { IMAG = multimea imaginilor
elementelor din A }
{ adica f [poz] }
Begin { PROGRAM PRINCIPAL }
clrscr;
repeat
write ('k = ');
readln (k);
until ( k >= 1 ) AND ( k <= Kmax );
repeat
write ('Introduceti un n >= ', k,'
n = ');
readln (n);
if n < k then
writeln ('Pentru acest n = ', n,' Nu exista
solutii')
until ( n >= k ) AND ( n >= 1 ) AND ( n <= Nmax );
writeln;
writeln ('Apasati ENTER pentru urmatoarea solutie');
writeln;
readln;
poz := 1;
}
f [poz] := 0 ;
IMAG := [] ;
multimea vida }
{ initializare element }
{ initializare multime imagini cu
begin
{tiparire SOLUTIE}
write ( CHR (64
+ f[i] ) ,' ');
end;
readln;
end
else
begin
IMAG := IMAG + [ f
[poz] ];
poz := poz + 1 ;
{pas INAINTE}
f [poz] := 0
{reinitializare element}
end;
end; { sf. IF NOT }
end; { sf. WHILE interior }
poz := poz - 1;
{pas INAPOI}
IMAG := IMAG - [ f [poz] ];
end; { sf. WHILE exterior }
readln
END.
ATESTAT - 2005 - 2 - Civa copii cu vrste ntre 2 si 7 ani trebuie s fie vizitai de
Mo Crciun. Scriei un program care determin toate modurile diferite n care pot
ei s fie aezai n lista lui Mo Crciun, astfel nct s fie vizitai toi copiii i vizitele
s se fac n ordinea cresctoare a vrstei lor. Se citesc de la tastatur: n = numrul
de copii (0 < n < 10), apoi numele i vrsta fiecruia dintre cei n copii. Se scriu, pe
linii diferite, liste cu numele copiilor, n ordinea n care vor fi vizitai de Mo Crciun.
O list este format din toate cele n nume ale copiilor, ntr-o anumit ordine, oricare
dou nume succesive fiind desprite prin spaii.
Exemplu:
Pentru datele de intrare:
n = 4,
Dan 6, Cristina 4, Corina 2, Iulia 4
se scriu urmtoarele soluii:
Corina Iulia Cristina Dan
Corina Cristina Iulia Dan
Rezolvare:
Definim o procedur ORDONEAZ, pentru ordonarea numelor copiilor.
program ATESTAT_2005_2_MOS_CRACIUN_SI_COPIII;
uses crt;
const
5
nmax = 100;
type
vector = array [1..nmax] of integer;
vector_nume = array [1..nmax] of string;
vector_virsta = array [1..nmax] of integer;
var
f : vector;
sol, n, i : integer;
incep, sf : integer;
NUME : vector_nume;
VIRSTA : vector_virsta;
EGAL : boolean;
t : integer;
k : integer; {contor care numara elementele vecine egale
in vectorul VIRSTA }
pozitie : integer; {pozitia incepind de la care apar
elemente egale}
{in vectorul VIRSTA}
j : integer;
begin
sol := sol + 1;
write ('Solutia nr. ',sol,'
');
for t := 1 to incep - 1 do
begin
write ( NUME [t],' ');
end;
for j := 1 to sf - incep + 1 do
begin
write ( NUME [ f [j] + incep - 1 ],' ' )
end;
for t := sf + 1 to n do
begin
write ( NUME [t],' ');
end;
writeln;
readln;
end;
{ PROGRAM
clrscr;
PRINCIPAL }
sol := 0;
write ('Dati numarul de copii, n = ');
readln (n);
writeln;
writeln;
9
for i := 1 to n do
begin
write ('Dati NUMELE copilului ', i,' nume =
');
readln ( nume [i] );
write ('Dati VIRSTA copilului ', i, '
virsta = ');
readln ( virsta [i] );
writeln;
writeln
('*****************************************');
writeln
end;
ORDONEAZA (virsta, nume, n);
writeln;
writeln ('Apasati ENTER pentru urmatoarea solutie');
readln;
10
i := 1;
while i < n do
begin
EGAL := FALSE;
k := 0;
while ( VIRSTA [i] = VIRSTA [i+1] ) AND (i < n
) do
begin
EGAL := TRUE;
k := k + 1;
i := i + 1
end;
if EGAL = TRUE then
begin
k := k + 1;
pozitie := i - k + 1;
incep := pozitie;
sf := pozitie + k - 1;
PERMUTA (incep, sf);
end;
i := i + 1
end;
writeln;
if sol = 0 then
writeln ('Nu exista solutie');
readln
END.
12
procedure SCRIE;
begin
for i := 1 to k - 1 do
begin
write (w [ f[i] ]);
end;
write ( w [ f[k] ]);
writeln;
end;
function NRCIFRE (x : integer) : integer;
begin
if x = 0 then
nrcif := 1
else
begin
nrcif := 0;
while x <> 0 do
begin
nrcif := nrcif + 1;
x := x DIV 10
end;
end;
NRCIFRE := nrcif
end;
procedure ORDONEAZA (var v:vector; q:integer);
var
k, j, aux: integer;
begin
repeat
k:= 0;
j := 1;
repeat
if v[j] > v [j+1] then
begin
aux := v[j];
v[j] := v[j+1];
v[j+1] := aux;
k := 1
end;
j := j + 1
until (j > q-1)
until (k = 0);
end;
13
14
x := 1;
f [x] := 0;
while x > 0 do
begin
if f [x] < nrcif then
begin
f [x] := f[x] + 1;
if x = k then
begin
SCRIE;
readln;
end
else
begin
x := x + 1; {PAS
f [x] := 0
end
end
else
x := x 1
{PAS INAPOI}
end;
readln
END.
INAINTE}
begin
write ('{ ');
for i := 1 to n - 1 do
begin
write (nota [ f[i] ],' , ');
end;
write ( nota [ f[n] ],' ');
write ('} ');
writeln;
end;
16
[1]
[2]
[3]
[4]
[5]
[6]
[7]
:=
:=
:=
:=
:=
:=
:=
'do';
're';
'mi';
'fa';
'sol';
'la';
'si';
x := 1;
f [x] := 0;
while x > 0 do
begin
if f [x] < p then
begin
f [x] := f[x] + 1;
if x = n then
begin
SCRIE;
readln;
end
else
begin
x := x + 1; {PAS INAINTE}
f [x] := 0
end
end
else
x := x 1
{PAS INAPOI}
end;
readln
END.
17
18
program ATESTAT_2005_5_Codul_Morse_produs_cartezian;
uses CRT;
type
vector = array [1..20] of integer;
var
p, i, x, n : integer;
m, f : vector;
procedure SCRIE;
begin
for i := 1 to n
do
write (CHR (44 + f[i] ),' ');
writeln;
end;
Begin { PROGRAM PRINCIPAL }
CLRSCR;
writeln ('Precizati de cite ori trebuie inmultita
multimea M cu ea insasi');
write ('Dati n = ');
readln (n);
writeln ('Multimea M are doar p = 2 elemente:
. si -
');
p := 2;
writeln;
writeln ('Apasati ENTER dupa fiecare
solutie');
readln;
x := 1;
f [x] := 0;
while x > 0 do
begin
if f [x] < p then
begin
f [x] := f[x] + 1;
if x = n then
begin
if NOT ( f [1] = 1 ) AND NOT (
f [n] = 1 ) then
begin
SCRIE;
readln;
end;
end
else
begin
x := x + 1; {PAS INAINTE}
f [x] := 0
end
end
19
else
x := x 1
{PAS
INAPOI}
end;
readln
END.
20
program ATESTAT_2005_6_PERMUTARI_ITERATIV;
uses crt;
const
nmax = 100;
type
vector = array [1..nmax] of integer;
var
f : vector;
sir : string;
lungime_sir : integer;
sol, n, i : integer;
procedure VERIFICA ( k : integer; f : vector ; VAR CONTIN
: boolean );
LABEL
10;
begin
CONTIN := TRUE;
for i := 1 to k - 1 do
begin
if f [i] = f [k] then
begin
CONTIN := FALSE;
GOTO 10
end;
end;
10: end;
procedure SCRIE ;
begin
sol := sol + 1;
write ('Solutia nr. ',sol,'
');
for i := 1 to n do
write ( sir [f [i] ] )
readln;
writeln
{optionale}
end;
procedure PERMUTA ( m : integer );
LABEL
20;
var
k : integer;
CONTIN : boolean;
begin
k := 1;
f [k] := 0;
while k > 0 do
begin
CONTIN := FALSE;
21
22
Begin
{ PROGRAM
clrscr;
PRINCIPAL }
sol := 0;
writeln;
write ('Dati sirul care se va permuta, sir = ');
readln (sir);
writeln;
writeln;
writeln;
writeln ('Apasati ENTER dupa fiecare solutie
afisata');
writeln;
lungime_sir := LENGTH (sir);
n := lungime_sir;
writeln;
writeln;
PERMUTA (n);
if sol = 0 then
writeln ('Nu exista solutie');
readln
END.
procedure SCRIE;
begin
write ('{ ');
for i := 1 to n - 1 do
begin
write (f[i],' , ');
end;
write ( f[n],' ');
write (' ');
writeln;
end;
24
26
end;
Begin
{ PROGRAM PRINCIPAL }
clrscr;
sol := 0;
write('Dati n = ');
readln (n);
writeln;
writeln ('Apasati ENTER dupa fiecare solutie');
writeln;
PERMUTA (n);
if sol = 0 then
writeln ('Nu exista solutie');
readln
END.
28
end;
end;
NRCIFRE := nrcif
end;
function PALINDROM ( x : integer ) : boolean;
begin
n := NRCIFRE (x);
for i := n DOWNTO 1 do
begin
y [i] := x MOD 10;
x := x DIV 10;
end;
30
OK := TRUE;
for i := 1 to n DIV 2 do
begin
if y [i] <> y [n-i+1] then
OK := FALSE
end;
PALINDROM := OK
end; { sfarsit functie PALINDROM }
procedure SCRIE;
begin
write ('{ ');
for i := 1 to n - 1 do
begin
write (f[i],' , ');
end;
write ( f[n],' ');
write (' ');
writeln;
writeln;
end;
Begin { PROGRAM PRINCIPAL }
CLRSCR;
writeln ('Precizati numarul de cifre al viitorului
numar');
write ('Dati n = ');
readln (n);
{n = nr de multimi ale produsului cartezian }
writeln;
repeat
writeln ('Precizati care este cea mai mare cifra
din viitorul numar');
write ('Dati p = ');
readln (p);
until (p > 0) AND (p<=5);
writeln;
{este acelasi lucru cu a cere numarul de elemente din
fiecare multime }
{implicata in calculul produsului cartezian }
poz := 1;
f [poz] := 0;
while poz > 0 do
begin
if f [poz] < p then
begin
f [poz] := f[poz] + 1;
if poz = n then
begin
x := 0;
for i := n downto 1 do
31
begin
x := x + PUTERE (10, ni) * f [i];
end;
if PALINDROM (x) = TRUE then
begin
writeln ('x = ', x, '
este PALINDROM');
SCRIE;
end;
end
else
begin
poz := poz + 1;
INAINTE}
f [poz] := 0
end
end
else
poz := poz 1
end;
readln
END.
32
{PAS INAPOI}
{PAS
ALOCARE DINAMICA
ATESTAT - 2005 - 10 - S se realizeze operaiile de creare i vizualizare a unei
stive implementate dinamic, precum i eliminarea unui element din stiv.
Barem:
- declararea corect a variabilelor: 1 punct
- crearea: 4 puncte
- vizualizarea: 2 puncte
- eliminarea unui element: 2 puncte
- din oficiu: 1 punct
Rezolvare:
program ATESTAT_2005_10_STIVA;
label
10,500;
type
STIVA = ^Nod;
Nod = record
cheie : integer;
data : integer;
urm : STIVA
end;
var
p, q, r, baza : STIVA;
n, x, i, j : integer;
data : integer;
c : char;
procedure CITDATA; { introducere date utile }
begin
write ('introduceti datele nodului : ');
readln (data);
end;
procedure TRAVLISTA ; { traversare in ordinea introducerii
}
begin
p:=baza;
while p<>nil do
begin
writeln(' cheia= ',p^.cheie,' data= ',p^.data);
p:=p^.urm;
writeln
end;
end;
33
34
writeln(p^.cheie,' ',p^.data);
writeln
end
end;
procedure STERGE ;{ sterge un nod indicat printr-o cheie
}
begin
q:=p^.urm;
p^:=q^
end;
Begin { PROGRAM PRINCIPAL }
write('dati nr.de noduri N = ');
readln(n);
writeln;
if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end
36
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');
INSEREAZAPRIMUL;
writeln
end;
if n > 1 then
begin
for j:=2 to n do
begin
INSEREAZAREST;
writeln
end
end;
j:=j+1;
INSEREAZAREST;
writeln;
writeln(' LISTA ESTE : ');
TRAVLISTA;
writeln;
10:
write('DORITI SA CAUTATI UN NOD ? APASATI D SAU N
');
readln(c);
if (c='d') or (c='D') then
begin
CAUTA
end;
writeln;
write('DORITI SA STERGETI UN NOD ? APASATI D SAU N
');
readln(c);
writeln;
if (c='d') or ( c='D') then
begin
CAUTA;
writeln('CONTINUT NOD CU CHEIA ',X,' INAINTE
DE STERGERE ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln;
STERGE;
writeln;
writeln('CONTINUTUL NODULUI DUPA STERGERE
ESTE :');
writeln(p^.cheie,' ',p^.data);
writeln;
37
38
Rezolvare:
program ATESTAT_2005_11_COADA;
label
10,500;
type
COADA=^nod;
nod=record
cheie : integer;
data : integer;
urm : COADA
end;
var
q, r, baza, p : COADA;
n, x, i, j : integer;
data : integer;
c : char;
procedure CITDATA; { introducere date utile }
begin
write ('introduceti datele nodului : ');
readln (data);
end;
procedure TRAVLISTA ; { traversare in ordinea introducerii
}
begin
p:=baza;
while p<>nil do
begin
writeln(' cheia= ',p^.cheie,' data= ',p^.data);
p:=p^.urm;
writeln
end;
end; {sfarsit procedura TRAVLISTA}
procedure INSEREAZAPRIMUL ; {introduce primul element - la
incep. listei }
begin
baza:=nil;
new(p);
write('dati cheia nodului 1 : ');
readln(p^.cheie);
p^.urm:=baza;
baza:=p;
CITDATA;
39
p^.data:=data
end;
procedure INSEREAZAREST ; { introduce celelalte elem. - la
sfirs. listei }
begin
new (q);
q^.urm:=nil;
p^.urm:=q;
if j<=n then
begin
write('dati cheia nodului ', j,' : ');
readln(q^.cheie);
CITDATA;
q^.data:=data;
p:=q
end
40
else
begin
q^.cheie:=N+1;
{
q^.data:='ACEST NOD NU SE VA STERGE SI NU SE
ADAUGA NIMIC DUPA EL'; }
p:=q
end
end;
procedure CAUTA ; { cauta un nod dupa cheie }
var
b:boolean;
begin
b:=false;
write('DATI CHEIA X = ');
readln(x);
writeln;
p:=baza;
while (p<>nil) and not b do
begin
if p^.cheie=x then
b:=true
else
p:=p^.urm
end;
if not b then
writeln('NODUL ( CHEIA ) NU EXISTA ')
else
begin
writeln('PRIMUL NOD CARE ARE CHEIA
',X,' ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln
end
end;
procedure STERGE ;{ sterge un nod indicat printr-o cheie
}
begin
q:=p^.urm;
p^:=q^
end;
Begin { PROGRAM PRINCIPAL }
write('Dati numarul de noduri N = ');
readln(n);
writeln;
if n=0 then
begin
writeln('LISTA VIDA');
41
goto 500
end
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');
INSEREAZAPRIMUL;
writeln
end;
if n > 1 then
begin
for j:=2 to n do
begin
INSEREAZAREST;
writeln
end
end;
j:=j+1;
writeln('INTRODUCETI NODUL
INSEREAZAREST;
writeln;
42
F A N I O N ');
10:
');
');
readln(c);
writeln;
if (c='d') or ( c='D') then
begin
CAUTA;
writeln('CONTINUT NOD CU CHEIA ',X,' INAINTE
DE STERGERE ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln;
STERGE;
writeln;
writeln('CONTINUTUL NODULUI DUPA STERGERE
ESTE :');
writeln(p^.cheie,' ',p^.data);
writeln;
writeln('LISTA DUPA STERGEREA NODULUI CU
CHEIA ',X,' ESTE :');
TRAVLISTA;
writeln
end;
write('DORITI SA RELUATI PROGRAMUL ? APASATI D SAU N
');
readln(c);
writeln;
if ( c='d') or ( c='D') then goto 10;
500: readln
END.
Rezolvare:
program ATESTAT_2005_12_LISTA_DUBLU_INLANTUITA;
uses CRT;
label
10, 500;
type
LISTA = ^nod;
nod = record
cheie : integer;
data : string;
urm, preced : LISTA
end;
44
var
q,r,baza,p: LISTA;
n,x,i,j:integer;
data:string;
c:char;
procedure CITDATA; { introducere date utile }
begin
write ('Introduceti datele nodului : ');
readln (data);
end;
procedure TRAVLISTA_INCEP_SFARSIT ; { traversare lista
inceput -> sfirsit }
begin
p:=baza;
writeln ('--------------------------------------');
writeln ('Traversare in sens direct');
writeln ('--------------------------------------');
while ( p<>nil ) AND ( p^.data <> '*' ) do
begin
writeln ('NODUL cu cheia= ',p^.cheie,' data=
',p^.data);
p:=p^.urm;
end;
writeln('Ultimul NOD (FANION): cheia=
',p^.cheie,' data= ',p^.data);
end;
procedure TRAVLIST_SFARSIT_INCEP;
{ traversare lista
sfirsit -> inceput }
begin
p:=baza;
q:=p;
p:=p^.urm;
p^.preced := q;
while ( p<>nil ) AND ( p^.data <> '*' ) do
begin
q := p;
p:=p^.urm;
p^.preced := q;
end;
writeln ('--------------------------------------');
writeln ('Traversare in sens invers');
45
writeln ('--------------------------------------');
while p <> baza do
begin
writeln ('NOD CURENT cheia= ',p^.cheie,'
data= ',p^.data);
p:=p^.preced;
end;
writeln('NOD CURENT cheia= ',p^.cheie,' data=
',p^.data);
end; {sfarsit procedura TRAVLIST_SFARSIT_INCEP }
procedure INSEREAZAPRIMUL ; {introduce primul element - la
incep. listei }
begin
baza:=nil;
new(p);
write('dati cheia nodului 1 : ');
readln(p^.cheie);
p^.urm:=baza;
baza:=p;
CITDATA;
p^.data:=data
end;
46
48
if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');
INSEREAZAPRIMUL;
writeln
end;
if n > 1 then
begin
for j:=2 to n do
begin
INSEREAZAREST;
writeln
end
end;
j:=j+1;
INSEREAZAREST;
writeln;
writeln(' LISTA parcursa de la INCEPUT la SFIRSIT
este : ');
TRAVLISTA_INCEP_SFIRSIT;
writeln;
writeln
('*********************************************');
writeln;
writeln(' LISTA parcursa de la SFIRSIT la INCEPUT
este : ');
TRAVLIST_SFIRSIT_INCEP;
writeln;
500:
END.
readln
49
50
Rezolvare:
program
ATESTAT_2005_13_LISTA_LINIARA_SIMPLU_INLANTUITA_INTREGI;
uses CRT;
label
10,500;
const
nmax = 50;
type
LISTA = ^Nod;
Nod = record
cheie : integer;
data : integer;
urm : LISTA
end;
vector = array [1..nmax] of integer;
var
q, r, baza, p : LISTA;
n, x, i, j : integer;
data : integer;
c : char;
v : vector;
function VERIFICA ( v : vector; q:integer) : boolean;
var
j : integer;
begin
VERIFICA := TRUE;
j := 1;
repeat
if v[j] > v [j+1] then
VERIFICA := FALSE;
j := j + 1
until (j > q-1)
end;
procedure TRAVLISTA ; { traversare in ordinea introducerii
}
begin
p:=baza;
while p<>nil do
51
begin
writeln ('data= ',p^.data);
p:=p^.urm;
end;
end;
Begin { PROGRAM PRINCIPAL }
clrscr;
writeln ('Dati elementele listei');
writeln ('**********************');
i := 0; {contor care numara numerele introduse }
write ('Dati primul element, x = ');
readln (x);
writeln;
52
If x = 0 then
begin
writeln ('LISTA VIDA');
goto 500
end
else
begin
{ INSERARE PRIMUL NOD }
i := i + 1;
baza:=nil;
new (p);
p^.urm:=baza;
baza:=p;
p^.data := x;
v [i] := x;
end;
writeln;
writeln ('Dati urmatoarele elemente');
repeat
write ('Dati elementul ', i + 1,'
x = ');
readln (x);
if x <> 0 then
{ INSERARE URMATOARELE NODURI }
begin
i := i + 1;
v [i] := x;
new (q);
q^.urm := nil;
p^.urm := q;
q^.data := x;
p := q
end;
until x = 0;
n := i;
writeln;
writeln ('Lista are ', n, ' elemente');
writeln;
writeln(' LISTA ESTE : ');
TRAVLISTA;
writeln;
if VERIFICA (v, n) = TRUE then
writeln ('Lista este ORDONATA')
else
writeln ('Lista NU este ORDONATA');
500:
END.
readln
53
54
Rezolvare:
program ATESTAT_2005_14_LISTA_SIMPLU_INLANTUITA;
uses CRT;
label
10, 500;
type
LISTA = ^NOD;
NOD = record
cheie : integer;
data : integer;
urm : LISTA
end;
var
q,r,baza,p: LISTA;
n,x,i,j:integer;
data:integer;
primul, ultimul : integer;
c:char;
procedure CITDATA; { introducere date utile }
begin
write('introduceti datele nodului : ');
readln(data);
end;
procedure TRAVLISTA_INCEP_SFIRSIT ; { traversare lista
inceput -> sfirsit }
begin
p:=baza;
writeln ('--------------------------------------');
primul := p^.data;
writeln ('Primul = ', primul);
writeln;
while p <> nil do
begin
writeln ('NODUL cu cheia= ',p^.cheie,'
',p^.data);
ultimul := p^.data;
p:=p^.urm;
end;
writeln;
writeln ('Ultimul = ', ultimul);
55
data=
writeln;
end;
procedure INSEREAZAPRIMUL ; {introduce primul element - la
incep. listei }
begin
baza:=nil;
new(p);
write('dati cheia nodului 1 : ');
readln(p^.cheie);
p^.urm:=baza;
baza:=p;
CITDATA;
p^.data:=data
end;
56
if not b then
writeln('NODUL ( CHEIA ) NU EXISTA ')
else
begin
writeln('PRIMUL NOD CARE ARE CHEIA
',X,' ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln
end
end;
58
readln;
TRANSFERA;
writeln;
writeln ('Dupa TRANSFER, avem:');
writeln;
writeln ('Primul = ', primul);
writeln ('Ultimul = ', ultimul);
p := baza;
p^.data := primul;
j := 1;
while (p <> nil) AND (j <> n) do
begin
p:=p^.urm;
j := j + 1;
end;
60
p^.data := ultimul;
writeln;
writeln ('A doua traversare a listei:');
TRAVLISTA_INCEP_SFIRSIT ;
500:
END.
readln
end;
procedure TRAVLISTA ; { traversare in ordinea introducerii
}
begin
p:=baza;
while p<>nil do
begin
writeln(' cheia= ',p^.cheie,' data= ',p^.data);
p:=p^.urm;
writeln
end;
end;
62
begin
if p^.cheie=x then
b:=true
else
p:=p^.urm
end;
if not b then
writeln('NODUL ( CHEIA ) NU EXISTA ')
else
begin
writeln('PRIMUL NOD CARE ARE CHEIA
',X,' ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln
end
end;
procedure STERGE ;{ sterge un nod indicat printr-o cheie
}
begin
q:=p^.urm;
p^:=q^
end;
64
66
data= ',p^.data);
data= ',p^.data);
end;
procedure INSEREAZAPRIMUL ; {introduce primul element - la
incep. listei }
begin
baza:=nil;
new(p);
write('dati cheia nodului 1 : ');
readln(p^.cheie);
p^.urm:=baza;
baza:=p;
CITDATA;
p^.data:=data
end;
68
p^:=q^
end;
Begin { PROGRAM PRINCIPAL }
write('dati nr.de noduri N = ');
readln(n);
writeln;
if n=0 then
begin
writeln('LISTA VIDA');
goto 500
end
else
begin
writeln('INTRODUCETI DATELE NODULUI 1 ');
INSEREAZAPRIMUL;
writeln
end;
70
if n > 1 then
begin
for j:=2 to n do
begin
INSEREAZAREST;
writeln
end
end;
q^.urm := baza;
{ j:=j+1;}
writeln ('INTRODUCETI NODUL
INSEREAZAREST;
F A N I O N ');
writeln;
writeln (' LISTA ESTE : ');
TRAVLISTA;
writeln;
500: readln
END.
var
q, r, baza, p : LISTA;
n, x, i, j : integer;
data : integer;
c : char;
procedure CITDATA; { introducere date utile }
begin
write ('introduceti datele nodului : ');
(data);
end;
72
readln
var
b:boolean;
begin
b:=false;
write('DATI CHEIA X = ');
readln(x);
writeln;
p:=baza;
while (p<>nil) and not b do
begin
if p^.cheie=x then
b:=true
else
p:=p^.urm
end;
if not b then
writeln('NODUL ( CHEIA ) NU EXISTA ')
else
begin
writeln('PRIMUL NOD CARE ARE CHEIA
',X,' ESTE ');
writeln(p^.cheie,' ',p^.data);
writeln
end
end;
74
writeln;
if (c='d') or ( c='D') then
begin
CAUTA;
writeln('CONTINUT NOD CU CHEIA ',X,' INAINTE
DE STERGERE ESTE ');
writeln(p^.cheie,' ',p^.data);
STERGE;
writeln;
writeln('CONTINUTUL NODULUI DUPA STERGERE
ESTE :');
writeln(p^.cheie,' ',p^.data);
writeln('LISTA DUPA STERGEREA NODULUI CU
CHEIA ',X,' ESTE :');
TRAVLISTA;
end;
write('DORITI SA RELUATI PROGRAMUL ? APASATI D SAU N
');
readln (c);
writeln;
if ( c='d') or ( c='D') then goto 10;
500: readln
END.
76
GRAFURI
ATESTAT - 2005 - 18 - Se d un graf neorientat G la care:
- n = numrul de vrfuri (n, numr natural pozitiv);
- pentru fiecare vrf se cunosc vrfurile adiacente cu el;
S se scrie un program prin care s se afieze:
a). gradul fiecrui vrf (nod);
b). lista tuturor vrfurilor de grad maxim;
c). numrul de vrfuri izolate;
d). numrul de muchii din graf.
Barem:
- declaraii i introducere corect a grafului: 1 punct
- realizarea punctului a): 2 puncte
- realizarea punctului b): 2 puncte
- realizarea punctului c): 2 puncte
- realizarea punctului d): 2 puncte
- din oficiu: 1 punct
Rezolvare:
Considerm urmtorul graf neorientat:
5
2
Graful are 5 noduri (vrfuri),
1
notate cu 1, 2, 3, 4, 5 i
4
4 muchii, notate cu
3
[2,3], [2,4], [3,4] i [4,5].
n general, la un graf neorientat cu n vrfuri, matricea de adiacen A
este o matrice ptratic de ordinul n, simetric, cu elementele:
A [i, j] =
1,
0,
A (5, 5) =
1
2
3
4
5
1
0
0
0
0
0
2
0
0
1
1
0
3
0
1
0
1
0
4
0
1
1
0
1
5
0
0
0
1
0
For j := 1 to n do
A [i, j] := 0;
II A Dac se cunoate numrul muchiilor. Notm cu [x, y] o muchie din graf,
unde x i y sunt extremitile muchiei (dou noduri ale grafului). n matricea de
adiacen, elementul A [x, y] = 1. Cum matricea de adiacen este i simetric,
rezult cu i A [y, x] = 1. Notnd cu m numrul de muchii din graf, vom folosi o
structur FOR n care, pentru fiecare muchie i, vom introduce extremitile x i
y. Evident, aceste extremiti sunt vrfuri n graf. Vom scrie:
78
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:)
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1;
A [y, x] := 1;
{matrice simetric}
End;
II B Dac NU se cunoate numrul muchiilor (este cazul problemei noastre), dar,
pentru fiecare vrf, se cunosc vrfurile adiacente cu el (se cunosc vecinii fiecrui
vrf). Notm cu x, respectiv cu y dou vrfuri din graf. Evident, att x ct i y iau
valori ntre 1 i n (n = numrul total de vrfuri din graf). Pentru fiecare nod x, trebuie
s precizm numrul vecinilor si, precum i care sunt acetia. n program vom
scrie:
For x := 1 to n do
begin
write (Ci vecini are x, nrvecini = );
readln (nr);
For i := 1 to nrvecini do
begin
write (Dai urmtorul vecin, y = );
readln (y);
A [x, y] := 1;
A [y, x] := 1
end;
end;
a Gradul unui vrf v, se noteaz cu d(x) i este dat de numrul muchiilor
incidente cu v. n program vom folosi un vector notat cu d, cu 5 elemente (5 =
numrul de noduri), fiecare element reprezentnd gradul unui nod (vrf). Pentru cazul
particular al grafului de mai sus, avem:
d (1) = 0
d (2) = 2
d (3) = 2
d (4) = 3
d (5) = 1
Se observ c gradul unui nod icoincide cu numrul de cifre de 1 de pe linia
i din matricea de adiacen. Prin urmare, pentru a determina gradul unui nod,
numrm cifrele de 1 de pe fiecare linie a matricii de adiacen i reinem aceste
numere n elementele vectorului d.
b Determinm gradul maxim (elementul maxim din vectorul d) i afim doar
numerele nodurilor al cror grad = gradul maxim.
c Un vrf izolat are gradul zero. n matricea de adiacen, unui nod izolat i
corespunde o linie, respectiv o coloan cu toate elementele egale cu zero. Pentru a
determina numrul de vrfuri izolate, numrm liniile din matricea de adiacen care
au toate elementele nule.
79
program ATESTAT_2005_18_GRAF_NEORIENTAT;
uses CRT;
CONST
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
matrice = array [1..nmax, 1..nmax] of integer;
80
VAR
n : integer; {n = numarul nodurilor}
i, j : integer;
x, y : integer; {noduri in graf, extremiti ale unei
muchii}
A : matrice; {matricea de adiacenta}
d : vector;
{vectorul care contine "gradele" fiecarui
nod din graf}
nrvecini : integer; {numarul de vecini ai unui nod}
nrcifre1 : integer; {numarul de cifre egale cu 1 din
matricea de adiacenta}
gradmax : integer; {gradul maxim al unui nod}
nrcifrezero : integer; {numarul cifrelor egale cu zero
din matricea de adiacenta}
nrnodurigradzero : integer; {numarul nodurilor cu gradul
zero}
sumagrade : integer; {suma gradelor tuturor nodurilor}
m : integer; {numarul de muchii din graf}
Begin { PROGRAM PRINCIPAL }
CLRSCR;
write ('Dati numarul de noduri, n = ');
readln (n);
{Initializarea tuturor elementelor matricii de adiacenta
cu zero}
for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0
end;
end;
writeln;
{Completare matrice de adiacenta}
For x := 1 to n do
begin
write ('Cati vecini are nodul ',x, ' ? Dati
nrvecini = ');
readln (nrvecini);
For i := 1 to nrvecini do
begin
write ('Pentru nodul ', x,', dati urmatorul
vecin, y = ');
81
readln (y);
A [x, y] := 1;
A [y, x] := 1
end;
writeln;
end;
writeln;
{a - Determinare grade varfuri}
for i:= 1 to n do {i = index linie in matricea de
adiacenta}
begin
nrcifre1 := 0;
for j := 1 to n do {j = index coloana in matricea
de adiacenta}
begin
if A [i, j] = 1 then
nrcifre1 := nrcifre1 + 1;
end;
d [i] := nrcifre1;
writeln ('gradul nodului ', i,' = ', d [i] );
end;
writeln;
82
84
Altfel spus, fiecare nod are gradul n 1. Cum graful conine n noduri, rezult c
suma gradelor tuturor nodurilor este = n (n 1) = 2m.
Prin urmare, problema s-ar putea rezolva foarte simplu verificnd dac n (n 1)
= 2m, avnd n vedere c n i m sunt cunoscute (sunt date de intrare).
Presupunnd c nu dorim s verificm doar relaia de mai sus, vom face
verificri asupra matricii de adiacen A:
a - fie vom numra elementele egale cu 1 din matrice i vom verifica dac numrul
total de elemente egale cu 1 este egal cu n (n 1),
b - fie vom verifica dac, n matricea de adiacen, numai elementele diagonalei
principale sunt nule.
Notm cu [x, y] o muchie din graf, unde x i y sunt extremitile muchiei (dou
noduri ale grafului). n matricea de adiacen, elementul A [x, y] = 1. Cum matricea de
adiacen este i simetric, rezult cu i A [y, x] = 1. Deoarece se cunoate numrul
muchiilor (m), vom folosi o structur FOR n care, pentru fiecare muchie i, vom
introduce extremitile x i y. Evident, aceste extremiti sunt vrfuri n graf. Vom
scrie:
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:)
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1;
A [y, x] := 1;
{matrice simetric}
End;
program ATESTAT_2005_19_GRAF_NEORIENTAT;
uses CRT;
CONST
nmax = 100;
TYPE
vector = array [1..nmax] of integer;
matrice = array [1..nmax, 1..nmax] of integer;
VAR
n : integer; {n = numarul nodurilor}
m : integer; {numarul de muchii din graf}
x, y : integer; {noduri in graf, extremiti ale unei
muchii}
A : matrice; {matricea de adiacenta}
nrcifre1 : integer; {numarul de cifre egale cu 1 din
matricea de adiacenta}
nrcifrezero : integer; {numarul cifrelor egale cu zero
din matricea de
adiacenta}
i, j : integer;
85
86
end;
end;
writeln;
if nrcifrezero = n then
writeln (Graful este complet)
else
writeln (Graful este incomplet);
-----------------------------------------------------------------------------readln
end.
88
Rezolvare:
Un ciclu elementar are proprietatea c oricare dou vrfuri ale sale, cu excepia
primului i ultimului, sunt diferite dou cte dou. Lungimea unui ciclu = numrul
de muchii ce apar n ciclu.
Considernd graful din figura de mai jos, se poate observa uor ciclul 1 2 3
41
care
k
are
Nod 1
i=1
2
j=3
4
5
1
3
5
0
1
0
1
0
2
1
0
1
0
1
3
0
1
0
1
0
4
1
0
1
0
0
5
0
1
0
0
0
Trebuie doar s se verifice dac exist cicluri de lungime 4 (NU se cere generarea
acestora).
Pentru ciclul de lungime 4 identificat n graf (1 2 3 4 1), n matricea de
adiacen, liniile corespunztoare nodurilor 1 i 3 conin amndou cifra 1 pe poziiile
k = 2 i k = 4.
De asemenea, liniile corespunztoare nodurilor 2 i 4 conin amndou cifra 1
pe poziiile
k = 1 i k = 3.
Va trebui s verificm dac, pentru fiecare pereche de noduri distincte, liniile
(din matricea de adiacen) corespunztoare acestor noduri conin cifra 1 pe cel puin 2
poziii (coloane) identice.
Notm cu i, respectiv j dou linii distincte din matricea de adiacen, linii
corespunztoare a dou noduri i i j. Evident, i = 1 .. n-1, iar j = i + 1 .. n.
Notm cu k indexul de coloan (din matricea de adiacen) pentru care se face
testarea perechii A [i, k] i A [j, k]. Iniializm un contor nrcifre care numr cifrele
de 1, n condiia
( A [i, k] = 1 ) AND ( A [j, k] = 1 ).
program ATESTAT_2005_20_GRAF_CU_UN_CICLU_DE_LUNGIME_PATRU ;
uses CRT;
LABEL
sfarsit;
CONST
nmax = 100;
TYPE
89
90
91
92
Un lan ntr-un graf orientat se numete drum (notat D) dac toate arcele sale au
ACEEAI ORIENTARE, dat de sensul deplasrii de la x0 (extremitatea iniial a lui
a1) la xp (extremitatea final a lui ap). Vrfurile x0 i xp = extremitile lanului. De
observat c, n cazul drumului,
ARE IMPORTAN ORIENTAREA
ARCELOR
Altfel spus, un drum ntr-un graf orientat este un ir de vrfuri. Un drum se
poate scrie fie ca o succesiune de arce, fie ca o succesiune de vrfuri. Pentru graful
alturat, avem drumurile:
D1 = (1, 2, 3), D2 = (1, 2, 1, 3).
Matricea drumurilor unui graf G este o matrice B definit astfel:
B [i, j] =
1
A = 2
3
4
1
0
1
0
0
2
1
0
0
0
3
1
1
0
1
Matricea DRUMURILOR:
4
0
0
0
0
Nod
1
B = 2
3
4
1
1
1
0
0
2
1
1
0
0
3
1
1
0
1
4
0
0
0
0
IF A [i, j] = 0 then
A [i, j] := A [i, k] * A [k, j]
end
end
end
end
end;
94
program
ATESTAT_2005_21_MATRICEA_DRUMURILOR_ALGORITMUL_ROY_W
ARSHALL;
uses CRT;
CONST
nmax = 100;
TYPE
matrice = array [1..nmax, 1..nmax] of integer;
VAR
n, m : integer; {n = numarul nodurilor; m = numarul de
muchii din graf }
x, y : integer; {extremitati ale unei muchii}
A : matrice; {matricea de adiacenta}
B : matrice; {matricea drumurilor}
i, j, k : integer;
function MIN ( alfa, beta : integer) : integer;
begin
if alfa <= beta then
MIN := alfa
else
MIN := beta
end;
Begin { PROGRAM PRINCIPAL }
CLRSCR;
write ('Dati numarul de noduri, n = ');
readln (n);
write ('Dati numarul de muchii, m = ');
readln (m);
{Initializarea tuturor elementelor matricii de adiacenta
cu zero}
for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0
end;
end;
writeln;
{Completare matrice de adiacenta}
For i := 1 to m do
Begin
Writeln (Dai extremitile muchiei i:);
Write (Dai vrful x = ); readln (x);
Write (Dai vrful y = ); readln (y);
A [x, y] := 1;
{matricea NU este simetric}
End;
95
writeln;
writeln ('Matricea de ADIACENTA este:');
for i := 1 to n do
begin
writeln;
for j := 1 to n do
begin
write
( A [i, j] : 3 ); {se lasa 3
pozitii pentru fiecare }
{element
al
matricii }
end;
end;
writeln;
{ Deoarece se pleaca de la matricea de ADIACENTA A, si
pentru a nu afecta }
{aceasta matrice, Initializam
matrice DRUMURI B, cu matricea de ADIACENTA - A}
for i := 1 to n do
begin
for j := 1 to n do
begin
B [i, j] := A [i, j];
end;
end;
96
then
B [i, k] * B [k, j]
end
end
end;
writeln;
writeln ('Varianta 2 - Matricea drumurilor este:');
for i := 1 to n do
begin
writeln;
for j := 1 to n do
begin
write
( B [i, j] : 3 ); {se lasa 3
pozitii pentru fiecare }
{element
al
matricii }
end;
end;
readln
END.
98
NIL
NIL
NIL
NIL
NIL
Nod
1:
2:
3:
4:
5:
Succesori
2
3
4, 5
1, 5
n, m, i : integer ;
Iniializm toate componentele listei L cu pointerul NIL, scriind:
for i := 1 to n do
L [i] := NIL;
Prezena n graf a unui arc (x, y) presupune crearea unei locaii de memorie cu NEW
(P), urmat de calificarea celor dou cmpuri (NodSuccesor i URM) ale noii locaii.
Vom scrie:
P^. NodSuccesor := y ;
P^.URM := L [ x ] ;
L [ x ] := P ;
100
program ATESTAT_2005_22_LISTE_DE_ADIACENTA ;
uses CRT;
CONST
nmax = 100;
TYPE
LISTA = ^ELEMENT;
ELEMENT = RECORD
NodSuccesor : integer;
URM : LISTA
{pointer
de
legatura
spre
urmatorul nod din lista}
END;
VAR
L : array [1..nmax] of LISTA;
m, n, i : integer; { n = nr. de NODURI; m = nr. de ARCE
}
P : LISTA ;
{ P = pointer de lucru}
x, y : integer;
{ x, y = extremitatile unui arc }
Begin { PROGRAM PRINCIPAL }
CLRSCR;
write ('Dati numarul de noduri, n = ');
readln (n);
writeln;
write ('Dati numarul de muchii, m = ');
readln (m);
writeln;
{ Initializam toate componentele listelor de ADIACENTA
cu pointerul NIL }
for i := 1 to n do
begin
L [i] := NIL;
end;
writeln;
{Completarea LISTELOR de adiacenta}
For i := 1 to m do
Begin
Writeln ('Dati extremitatile muchiei i:');
Write ('Dati varful x = ');
readln (x);
Write ('Dati varful y = ');
readln (y);
NEW (P);
P^.NodSuccesor := y ;
P^.URM := L [x];
L [x] := P;
101
End;
writeln;
{Afisarea listelor de adiacenta pentru cele n noduri}
for i:= 1 to n do
begin
write ('Nodul ',i,' are urmatorii succesori :
');
P := L [i]; {P indic
initial spre
listei nodului i }
while P <> NIL do
begin
write (p^.NodSuccesor,' -> ');
P := P^.URM
end;
write (' NIL');
writeln;
writeln
end;
readln
END.
102
inceputul
CONST
nmax = 100;
TYPE
LISTA = ^ELEMENT;
ELEMENT = RECORD
NodSuccesor : integer;
URM : LISTA
{pointer
de
legatura
spre
urmatorul nod din lista}
END;
VAR
L : array [1..nmax] of LISTA;
m, n, i : integer; { n = nr. de NODURI; m = nr. de ARCE
}
P : LISTA ;
{ P = pointer de lucru}
x, y : integer;
{ x, y = extremitatile unui arc }
GradInt, GradExt : array [1..nmax] of integer ;
S : integer ;
{ S = suma gradele interior si
exterior pt. un varf }
f : TEXT;
{fisier in care memoram
informatiile despre GRAF }
linie : STRING ;
{ "linie" = o linie din fisierul
text GRAF.TXT }
ER : integer;
{ variabila eroare din apelul
procedurii VAL }
Begin { PROGRAM
CLRSCR;
writeln;
PRINCIPAL }
INC ( GradExt [ i ] );
INC ( GradInt [ P^.NodSuccesor] );
P := P^.URM
end;
writeln
end;
writeln;
writeln ('Gradele nodurilor sunt urmatoarele:');
writeln;
for i := 1 to n do
begin
writeln ('GradExt ( ', i,' ) = ', GradExt [i] );
writeln ('GradInt ( ', i,' ) = ', GradInt [i] );
S := GradExt [ i ] + GradInt [ i ] ;
writeln;
writeln ('Suma gradelor = ', S );
writeln ;
writeln;
if GradExt [ i ] + GradInt [ i ] = 0 then
writeln ('Nodul ', i,' este IZOLAT');
end;
readln
END.
106
107
Rezolvare:
1
4
5
Considerm graful din figura alturat.
Notm cu GradExt, respectiv GradInt,
gradul exterior i interior al fiecrui
2
3
6
vrf.
Dac pentru un vrf suma celor dou
NOD GradExt GradInt Suma grade
grade este zero, acel vrf este izolat.
1
2
1
3
2
2
1
3
De asemenea, un vrf este izolat dac
3
2
2
4
i numai dac linia i i coloana i
4
2
2
4
din matricea de ADIACEN au
5
0
2
2
toate elementele NULE.
6
0
0
0
Un drum ntr-un graf orientat este un ir
de vrfuri. Un drum se poate scrie fie ca o succesiune de arce, fie ca o succesiune de
vrfuri.
Dac toate arcele unui drum sunt distincte, iar primul i ultimul nod coincid,
drumul se numete circuit.
Dac toate vrfurile unui circuit, cu excepia primului i ultimului, sunt distincte,
circuitul este elementar.
Pentru graful alturat, avem circuitele:
C1 = (1, 2, 3, 4, 1, 3, 4, 1), C2 = (1, 3, 4, 1, 2, 3, 4, 1)
precum i circuitele elementare:
C3 = (1, 2, 4, 1), C4 = (1, 3, 4, 1), C5 = (1, 2, 3, 4, 1)
Pentru graful de mai sus, avem:
Matricea de ADIACEN:
Nod
1
A = 2
3
4
5
6
1
0
0
0
1
0
0
2
1
0
0
0
0
0
3
1
1
0
0
0
0
4
0
1
1
0
0
0
5
0
0
1
1
0
0
Matricea DRUMURILOR:
6
0
0
0
0
0
0
Nod
1
B = 2
3
4
5
6
1
1
1
1
1
0
0
2
1
1
1
1
0
0
3
1
1
1
1
0
0
4
1
1
1
1
0
0
5
1
1
1
1
0
0
6
0
0
0
0
0
0
Pentru a verifica dac graful conine noduri izolate, declarm doi vectori zeropelin si
zeropecol in care memorm numarul de zero-uri de pe fiecare linie, respectiv fiecare
coloan. Apoi, pentru fiecare linie din matricea de ADIACEN, verificam dac este
ndeplinit condiia
( zeropelin [ i ] = n) AND (zeropecol [ i ] = n)
adic, simultan pe linia i i coloana i avem numai zero-uri (n zero-uri).
Se observ c, n matricea de ADIACEN linia 6 i coloana 6 au toate elementele
nule. Rezult c nodul 6 este nod izolat.
Pentru a verifica dac graful are circuite, se verific dac matricea drumurilor
conine elemente egale cu 1 pe diagonala principal. Din faptul c matricea
drumurilor are numai elemente de 1 pe diagonala principal deducem doar c fiecare
108
vrf aparine unui circuit; NU rezult c exist un circuit care trece prin toate nodurile
grafului.
program
ATESTAT_2005_24_CIRCUITE_MATRICEA_DRUMURILOR_ALGORITMUL_RO
Y_WARSHALL;
uses CRT;
CONST
nmax = 100;
TYPE
matrice = array [1..nmax, 1..nmax] of integer;
109
VAR
n : integer; {n = numarul nodurilor}
m : integer; {numarul de muchii din graf}
x, y : integer; { extremitati ale unei muchii}
A : matrice; {matricea de adiacenta}
B : matrice; {matricea drumurilor}
i, j, k : integer;
zeropelin : array [1..nmax] of integer;
{vector in care memoram numarul zero-urile gasite
pe o linie }
zeropecol : array [1..nmax] of integer;
{vector in care memoram numarul zero-urile gasite
pe o coloana }
GASIT : boolean ; {testeaza daca exista circuite in graf
}
function MIN ( alfa, beta : integer) : integer;
begin
if alfa <= beta then
MIN := alfa
else
MIN := beta
end;
Begin { PROGRAM PRINCIPAL }
{ CLRSCR;}
write ('Dati numarul de noduri, n = ');
readln (n);
write ('Dati numarul de muchii, m = ');
readln (m);
{Initializarea tuturor elementelor matricii de adiacenta
cu zero}
for i := 1 to n do
begin
for j := 1 to n do
begin
A [i, j] := 0
end;
end;
writeln;
{Completare matrice de adiacenta}
For i := 1 to m do
Begin
110
Writeln
('Dati
extremitatile
muchiei
',
i,
':');
Write ('Dati varful x = ');
readln (x);
Write ('Dati varful y = ');
readln (y);
A [x, y] := 1;
{matricea NU este simetrica}
End;
writeln;
writeln ('Matricea de ADIACENTA este:');
for i := 1 to n do
begin
writeln;
for j := 1 to n do
begin
write
( A [i, j] : 3 ); {se lasa 3
pozitii pentru fiecare }
{element
al
matricii }
end;
end;
writeln;
111
{ Verificam, in
varfuri IZOLATE }
matricea
de
ADIACENTA,
daca
exista
for i := 1 to n do
begin
zeropelin [ i ] := 0;
for j := 1 to n do
begin
if A [i, j] = 0 then
zeropelin [i] := zeropelin [i] + 1;
end
end;
for j := 1 to n do
begin
zeropecol [ j ] := 0;
for i := 1 to n do
begin
if A [i, j] = 0 then
zeropecol [ j ] := zeropecol [ j ] + 1;
end
end;
writeln;
113
for i := 1 to n do
begin
writeln ('zeropelin [ ',i,' ] = ', zeropelin [
i ] );
writeln ('zeropecol [ ',i,' ] = ', zeropecol [
i ] );
writeln
end;
for i := 1 to n do
begin
if ( zeropelin [ i ] = n) AND (zeropecol [ i ]
= n) then
writeln ('Varful ', i,' este izolat') ;
writeln
end;
{ Verificam, in matricea de DRUMURILOR, daca exista 1 pe
diagonala principala }
GASIT := FALSE; {presupunem ca nu exista circuite in
graf }
for i := 1 to n do
begin
if B [i, i] = 1 then
GASIT := TRUE
end;
if GASIT = TRUE then
writeln ('Graful contine circuite')
else
writeln ('Graful NU contine circuite');
readln
END.
115
s := SUMA (n);
writeln ('S ( ', n, ') = ', s);
s:=2;
for i := 1 to n do
begin
writeln ('SUMA ( ', i, ' ) = ', SUMA (i) );
s := s + SUMA (i);
end;
readln
END.
117
s1 := 0;
for i := 1 to NRCIFRE (nr) do
begin
S1 := s1 + y [i] ;
end;
SUMACIFRE := s1
end;
Begin
{ PROGRAM PRINCIPAL }
write ('Introduceti un numar natural x = ');
readln (x);
n := NRCIFRE (x);
writeln ('Numarul ',x,' are ',n,' cifre');
writeln;
119
x1 := x;
{conservam valoarea numarului initial x,
folosind auxiliarul x1}
for i := 1 to n do
begin
y [ i ] := x1 MOD 10;
writeln ('y [',i,'] = ', y [i]);
x1 := x1 DIV 10;
end;
s := SUMACIFRE (x);
writeln ('Suma cifrelor numarului ', x, ' = ', s);
readln
END.
i:=1;
R[i] := 0
end
else
begin
i := 0;
ZECIMAL := nr10;
while nr10 <> 1 do
begin
rest := nr10 MOD 2;
i := i + 1;
R [i] := rest;
nr10 := nr10 DIV 2;
end;
i := i + 1;
r [i] := nr10;
end;
n := i;
121
writeln;
write ('Numarul binar echivalent lui ', ZECIMAL,' este
');
for i := n downto 1 do
begin
write ( R[i] );
end;
readln
END.
program
ATESTAT_2005_28_TRANSFORMARE_BAZA_10_IN_BAZA_B_VARIANTA_IT
ERATIVA_2;
uses CRT;
type
vector = array [1..100] of integer;
VAR
ZECIMAL, BINAR, nr10 : integer; {numarul zecimal}
nr2inversat, nr2 : integer; {numar binar inversat
respectiv nr binar final}
R : vector;
baza, n, i, j, k, rest : integer;
Begin { PROGRAM PRINCIPAL }
clrscr;
write ('Dati numarul zecimal nr10 = ');
readln (nr10);
write ('Dati noua baza = ');
readln (baza);
i := 0;
ZECIMAL := nr10;
while nr10 <> 0 do
begin
rest := nr10 MOD baza;
i := i + 1;
R [i] := rest;
nr10 := nr10 DIV baza;
end;
n := i;
write ('Numarul in baza ', baza,' echivalent este
');
for i := n downto 1 do
begin
write ( R[i] );
122
end;
readln
END.
program
ATESTAT_2005_28_TRANSFORMARE_BAZA_10_IN_BAZA_2_VARIANTA_RE
CURSIVA;
var
n: integer;
b: byte;
procedure conversie (x: integer; b:byte);
var r:byte;
begin
if x>0 then
begin
r:=x mod b;
conversie (x div b, b);
write(r);
end;
end;
123
Begin
{ PROGRAM PRINCIPAL }
write ('Dati numarul de cuvinte, n = ');
readln (n);
for i := 1 to n do
begin
write ('Introduceti cuvintul ', i,'
');
readln (sir);
siruri [i] := sir;
end;
writeln;
writeln ('********************************');
for i := 1 to n do
begin
writeln (siruri [i] : 20, '
', INVERS (
siruri [i] ) );
end;
readln
END.
125
{ PROGRAM PRINCIPAL }
clrscr;
write ('Dati sirul (max 8 caractere), sir = ');
readln (sir);
L := LENGTH (sir);
sir := COPY (sir, 1, L - 1);
writeln ('Noul sir = ', sir);
writeln;
writeln ('********************************');
sir2 := INVERS (sir);
writeln ('sir 2 = ', sir2 );
readln
END.
126
ALGORITMI FUNDAMENTALI
CARE LUCREAZ CU TABLOURI
(varianta iterativ)
ATESTAT - 2005 - 31 - S se citeasc din fiierul standard de intrare un numr
natural x. S se creeze un fiier text, numit FACTORI.TXT cu structura :
- pe prima linie se va scrie valoarea lui x;
- pe urmtoarele linii se vor scrie factorii primi i puterile lor, n descompunerea
lui x n factori primi (cte un factor pe o linie).
S se citeasc fiierul creat i s se afieze pe ecran descompunerea numrului x.
127
Barem:
- declaraii i citire corect: 1 punct
- algoritmul de descompunere n factori primi: 3 puncte
- crearea fiierului FACTORI.TXT: 2 puncte
- listarea coninutului fiierului: 3 puncte
- din oficiu: 1 punct
Rezolvare:
n ipoteza c fiierul text nu exist deja pe disc, vom crea acest fiier cu acelai
program care face i celelalte determinri cerute de enun.
Dup citirea de la tastatur a numrului x, l vom converti ntr-un ir de caractere,
notat sirx, prin apelarea procedurii STR. Introducem n fiierul text irul
sirx asociat numrului x.
n fiierul text se vor introduce att factorii primi n care se descompune x, ct i
puterile lor, astfel:
Transformm factorii n sir1, iar puterile n sir2
Dup fiecare astfel de numr transformat n ir, fie vom lsa cte un singur
spaiu liber (blank), fie vom aduga un comentariu (un ir de caractere). n acest fel,
se va crea, prin CONCATENARE, cte o linie n fiierul text. Evident, linie este
tot un ir de caractere.
Celelalte etape sunt comentate direct n program.
program ATESTAT_2005_31_FACTORI_PRIMI_SI_PUTERILE_LOR;
{ Fie x un numar natural. Afisati factorii primi ai lui x
si puterile lor }
CONST
nmax = 1000;
TYPE
vector = array [1..nmax] of integer;
VAR
f : TEXT;
linie : string;
sirx, sir1, sir2 : string;
putere : vector; {retinem in vectorul "putere" puterea
unui factor prim}
divizor : vector; {"divizor" = vector in care se retin
factorii primi}
x, d : integer;
divmax : integer; {divizorul sau factorul prim maxim}
{d = un divizor oarecare, curent}
Begin
{ PROGRAM PRINCIPAL }
ASSIGN (f, 'C:\FACTORI.TXT');
REWRITE (f);
128
129
while x > 1 do
begin
If x MOD d = 0 then
{daca x se imparte la
d}
begin
putere [d] := putere [d] + 1;
x := x DIV d;
end
else
begin
d := d + 1;
divizor [d] := d;
putere [d] := 0
end;
end;
writeln;
divmax := d;
for d := 2 to divmax do
begin
if putere [d] <> 0 then
begin
writeln ('Divizorul ', divizor [d],
' apare la puterea a ', putere [d]
, '-a');
STR (divizor [d], sir1); {transform divizor [d]
in sir1}
STR (putere [d], sir2);
in sir2}
linie := 'Divizorul ' + sir1 + ' apare la
puterea a ' + sir2 + '-a';
APPEND (f); {APPEND, deoarece am scris deja
sirx in f}
writeln (f, linie);
end
end;
writeln;
writeln ('Continutul fisierului este:');
RESET (f);
while NOT EOF (f) do
begin
readln (f, linie);
writeln (linie)
130
end;
readln
end.
131
Rezolvare: Folosim funcia STR pentru conversia unui numr ntr-un ir, la
introducerea elementelor matricii n fiier.
program ATESTAT_2005_32_ELEMENT_MAX_IN_MATRICE;
uses CRT;
LABEL
100;
CONST
nmax = 100;
TYPE
matrice = array [1..nmax, 1..nmax] of integer;
VAR
m, n, i, j, MAX : integer;
f : TEXT;
A : matrice;
sir, sir1, sir2, linie : STRING;
begin
CLRSCR;
ASSIGN (f, 'C:\MATRICE.txt');
rewrite (f); {generam fisierul text}
{ --------------------------------------------------------------------- }
{ scriem pe prima linie din fisierul TEXT cele doua
valori "m" si "n" }
linie := ''; { initializare variabila "linie" cu sirul
vid }
{ "linie" = un STRING care se va introduce
in fisierul text }
{ Prima "linie" va contine "m" si "n"
separate de spatii }
{ Urmatoarele "m" linii vor contine cate
"n" elemente separate de
spatii }
writeln ;
write ('Dati numarul de linii, m = ');
readln (m);
STR (m, sir1); {transforma "m" in "sir1", pentru a-l
memora in fisier}
linie := linie + sir1 + ' '; {construim "linie" prin
concatenare,}
{scriind un "spatiu" dupa
fiecare sir }
132
writeln;
write ('Dati numarul de coloane, n = ');
readln (n);
STR (n, sir2); {transforma "n" in "sir2", pentru a-l
memora in fisier}
linie := linie + sir2 ; {construim "linie" prin
concatenare cu vechea valoare}
{ a sirului "linie" }
writeln (f, linie);
fisierul TEXT }
writeln;
{ Introducerea matricii }
writeln ;
writeln ('Dati matricea');
writeln;
for i := 1 to m do
begin
for j := 1 to n do
begin
write ('Dati A [ ', i,',',j, ' ] = ');
readln ( A [i, j] );
end;
end;
writeln;
133
end;
writeln ;
writeln ('Continutul fisierului TEXT este :');
writeln;
RESET (f);
WHILE NOT EOF (f) do
begin
readln (f, linie);
writeln (linie)
end;
writeln;
RESET (f);
{ Se citesc din fisier dimensiunile matricii }
Read (f, m);
Readln (f, n);
{ Se citesc din fisier elementele matricii }
for i := 1 to m do
begin
for j:=1 to n do
134
begin
Read (f, A [i, j]);
end;
Readln (f);
{ avansul la linia urmatoare in
fisier }
end;
Close (f);
{ Determinare element MAXIM }
MAX := ABS ( A [1, 1] );
for i := 1 to m do
begin
for j := 1 to n do
begin
if ABS ( A [i, j] ) >= MAX then
begin
MAX := ABS ( A [i, j] ) ;
end;
end;
end;
135
writeln;
writeln ('Elementul maxim, in modul, este : ', MAX );
writeln;
writeln ('Linia / liniile pe care se afla elementul
cautat : ');
writeln;
for i := 1 to m do
begin
for j := 1 to n do
begin
if ABS ( A [i, j] ) = MAX then
begin
writeln ('Elementul cautat se afla pe Linia
= ', i );
GOTO 100; { daca MAX a fost gasit
intr-o linie, }
{ trecem la urmatoarea
linie }
end;
end;
100 :
end;
readln;
end.
nmax = 30;
type
vector = array [1..nmax] of integer;
matrice = array [1..nmax, 1..nmax] of integer;
var
f : file of integer;
A : matrice;
linia : vector;
n, j, i, m : integer;
t, suma, index : integer;
procedure BUBBLE (var v : vector; nr:integer);
var
k1, j : integer;
aux : integer;
137
begin
repeat
k1:= 0;
j := 1;
repeat
if v[j] > v [j+1] then
begin
aux := v [j];
v [j] := v [j+1];
v [j+1] := aux;
k1 := 1
end;
j := j + 1
until (j > nr - 1)
until (k1 = 0);
end;
procedure ORDONEAZA (var v : vector; nr : integer ); {alt
algoritm de sortare}
var
aux : integer;
begin
for t := 1 to nr - 1 do
begin
for j := t + 1 to nr do
begin
if v [t] < v [j] then
begin
aux := v [t];
v [t] := v [j];
v [j] := aux
end;
end;
end;
end;
procedure TIPARESTE (x:vector; nr:integer);
begin
for t := 1 to nr do
write ( x [t],',')
end;
Begin { PROGRAM PRINCIPAL }
clrscr;
ASSIGN (f, 'c:\intregi.txt');
rewrite (f);
repeat
write ('Dati numarul de linii, m = ');
readln (m);
138
139
for i := 1 to m do
begin
for j := 1 to n do
begin
linia [j] := a [i,j];
end;
writeln;
TIPARESTE (linia, n);
readln;
end;
suma := m + n;
index := suma mod 2;
case index of
0 : begin
for i := 1 to m do
begin
for j := 1 to n do
begin
linia [j] := a[i, j];
end;
write ('linia ', i,'
este
');
begin
for i := 1 to m do
begin
for j := 1 to n do
begin
linia [j] := a[i, j];
end;
140
141
143
writeln;
writeln ('Dati elementele multimii A');
for i := 1 to m do
begin
write ('A [ ', i,' ] = ');
readln ( A [i] );
end;
writeln;
writeln ('Dati elementele multimii B');
for i := 1 to n do
begin
write ('B [ ', i,' ] = ');
readln ( B [i] );
end;
145
Ma := [];
for i := 1 to m do
begin
Ma := Ma + [ A[i] ]; {construiesc Ma prin
reuniune }
end;
Mb := [];
for i := 1 to n do
begin
Mb := Mb + [ B[i] ]; {construiesc Ma prin
reuniune }
end;
INTERS := Ma * Mb;
writeln;
writeln ('Elementele multimii INTERS sunt :');
for elem := 0 to 255 do
begin
if elem IN INTERS then
write (elem,' , ');
end;
readln
END.
var
a, b : vector;
DIFER, Ma, Mb : set of byte;
elem, m,n,i,j : integer;
Begin
{ PROGRAM PRINCIPAL }
repeat
write ('Dati nr. de elemente ale multimii A, m =
');
readln (m)
until (m >= 1 ) AND (m <= nmax);
repeat
write ('Dati nr. de elemente ale multimii B, n =
');
readln (n)
until (n >= 1 ) AND (n <= nmax);
writeln;
147
149
151
Rezolvare: Ordonm vectorii prin metoda bubble sort, dup care interclasm vectorii.
program ATESTAT_2005_38_INTERCLASARE;
uses CRT;
const
Nmax = 30;
type
vector = array [1 .. Nmax] of integer;
var
A, B : vector;
C : array [1 .. 2 * Nmax] of REAL;
i, j, m, n, k : integer;
procedure ORDONEAZA (VAR v : vector; q:integer);
var
k1, t: integer;
aux : integer;
begin
repeat
k1:= 0;
t := 1;
repeat
if v [t] > v [t+1] then
begin
aux := v [t];
v [t] := v [t+1];
v [t+1] := aux;
k1 := 1
end;
t := t + 1
until (t > q-1)
until ( k1 = 0);
end;
Begin { PROGRAM PRINCIPAL }
clrscr;
REPEAT
write ('Dati nr. de elemente pentru vectorul A,
m = ');
readln (m);
UNTIL (m >=1) AND (m <= Nmax);
writeln;
REPEAT
write ('Dati nr. de elemente pentru vectorul B,
n = ');
readln (n);
UNTIL (n >=1) AND (n <= Nmax);
writeln;
152
153
{ Algoritmul de INTERCLASARE }
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;
writeln;
writeln ('Vectorul rezultant C este:');
for k := 1 to m + n do
begin
writeln ('C [k] = ', C [k])
end;
readln
END.
154