Sunteți pe pagina 1din 8

Universitatea Tehnică a Moldovei

Facultatea Calcultoare, Informatică şi Microelectronică


Departamentul Informatică şi Ingineria Sistemelor

RAPORT
la lucrarea de laborator nr. 6, 7

la Structuri de Date și Algoritmi

Tema: Analiza algoritmilor ale TEHNICII PROGRAMĂRII

Varianta 1

A efectuat: st. gr. TI-183 Bortă Sergiu

A verificat: Mititelu Vitalie

Chişinău – 2019
Sarcina şi obiectivele:
1. De studiat şi însuşit materialul teoretic pentru evidenţierea esenţialului tehnicilor de
programare în elaborarea modelelor soluţiei problemelor: esenţa metodelor (strategiilor tehnicilor de
programare) şi specificul realizării;
2. să se analizeze şi să se descrie tehnica modelării şi scenariile programării eficiente pentru
diverse compartimente ale diferitor situaţii cu argumentări şi modele de structuri abstracte;
3. să se preia varianta problemei din compartimentul “3.Problemele cu exemple pentru însuşire,
modificare şi rulare”, pentru analiza aplicatiilor, aprofundare şi rularea programelor în limbajul C
4. la lucrarea de laborator Nr.7 să se elaboreze scenariile succinte de modificare in baza
Metodelor euristice pentru variantele cu grafuri, incluzând pointeri, subprograme şi fişiere cu teste
de verificare şi vizualizări şi explicaţii la principalele raţionamente Euristice, incluse in subprograme.
În raport de descris concis esenţa fiecărei metode ( ca strategie sau tehnică de programare).

Consideraţiile teoretice şi exemple

Tehnica de programare “ Divide et Impera”


Tehnica “ Divide et Impera” constă în două etape:

 Divide. Problema dată este împărţită în două sau mai multe subprobleme de acelaşi tip, dar de
dimensiuni mai mici. Subproblemele se rezolvă direct, dacă dimensiunea lor permite aceasta (cazuri
elementare), sau, fiind de acelaşi tip, se rezolvă în mod recursiv, prin acelaşi procedeu.
 Impera. Se combină soluţiile subproblemelor pentru a obţine soluţia problemei iniţiale.

Restricţii
Metoda Divide Et Impera se poate aplica în rezolvarea unei probleme care îndeplineşte următoarele
condiţii :
- se poate descompune în ( două sau mai multe) suprobleme ;
- aceste subprobleme sunt independente una faţă de alta (o subproblemă nu se rezolvă pe baza
alteia şi nu se foloseşte de rezultatele celeilalte);
- aceste subprobleme sunt similare cu problema iniţială;
- la rândul lor subproblemele se pot descompune (dacă este necesar) în alte subprobleme mai
simple;
- aceste subprobleme simple se pot soluţiona imediat prin algoritmul simplificat.

Evident nu toate problemele pot fi rezolvate prin utilizarea acestei tehnici. Fără teamă de a greşi,
putem afirma că numărul lor este relativ mic, tocmai datorită restricţiilor de mai sus.

Pentru a intui funcţionarea algoritmului luăm ca exemplu un turneu de tenis. Participanţii sunt împărţiţi în
două grupe- se organizează turneul în cadrul fiecărei grupe, iar finala se va disputa între cei doi câştigători ai
turneului pe grupe. Câştigătorul finalei este câştigătorul întregului turneu. Organizarea turneului pe grupe se
face după acelaşi procedeu: se împart concurenţii din cadrul grupei pe semigrupe, se organizează turneul pe
semigrupe, iar câştigătorul grupei se decide într-un meci de semifinală între cei doi câştigători din cele două
semigrupe ş.a.m.d. Împărţirea se repetă până când avem doar doi jucători, care joacă un meci “direct”.
Schema generală
Metoda Divide Et Impera admite o implementare recursivă, deorece subproblemele sunt similare problemei
iniţiale, dar de dimensiuni mai mici .
Principiul fundamental al recursivităţii este autoapelarea unui subprogram când acesta este activ; ceea ce se
intamplă la un nivel, se intamplă la orice nivel, având grijă să asigurăm condiţia de terminare a apelurilor
repetate. Asemănător se intâmplă şi în cazul metodei Divite Et Impera ; la un anumit nivel sunt doua
posibilităţi:
 s-a ajuns la o (sub)problemă simplă ce admite o rezolvare imediată, caz în care se rezolvă
(sub)problema şi se revine din apel (la subproblema anterioară, de dimensiuni mai mari);
 s-a ajuns la o (sub)problemă care nu admite o rezolvare imediată, caz în care o descompunem in
două sau mai multe subprobleme şi pentru fiecare din ele se continuă apelurile recursive (ale
procedurii sau funcţiei).

În etapa finală a metodei Divide Et Impera se produce combinarea subproblemelor (rezolvate deja) prin
secvenţele de revenire din apelurile recursive.
Etapele metodei Divide Et Impera- prezentate anterior, se pot reprezenta prin următorul subprogram general
recursiv exprimat în limbaj natural:

Subprogram DIVIMP (X);


Dacă PROBLEMA X este simplă
Atunci se rezolvă şi se obţine soluţia SOL
Altfel pentru i=1,k execută DIVIMP(X) şi se obţine SOL1;
Sf _dacă
Se combina soluţiile SOL 1,... ,SOL K şi se obţine SOL;
Sf _subprogram;

Deci, subprogramul DIVIMP se apelează pentru problema iniţială X; aceasta admite descompunerea în K
subprobleme simple; pentru acestea se reapelează recursiv subprogramul; în final se combină soluţiile
acestor K subprobleme.

Identificarea dimensiunii subproblemelor


În general un subprogram Divide Et Impera se aplică unui tablou (vector) V = <v 1,...,vn> (V[1..n], n=dim[V]),
asupra căruia vrem sa aplicăm o operaţie oarecare (sortare, determinarea valorii maxime, determinarea
cmmdc, etc).
Identificarea modalităţii de împărţire în subprobleme
În acest caz se execută împărţirea în două subprobleme de dimensiuni aproximativ egale şi anume [n/2] .
Împărţirea în subprobleme are loc până când dimensiunea acestora devine suficient de mică pentru a fi
rezolvate în mod direct (cazul de bază).
Rezolvarea subproblemelor
Se rezolvă subproblema directă.
Combinarea soluţiilor
După rezolvarea celor două subprobleme se execută faza de combinare a rezultatelor în vederea rezolvării
întregii probleme. Se face prin interclasarea soluţiilor.
Subprogramul divide
Subprogram DivImp(V,p,q)
      Daca q-p <= 1 atunci  Rezolva(V,p,q)
               altfel  m=(p+q) div 2
                         DivImp(V,p,m)
                         DivImp(V,m+1,q)
                         Combina(V,p,m,q)
      Sf_Daca
Sf_subprogram.
Apelul subprogramului
Iniţial p=1, q=n, rezultă DivImp(V,1,n).

Tehnica de programare “ Backtracking”


Această tehnică se foloseşte în rezolvarea problemelor care îndeplinesc simultan următoarele condiţii:
- soluţia lor poate fi pusă sub forma unui vector S= x1 x2 …, xn cu x1  A1, x2  A2
Xn  An ;
- mulţimile A1, A2 , …., An sunt mulţimi finite, iar elementele lor se consideră că se află într-o relaţie de
ordine bine stabilită;
- nu se dispune de o altă metodă de rezolvare, mai rapidă
- x1 x2 …, xn pot fi la rândul lor vectori;
- A1, A2 …, An pot coincide.
Tehnica Backtracking are la bază un principiu extrem de simplu:
- se construieşte soluţia pas cu pas: x1, x2 …,xn
- dacă se constată că, pentru o valoare aleasă, nu avem cum să ajungem la soluţie, se renunţă la
acea valoare şi se reia căutarea din punctul în care am rămas.
Concret:
- se alege primul element x, ce aparţine lui A;
- presupunând generate elementele x 1,x2 …,xk , aparţinând mulţimilor A1, A2 …,Ak se alege (dacă
există) xk+1 , primul element disponibil din mulţimea Ak+1 , apar două posibilităţi :
1) Nu s-a găsit un astfel de element, caz în care caz în care se reia căutarea considerând generate
elementele x1,x2 …,xk-1 , iar aceasta se reia de la următorul element al mulţimii Ak rămas netestat;
2) A fost găsit, caz în care se testează dacă acesta îndeplineşte anumite condiţii de continuare
apărând astfel două posibilităţi:
- îndeplineşte, caz în care se testează dacă s-a ajuns la soluţie şi apar din nou două posibilităţi:
- s-a ajuns la soluţie, se tipăreşte soluţia şi se reia algoritmul considerând generate elementele x 1,x2
…,xk , (se caută în continuare, un alt element al mulţimii Ak , rămas netestat);
- nu s-a ajuns la soluţie, caz în care se reia algoritmul considerând generate elementele x 1,x2 …,xk , şi
se caută un prim element xk+1 din Ak+1.
- nu le îndeplineşte, caz în care se reia algoritmul considerând generate elementele x 1,x2 …,xk , iar
elementul xk+1 se caută între elementele mulţimii Ak+1, rămase netestate.
Algoritmii se termină atunci când nu există nici un element x 1 din A1 netestat.
Observaţie: tehnica Backtracking are ca rezultat obţinerea tuturor soluţiilor problemei. În cazul în care se
cere o singură soluţie se poate forţa oprirea, atunci când aceasta a fost găsită.

Am arătat că orice soluţie se generează sub formă de vector. Vom considera că generarea soluţiilor se face
intr-o stivă. Astfel, x1 din A1, se va găsi pe primul nivel al stivei, x 2 din A2 se va găsi pe al doilea nivel al
stivei,... xk din Ak se va găsi pe nivelul k al stivei.
Nivelul k+1 al stivei trebuie iniţializat (pentru a alege, în ordine, elementele mulţimii k+1 ). Iniţializarea trebuie
făcută cu o valoare aflată (în relaţia de ordine considerată, pentru mulţimea A k+1 ) înaintea tuturor valorilor
posibile din mulţime. De exemplu, pentru generarea permutărilor mulţimii {1,2.....n}, orice nivel al stivei va lua
valori de la 1 la n. Iniţializarea unui nivel (oarecare) se face cu valoarea 0. Funcţia de iniţializare o vom numi
Init().
Găsirea următorului element al mulţimii Ak (element care a fost netestat) se face cu ajutorul funcţiei
Am_Suceeesor(). AS este o variabilă booleană. În situaţia în care am găsit elementul, acesta este pus în
stivă şi AS ia valoarea TRUE, contrar (nu a rămas un element netestat) AS ia valoarea FALSE..
Odată ales un element, trebuie văzut dacă acesta îndeplineşte condiţiile de continuare (altfel spus, dacă
elementul este valid). Acest test se face cu ajutorul funcţiei E_Valid().
Testul dacă s-a ajuns sau nu la soluţia finală se face cu ajutorul funcţiei Solutie() iar o soluţie se tipăreşte
cu ajutorul funcţiei Tipar(). Prezentăm în continuare rutina Back():
void back () {
int AS;
k=1;
Init();
while (k>0)
{
do {} while ((AS=Am_Suceeesor()) && !E_Valid());
if (AS)
if (Solutie()) Tipar();
else {k++; Init();}
else k--;
}
}
Observaţie: Problemele rezolvate prin această metodă necesită un timp îndelungat. Din acest motiv, este bine să
utilizăm metoda numai atunci când nu avem la dispoziţie un alt algoritm mai eficient. Cu toate că există probleme
pentru care nu se pot elabora alţi algoritmi mai eficienţi, tehnica backtracking trebuie aplicată numai în ultimă instanţă.

Tehnica de programare “ Greedy”


Restricţii
Să considerăm o mulţime A cu n elemente. Se cere o submulţime a sa cu m<=n elemente (în cazul m=n
este importantă ordinea alegerii elementelor), astfel încât să fie îndeplinite anumite condiţii (acestea diferă de
la o problemă la alta).
Schema generală Greedy
Pentru a rezolva o problemă cu Greedy, soluţia se construieşte, după regula:
Pentru fiecare element care urmează să fie adăugat soluţiei finale, se efectuează o alegere a sa din
elementele mulţimii A (după un mecanism specific fiecărei probleme în parte), iar dacă este posibil, acesta
este adăugat. Algoritmul se termină fie când a fost găsită soluţia cerută, fie când s-a constatat inexistenţa
acesteia.
Intuitiv, alegem un element, al doilea,...până când obţinem ce dorim sau până când au fost testate toate
elementele mulţimii. De aici provine şi numele metodei greedy (lacom).
Definiţie
Tehnica Greedy poate fi privită ca o particularizare a tehnicii Backtracking, în care se renunţă la mecanismul
de întoarcere.

Să analizăm, în paralel, cele două tehnici, pentru a putea stabili asemănările şi diferenţele existente între ele:
 ambele tehnici oferă soluţii sub formă de vector;
 tehnica Backtracking poate oferi toate soluţiile problemei, în timp ce tehnica Greedy oferă o
singură soluţie;
 tehnica Greedy nu dispune de mecanismul întoarcerii, specific tehnicii backtracking.

Tehnica Greedy conduce la timp de calcul polinomial.


Motivul care conduce la acest timp de calcul, ţine de mecanismul tehnicii.Să presupunem că mulţimea din
care se face alegerea are n elemente şi că soluţia are tot n elemente (caz maxim). Se fac n alegeri, la fiecare
alegere se fac n teste, rezultă un algoritm cu timp O(n 2).
Selectarea elementelor ce formează soluţia
De multe ori, este necesar ca elementele mulţimii A să fie sortate, pentru ca apoi să alegem din acestea, iar
sortarea necesită un timp minim O(nxlog 2n). Însă sortarea se efectuează la început. Prin urmare, acest timp
se adună, deci nu influenţează rezultatul.
O întrebare firească: fiind dată o problemă, există întotdeauna un algoritm de tip greedy care găseşte soluţia
optimă?Evident, nu. Există probleme pentru care nu se cunosc astfel de algoritmi.Mai mult, pentru cele mai
multe probleme, nu se cunosc algoritmi Greedy.
Generarea şi afişarea soluţiei.
Deoarece soluţia problemelor ce se rezolvă cu acestă tehnică este sub formă de vector, acesta se
completează pas cu pas şi apoi se afişează.

Sarcina laboratorului 6:
Considerăm urmãtoarea problemã (Săritura calului):
Se dã o tablã de şah. Se cere sã sa gãseascã un drum pe care îl parcurge un cal care porneşte dintr-un colţ şi
sare într-o poziţie liberã (în care nu a mai sărit) conform mutãrii de la jocul de şah. În acest mod, calul va
trebui sã treacã prin toate cãsuţele. În cazul în care problema nu are soluţie se va afişa un mesaj
corespunzãtor.
Rezolvare: În primul rând, se ţine de cont de modul în care se poate deplasa un cal pe tabla de şah. Faţã de o
anumitã poziţie, mutãrile calului implicã modificarea coordonatelor pe tabla de şah conform matricei Mutari.
Apoi, se porneşte din colţul de coordonate (0,0) şi se va încerca înaintarea. Condiţiile de continuare conţin:
calul sã nu depãşeascã marginile tablei şi poziţia pe care o va ocupa în urma mutãrii sã nu fie deja ocupatã.
Funcţia Rezolva va specifica dacã problema are soluţie.

Listing-ul programului:

#include<stdio.h>
#define MaxDim 8 //dimensiune maxima a tablei de sah
int Mutari[8][2]={{-1,-2},{-1,2},{1,-2},{1,2},{-2,-1},{-2,1},
{2,-1},{2,1}};
int Tabla[MaxDim][MaxDim]; //tabla de sah
int Dim; //dimensiunea tablei
int NrMutari; //numarul mutarilor
int NrSolutii; //numarul solutiilor

//afisarea unei solutii gasite


void Afis(){
int i,j;
printf("\n");
for(i=0;i<Dim;i++){
for(j=0;j<Dim;j++)
printf("%d ",Tabla[i][j]);
printf("\n");
}
}

//functie recursiva
void Recurs(int X, int Y){
int DX,DY; //coordonatele rezultate in urma deplasarii
int i;
NrMutari++;
Tabla[X][Y]=NrMutari;
if(NrMutari==Dim*Dim){
NrSolutii++;
Afis();
}
for(i=0;i<8;i++){
DX=X+Mutari[i][0];
DY=Y+Mutari[i][1];
if((DX>=0)&&(DX<Dim)&&(DY>=0)&&(DY<Dim)&&(Tabla[DX]
[DY]==0)){
//daca mutarea nu depaseste marginile tablei
//si careul nu a mai fost ocupat inainte
Recurs(DX,DY);
}
}
//se retrage mutarea, elibarand careul (X,Y)
NrMutari--;
Tabla[X][Y]=0;
}

//rezolvarea problemei
int Rezolva(){
int i,j;
if(Dim<3){
//nu se poate efectua nici o mutare
return 0;
}
else{
//initializari
if(Dim>MaxDim)
Dim=MaxDim;
for(i=0;i<Dim;i++)
for(j=0;j<Dim;j++)
Tabla[i][j]=0;
NrMutari=0;
NrSolutii=0;
//apelul metodei backtracking
Recurs(0,0);
//se porneste din careul stang-sus
if(NrSolutii>0) return 1; //exista solutii
else return 0; //nu exista solutii
}
}

//programul principal
int main(){
do{
printf("Dimensiunile tablei:");
scanf("%d",&Dim);
}while((Dim<=0)||(Dim>MaxDim));
if(Rezolva())
printf("\nSunt %d solutii\n",NrSolutii);
else
printf("\nProblema nu are solutii\n");
}

Execuţia programului:
...

Observație: Soluții la această problemă există pentru dimensiunile tablei >=5. Pentru o tablă
de șah adevărată cu dimensiunile 8*8 există 26,534,728,821,064 de soluții.

Sarcina laboratorului 7:
Colorați un graf neorientat astfel încât doua varfuri vecine să nu posede culori asemănătoare
utilizând un număr minim de culori.

Listing-ul programului:

#include<stdio.h>
int G[50][50]; //matricea de adiacenta
int x[50]; //culorile varfurilor

void backtracking(int n){


int i,j;
for(j=0;j<n;j++){
x[j]=0; //de fiecare data revenim si incepem colorarea varfului
//urmator cu culoarea 0
for(i=0;i<j;i++){ //verificam toate varfurile
if(G[i][j]!=0 && x[j]==x[i]) //daca sunt conectate si au
//aceeasi culoare cu varful dat
x[j]=x[i]+1; //atunci ii atribuim o culoare diferita
//de varful cu care e conex
}
}
}
int main(){
int n,m,i,j,k;
printf("Dati numarul de varfuri : ");
scanf("%d",&n);
printf("Dati numarul de muchii : ");
scanf("%d",&m);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
G[i][j]=0; //complatam matricea de adiacenta cu 0

printf("Scrieti varfurile care sunt conectate in graf\n");


//completam matricea de adiacenta
for(i=0;i<m;i++){
printf("Muchia %d) ",i);
scanf("%d %d",&k,&j);
G[k][j]=1;
G[j][k]=1;
}

backtracking(n); //coloreaza varfurile

printf("Culorile varfurilor:\n");
for(i=0;i<n;i++) //culoarea pentru fiecare varf
printf("Varful %d : %d\n",i,x[i]);

return 0;
}

Execuţia programului:

Reprezentarea grafului:

1 00

22 33

Concluzii:
În această lucrare am elaborat două programe (utilizând compilatorul C) pe baza utilizării
tehnicilor de programare și combinațiile acestora (în lucrarea dată am utilizat backtracking (lab. 6) și
backtracking în plan cu modificarea configurației (lab. 7)). În urma executării acestei lucrări de
laborator am însușit diferența dintre diferite metode de programare și am evidențiat avantajele și
dezavantajele fiecăreia.
În concluzie pot afirma că tehnicile de programare studiate ușurează cu mult situația la abordarea
problemelor, deoarece soluția gasită rezultă din rezolvarea pas cu pas a subproblemelor în urma
divizării problemei inițiale.

Bibliografia
Indicațiile metodice pentru lucrarea de laborator nr. 6. la Structuri de Date și Algoritmi.

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

  • Laborator-2 TS
    Laborator-2 TS
    Document13 pagini
    Laborator-2 TS
    Сергей Борта
    Încă nu există evaluări
  • Lucrare de Laborator nr.1 Tema: Cercetarea Microclimatului La Posturile de Lucru
    Lucrare de Laborator nr.1 Tema: Cercetarea Microclimatului La Posturile de Lucru
    Document14 pagini
    Lucrare de Laborator nr.1 Tema: Cercetarea Microclimatului La Posturile de Lucru
    VeronikaMalkoki
    Încă nu există evaluări
  • Laborator-4 TMPS Borta
    Laborator-4 TMPS Borta
    Document9 pagini
    Laborator-4 TMPS Borta
    Сергей Борта
    Încă nu există evaluări
  • Laborator-1 TMPS Borta
    Laborator-1 TMPS Borta
    Document10 pagini
    Laborator-1 TMPS Borta
    Сергей Борта
    Încă nu există evaluări
  • Laborator-5 TMPS Borta
    Laborator-5 TMPS Borta
    Document6 pagini
    Laborator-5 TMPS Borta
    Сергей Борта
    Încă nu există evaluări
  • Laborator-3 TMPS Borta
    Laborator-3 TMPS Borta
    Document7 pagini
    Laborator-3 TMPS Borta
    Сергей Борта
    Încă nu există evaluări
  • Composite&Builder
    Composite&Builder
    Document8 pagini
    Composite&Builder
    Сергей Борта
    Încă nu există evaluări
  • LP6 Matlab
    LP6 Matlab
    Document8 pagini
    LP6 Matlab
    Сергей Борта
    Încă nu există evaluări
  • Laborator-3 TMPS Borta
    Laborator-3 TMPS Borta
    Document7 pagini
    Laborator-3 TMPS Borta
    Сергей Борта
    Încă nu există evaluări
  • Laborator-2 TMPS Borta
    Laborator-2 TMPS Borta
    Document11 pagini
    Laborator-2 TMPS Borta
    Сергей Борта
    Încă nu există evaluări
  • Laborator-2 TMPS Borta
    Laborator-2 TMPS Borta
    Document11 pagini
    Laborator-2 TMPS Borta
    Сергей Борта
    Încă nu există evaluări
  • Laborator-1 TMPS Borta
    Laborator-1 TMPS Borta
    Document10 pagini
    Laborator-1 TMPS Borta
    Сергей Борта
    Încă nu există evaluări
  • TI183 BortaSergiu Lab3
    TI183 BortaSergiu Lab3
    Document5 pagini
    TI183 BortaSergiu Lab3
    Сергей Борта
    Încă nu există evaluări
  • Laborator-5 TMPS Borta
    Laborator-5 TMPS Borta
    Document6 pagini
    Laborator-5 TMPS Borta
    Сергей Борта
    Încă nu există evaluări
  • Laborator-4 TMPS Borta
    Laborator-4 TMPS Borta
    Document9 pagini
    Laborator-4 TMPS Borta
    Сергей Борта
    Încă nu există evaluări
  • Lab4 Programarea
    Lab4 Programarea
    Document6 pagini
    Lab4 Programarea
    Сергей Борта
    Încă nu există evaluări
  • LAB3 Matlab
    LAB3 Matlab
    Document13 pagini
    LAB3 Matlab
    Сергей Борта
    Încă nu există evaluări
  • LAB4 Matlab
    LAB4 Matlab
    Document20 pagini
    LAB4 Matlab
    Сергей Борта
    Încă nu există evaluări
  • Lab1 Programarea
    Lab1 Programarea
    Document7 pagini
    Lab1 Programarea
    Сергей Борта
    Încă nu există evaluări
  • Lab 5
    Lab 5
    Document9 pagini
    Lab 5
    Сергей Борта
    Încă nu există evaluări
  • LAB1
    LAB1
    Document4 pagini
    LAB1
    Сергей Борта
    Încă nu există evaluări
  • Lab 5
    Lab 5
    Document9 pagini
    Lab 5
    Сергей Борта
    Încă nu există evaluări
  • Lab2 Programarea
    Lab2 Programarea
    Document14 pagini
    Lab2 Programarea
    Сергей Борта
    Încă nu există evaluări
  • Lab 3
    Lab 3
    Document8 pagini
    Lab 3
    Сергей Борта
    Încă nu există evaluări
  • LAB2 Matlab
    LAB2 Matlab
    Document9 pagini
    LAB2 Matlab
    Сергей Борта
    Încă nu există evaluări
  • TI183 BortaSergiu Lab2
    TI183 BortaSergiu Lab2
    Document4 pagini
    TI183 BortaSergiu Lab2
    Сергей Борта
    Încă nu există evaluări
  • PR Lab2
    PR Lab2
    Document5 pagini
    PR Lab2
    Сергей Борта
    Încă nu există evaluări
  • Lab 1
    Lab 1
    Document3 pagini
    Lab 1
    Сергей Борта
    Încă nu există evaluări
  • Lab1 Pam
    Lab1 Pam
    Document9 pagini
    Lab1 Pam
    Ion Popescu
    100% (2)