Sunteți pe pagina 1din 14

7.

Metoda de programare Divide et Impera

7.1 Prezentare general


S ne imaginm c dorim s cutm un cuvnt n dicionarul explicativ. Dup
cum tim, n dicionar, cuvintele sunt ordonate alfabetic.
Presupunem c dorim s tim ce nseamn cuvntul paradigm. Deschidem
dicionarul la ntmplare. Am deschis la litera B, nu am ajuns la cuvntul cutat, dar
tim c el se afl undeva n partea dreapt a dicionarului, fa de litera B, nu este
necesar s mai cutm n tot dicionarul, deschidem i constatm c am ajuns la litera
S, de data aceasta tim c trebuie sa cutm n dicionar puin mai la stnga fa de
litera S. Repetm aceti pai pn ce vom gsi cuvntul cutat.
Prin urmare, am avut o carte mare n care trebuia s cautm un cuvnt, nu am
cutat cuvnt cu cuvnt de la nceputul crii, deoarece aceast operaiune ar fi durat
foarte mult, dar mai ales ne-am fi plictisit i am fi renunat s aflm ce nseamn
cuvntul paradigm. Cum am procedat?
Am mprit cartea n dou pri, urmnd s decidem n care parte vom cuta
mai departe. Deja problema s-a mai simplificat, pentru c nu mai aveam de cutat
ntr-o carte att de mare. Dac nc nu am gsit, am mprit din nou aceast parte a
crii n dou pri mai mici n care cutm mai uor i aa mai departe.

Prin urmare am mprit problema dificil n subprobleme mai simple, am


repetat operaiunea pn cnd am ajuns la subprobleme suficient de simple pe care le
putem rezolva cu usurin.

Divide et impera este o metoda general de elaborare a algoritmilor. n


cadrul acestei metode distingem trei etape:
Descompunerea problemei ce trebuie rezolvat n dou sau mai multe
subcazuri (subprobleme) mai mici ale aceleiai probleme.
Rezolvarea succesiv a fiecrui subcaz.
Recompunerea succesiv a soluiilor obinute penru fiecare subcaz, n vederea
determinrii soluiei problemei iniiale

Se poate spune c este o metod puternic de rezolvare a unor probleme


conceptual dificile, ca de exemplu Turnurile din Hanoi, generarea fractalilor, puzzle i
altele.

In mod natural metoda divide et impera se implementeaz recursiv, dar este posibil
s eliminm recursivitatea printr-un ciclu iterativ.

Compararea implementrii recursive cu cea iterativ


Implemantarea iterativ poate fi mai rapid i economisete memorie, deoarece nu
se fac reapelri succesive de funcii, crendu-se noi niveluri de stiv. Totui recompunerea
soluiei problemei iniiale din soluiile subproblemelor poate fi dificil n cazul implementrii
iterative.

1
7.2 Exemple de implementare a metodei:
1. Dndu-se un ir ordonat cresctor de n numere ntregi i un numr ntreg x, s se
determine dac numrul x aparine irului i poziia pe care se gsete n ir.

Vom cuta numrul x doar n mijlocul irului.


Dac nu l gsim, avnd n vedere faptul c irul este ordonat cresctor, vom cuta
numrul x n continuare, doar n jumtatea n care ar putea s existe.
Aceast rezolvare a problemei cutrii unui numr ntr-un ir ordonat de numere, este
cunoscut i sub denumirea de cutare binar.

Descrierea algoritmului:
Se citete irul ntr-un tablou unidimensional a. Notm cu li limita inferioar a irului
(indicele cel mai din stnga), cu ls limita superioar a irului (indicele cel mai din dreapta)
i cu m indicele din mijlocul irului.
Dac li <= ls nseamn c n ir mai sunt elemente printre care trebuie sa-l cutm pe
x. Determinm m=(li+ls)/2, indicele din mijlocul irului.
Verificm daca elementul de pe poziia m este chiar x.
dac da, funcia se termin returnnd poziia m pe care se gsete x
altfel, se verific dac x<a[m]
atunci se reapeleaz funcia pentru subsirul cuprins ntre li i ls=m 1
altfel se reapeleaz funcia pentru subsirul cuprins ntre li=m + 1 i ls.
Dac li>ls nseamn c x nu se gsete n ir iar funcia returneaz 1.

Implementarea recursiv a problemei:


#include<iostream.h> //CUTAREA BINAR
const MAX=20;
int a[MAX];
int cauta(int li,int ls,int x);
void main()
{ int n,m,x;
cout<<"n=";cin>>n; // se citete n-numrul de elemente al irului
for(int i=0;i<n;i++)
{cout<<"a["<<i<<"]="; cin>>a[i];} //se citesc elementele irului
cout<<"x=";cin>>x; //se citete elementul cautat x
m=caut(0,n-1,x); //apelul funciei cauta
if (m!= -1)
cout<<x<<" se gaseste pe pozitia "<<m; //indicele elementului x n ir
else
cout<<x<<" nu se gaseste in sir"; //dac funcia returneaz 1, x nu se gsete n ir
}
int cauta(int li,int ls,int x) // li-limita inferioara a irului, ls-limita superioar a irului
{int m;
if(li<=ls)
{m=(li+ls)/2; // m-indicele din mijlocul irului
if (x==a[m]) //se compar x cu elementul din mijlocul irului
return m; //returneaz indicele elementului de tablou, unde se gsete x
else
if (x<a[m]) //se compar x cu elementul din mijlocul irului
return cauta(li,m-1,x); //dc x este mai mic dect elementul din mijloc, se va cuta n
else //continuare n jumtatea stng a irului
return cauta(m+1,ls,x);} //n caz contrar se caut x n jumtarea dreapt a irului
else return -1; //dac nu mai avem unde cuta, nseamn c x nu se gsete n
} //ir

2
Implementarea iterativ a funciei cauta:

int cauta(int li,int ls,int x) // li-limita inferioara a irului, ls-limita superioar a irului
{int m;
while (li<=ls) //atta timp cr li <= ls nseamn c n ir mai sunt elemente
{ //printre care trebuie sa-l cutm pe x.
m=(li+ls)/2; // m-indicele din mijlocul irului
if(x==v[m]) //se compar x cu elementul din mijlocul irului
return m; //returneaz indicele elementului de tablou, unde se gsete x
if(x<v[m])
ls=m-1; //dc x este mai mic dect elementul din mijloc, se modifica ls
else
li=m+1; //n caz contrar se modific li
}
return -1; //dac x nu a fost gsit, funcia returneaz -1
}

2.. Se citete un ir de n numere ntregi. S se determine elementul maxim din ir.

Vom aplica metoda divide et impera astfel: irul iniial l mprim n dou
subiruri, apoi le mprit pe acestea n alte dou subiruri i aa mai departe, pn
cnd ajungem la un singur element.Cu siguran, dac un ir conine un singur
element, este foarte simplu s spunem care este cel mai mare element al irului.
Iat c mprind irul am ajuns la probleme suficient de simple pe care s le
rezolvm cu mare uurin.
Dup ce determinm maximul pe fiecare subir, recompunem soluiile pentru a
determina n final maximul irului iniial.

Exemplu: Fie iul 3 7 5 9 8 4 6

3 7 5 9 8 4 6

3 7 5 9 8 4 6

3 7 5 9 8 4 6

7 5 9 8 4 6

7 9 6

7 9

3
Descrierea algoritmului:
Notm cu li indicele reprezentnd limita inferioar a subsirului i cu ls indicele
reprezentnd limita superioar a irului.
Determinm indicele m din mijlocul irului.
Folosim dou variabile a n care vom pstra maximul subsirului stng (de la li la
m) i b n care vom pstra maximul subirului drept (de la m+1 la ls).
Funcia se reapeleaz pn cnd fiecare subir va conine un singur element.
Acest element l considerm ca fiind maximul pentru subirul respectiv.
Comparm maximele astfel obinute pntru fiecare subir, reinndu-se cel mai
mare dintre ele.

#include<iostream.h> //MAXIM
const MAX=20;
int v[20],n;

int maxim(int li,int ls);

void main()
{int i;
cout<<"n=";cin>>n;
for(i=0;i<n;i++)
{cout<<"v["<<i<<"]=";cin>>v[i];}
cout<<"elem. maxim="<<maxim(0,n-1);
}

int maxim(int li,int ls) //li-limita inferioara, ls-limita superioara


{int m,a,b;
if(li==ls) //dac subsirul conine un singur element, acela este
maximul
return v[li];
else
{m=(li+ls)/2; //determinam indicele din mijlocul irului
a=maxim(li,m); // a, va conine maximul pe subirul stng
b=maxim(m+1,ls); //b, va conine maximul pe subirul drept
if (a>b) // pe fiecare nivel de stiv se compar maximele obinute i
return a; //se returneaz cel mai mare dintre ele
else
return b;
}
}

3. Suma maxim n triunghi.


Fie un trunghi cu n linii (1<=n<=100). Pe fiecare linie i se gsesc i numere
ntregi.
S se determine cea mai mare sum fotmat din numere aflate pe un drum,
ntre numrul de pe prima linie i un numr de pe ultima linie.
Fiecare numr de pe acest drum este situat sub precedentul, la stnga sau la
dreapta acestuia.

4
Exemplu: pentru n= 4
5
4 0
3 8 2
2 7 9 6

5
#include <iostream.h> //SUMA MAXIMA
#define MAX 101
int t[MAX][MAX],n; //n-nr. linii, t-memoreaz elementele triunghiului
void citire();
void afisare();
int sumamax(int i,int j);

void main()
{citire();
afisare();
cout<<"suma maxima="<<sumamax(1,1);
}

void citire() //citete elementele triunghiului


{int i,j;
cout<<"n=";cin>>n;
for (i=1;i<=n;i++)
for(j=1;j<=i;j++)
{cout<<"t["<<i<<","<<j<<"]="; cin>>t[i][j]; }
}

void afisare() //afieaz elementele triunghiului


{int i,j,p;
p=(n-1)/2;
for(i=1;i<=n;i++)
{for (j=1;j<=n-p; j++) cout<<" ";
for (j=1;j<=i;j++) cout<<t[i][j]<<" ";
cout<<endl;
p=p+1;
}
}

int sumamax(int i,int j) //calculeaz suma maxim a elementelor din triunghi


{int a,b; //a-reine suma pe stnga, b-reine suma pe dreapta
if(i<=n)
{a=sumamax(i+1,j);
b=sumamax(i+1,j+1);
if(a>b) //decidem care sum este mai mare
return t[i][j]+a; //adun elementul triunghiului la suma cea mai mare
else
return t[i][j]+b;
}
return 0;
}

6
4. Turnurile din Hanoi
Fie trei tije i n discuri cu diametre distincte. Notm tijele cu literele A, B, C.
Cele n discuri se afl toate pe tija A, aezate n ordinea descresctoare a diametrelor.
Se cere s se mute cele n discuri de pe tija A pe tija B, folosind drept tij de manevr,
tija C, astfel:
- la un moment dat se mut un singur disc;
- niciodat un disc de diametru mai mare nu se afl peste un disc de diametru
mai mic.

exemplu:
pentru n=1 A B

pentru n=2 A C
A B

C B

pentru n=3 - se muta 2 discuri de pe A pe C folosind ca manevra tija, B la fel ca mai


sus
- se mut discul 3 de pe A pe B
- se aduc cele 2 discuri de pe C pe B folosind ca manevr tija A la fel ca
mai sus

.........................................................................................................................................

pentru n discuri:
- se muta n-1 discuri de pe A pe C folosind ca manevra tija B, la fel ca
mai sus
- se mut discul n de pe A pe B
- se aduc cele n-1 discuri de pe C pe B folosind ca manevr tija A, la fel
ca mai sus

#include<iostream.h> //HANOI
void hanoi(int n,char a,char b,char c);

void main()
{int n;
cout<<"n="; cin>>n; //n-numrul de discuri
hanoi(n,'A','B','C'); //apelul funciei hanoi nu parametri nr. discuri i cele 3 tije
}

void hanoi(int n,char a,char b,char c) //n-nr.discuri,a,b,c-cele trei tije


{if (n==1)
cout<<a<<"->"<<b<<endl; //se mut discul 1
else
{hanoi(n-1,a,c,b); //se mut n-1 discuri de pe tija A pe C folosind drept manevra tija B
cout<<a<<"->"<<b<<endl; //se mut discul n de pe A pe B
hanoi(n-1,c,b,a); //se mut n-1 discuri de pe tija C pe B folosind drept manevra tija A
}
}

7
5. S se determine cel mai mare divizor comun al unui ir de n numere naturale.

Vom mpri irul n dou subiruri, apoi fiecare subir n alte dou subiruri mai
mici, pn cnd subirurile astfel obinute vor conine cel mult dou elemente.
Pentru aceste elmente vom aplica algoritmul lui Euclid de determinare a celui
mai mare divizor comun.
Recompunem apoi soluiile astfel obinute pentru a determina cel mai mare
divizor comun al tuturor elementelor din irul iniial.

#include<iostream.h> //CMMDC
const MAX=20;
unsigned v[MAX],n;
unsigned cmmdc(unsigned li,unsigned ls);
unsigned euclid(unsigned a,unsigned b);

void main()
{int i;
cout<<"n=";cin>>n; //n-numrul de elemente ale irului
for(i=0;i<n;i++) //se citesc elementele irului
{cout<<"v["<<i<<"]=";cin>>v[i];}
cout<<"cmmdc="<<cmmdc(0,n-1);
}

unsigned cmmdc(unsigned li,unsigned ls) //li-limita inferioar a irului, ls-limita superioar a


{ unsigned m; // irului
if (ls-li<=1) //dac n ir exist cel mult dou elemente
return euclid(v[li],v[ls]); //se determin cmmdc cu algoritmul lui Euclid
m=(li+ls)/2; //m- mijlocul irului
return euclid(cmmdc(li,m),cmmdc(m+1,ls)); //apelul funciei euclid penru cele dou subiruri
}

unsigned euclid(unsigned a,unsigned b) //euclid determin cmmdc a doua numere


{unsigned r;
while (b) //ct timp mpritorul este diferit de 0
{r=a%b; a=b; b=r; //se calculeaz restul i dempritul devine
} // mprtitorul iar mpritorul devine restul
return a; //se returneaz ultimul rest diferit de 0
}

6. Se citesc n numere naturale. S se determine suma numerelor prime ale irului.

Conform strategiei metodei divide et impera vom mpri problema n


subprobleme mai simple de acelai tip, pn cnd devin suficient de simple pentru
a le rezolva. Apoi recompunem soluiile. Pentru aceasta vom proceda astfel:
Determinm elementul din mijlocul irului.
Dac este un numr prim l adunm la suma elementelor prime din subirul din
stnga lui i la suma elementelor prime din subirul din dreapta lui.
Dac nu este prim vom aduna doar cele dou sume obinute din subirul stng
i subirul dept.

8
Pentru cele dou subiruri se reapeleaz funcia recursiv relundu-se astfel
algoritmul pn cnd n subirurile astfel obinute nu mai exist nici un element.

#include <iostream.h> //SUM


#include <math.h>
#define MAX 20
int a[MAX],n; //a-memoreaz irul de numere, n-nr.de elemente ale irului
int suma(int li,int ls);
int e_prim (int k,int d=2);
void main()
{int i;
cout<<"n=";cin>>n; //citete nr. de elemente
for(i=0;i<n;i++) //citete elementele irului
{cout<<"a["<<i<<"]=";cin>>a[i];
}
cout<<"suma elementelor:"<<suma(0,n-1); //apeleaz funcia suma
}
int suma(int li,int ls) //li-limita inferioar a irului, ls-limita superioar
{int m,x,y; //m,x,y-variabile locale
if(li<=ls)
{m=(li+ls)/2; //m-reine indicale din mijlocul irului
x=suma(li,m-1); //x-reine suma calculat pe subirul din stnga
y=suma(m+1,ls); //y-reine suma calculat pe subirul din dreapta
if (e_prim(a[m],2)) //e_prim-verific daca numrul a[m] este prim
return a[m]+x+y; //dac este prim se adun la sumele de pe subiruri
else
return x+y; //dac nu este prim se adun numai sumele de pe subiruri
}
else
return 0; } //dac nu mai sunt elemente n ir
int e_prim (int k,int d) //k-numrul de verificat, d-cu valoare iniial 2
{if(k==0||k==1) //0 i 1 nu sunt numere prime
return 0;
if(d>sqrt(k)) //condiia de oprire a algoritmului recursiv
return 1;
else
if(k%d==0) //se verific dac numrul se divide la k
return 0;
return e_prim (k,d+1); //reapelul funciei
}

7. Sortarea prin interclasare


Se citete un vector cu n numere ntregi. S se ordoneze cresctor prin interclasare.

Algoritmul de interclasare a doi vectori a fost prezentat n manualul clasei a 10-


a.
Avnd dou iruri de valori ordonate cresctor, unul cu n elemente iar cellalt
cu m elemente, putem obine un ir cu toate valorile ordonate cresctor.

9
Problema noastr conine doar un ir neordonat.
Conform metodei divide et impera, vom mpri problema n subprobleme de
acelai tip pn cnd devin suficient de simple pentru a le rezolva. Rezolvm aceste
probleme apoi recompunem soluiile lor.
Pentru a ordona vectorul l vom mpri n doi vectori, vom mpri aceti doi
vectori fiecare n cte doi vectori i aa mai departe pn cnd vectorii obinui vor
avea cel mult dou elemente. Pentru astfel de vectori ordonarea este foarte simpl,
vom interschimba elementele lor dac este cazul. Apoi vom interclasa rnd pe rnd
vectorii n ordinea invers obinerii lor.
#include <iostream.h> //SORTARE PRIN INTERCLSARE
#define MAX 20
int a[MAX], n;
void div_imp(int li, int ls);
void sortare(int li, int ls);
void interclasare(int li, int ls, int m);
void citire();
void afisare();
void main()
{int i;
citire();
afisare();
div_imp(0,n-1);
afisare();
}
void citire() // citete n i elementele irului
{int i;
cout<<"n=";cin>>n;
for(i=0;i<n;i++)
{cout<<"a["<<i<<"]="; cin>>a[i]; }
}
void afisare() //afieaza elementele irului
{int i;
for(i=0;i<n;i++) cout<<a[i]<<" ";
cout<<endl;
}
void div_imp(int li, int ls) //gsete mijlocul i mparte irul n subiruri pn cnd
{int m; // se ajunge la cel mult dou elemente n fiecare subir
if((ls-li)<=1)
sortare(li,ls); //ordoneaz ubirurile formate din cel mult dou elemente
else
{m=(li+ls)/2; //mijlocul irului
div_imp(li,m); //reapelarea funciei pe subirul stng
div_imp(m+1,ls); //reapelarea funciei pe subirul drept
interclasare(li,ls,m);} //terclaseaz subirurile ordonate
}
void sortare(int li, int ls)
{int aux;
if(a[li]>a[ls]) //interschimb elementele irului dac nu sunt n ordinea dorit
{aux=a[li];
a[li]=a[ls];
a[ls]=aux; }
}

10
8. Sortarea rapid1 (Ouick Sort).

Fiind dat un ir cu n elemente, numere ntregi, sortm elementele irului dup


urmtorul algoritm: selectm un prim element din ir (acesta poate fi chiar
elementul din mijlocul irului).
Plasm acest element pe poxiia sa corect n ir, adic toate elementele din
stnga sa vor fi mai mici dect ele, iar toate elemente din dreapta sa vor fi mai
mari dect el.
Relum algoritmul pe subirul din stnga elementuli fixat i pe subirul din
dreapta elementului fixat.

#include<iostream.h> //QUICK SORT

void citire();
void afisare();
void qsort(int s,int d);

int n,a[20]; //n-nr. de elemente, a-vectorul care conine irul

void main()
{citire();
qsort(0,n-1);
afisare();
}

void qsort(int s,int d) //s-indicele din stnga intervalului, d-indicele din dreapta intervalului
{int aux,m,i,j; //aux-variabil auxiliar pentru interschimbarea elementelor, ind. de mijloc
if (s<d) //dac mai exist elemente n ir
{ m=a[(s+d)/2]; //determinm elementul din mijlocul irului
i=s; j=d; //i-indice, parcurge subirul stng de la stnga la dreapta
do // j-indice, parcurge subirul drept de la dreapta la stnga
{while ((i<=d) && (a[i]<m)) //ct timp elementele din stg. sunt n ordinea dorit
i++; // crete i
while ((j>=s) && (a[j]>m)) //ct timp elementele din dr. sunt n ordinea dorit
j--; // scade j
if (i<=j) //dac mai sunt elemente n subsiruri, ele nu sunt n orinea dorit
{aux=a[i]; //le inversm
a[i]=a[j];
a[j]=aux;
i++; j--; //crete i i scade j
}
}
while (i<=j); //se repet algoritmul ct timp mai sunt elemente ntre i i j
qsort(s,j); // se reia algoritmul pe subirul stng
qsort(i,d); // se reia algoritmul pe subirul drept
}
}

1
Funcia qsort(), este implementare metodei de sortare rapid i se afl n biblioteca limbajului de programare C+
+.

11
void citire() //tire datelor
{int i;
cout<<"n="; cin>>n;
for (i=0;i<n;i++)
{cout<<"a["<<i<<"]=";cin>>a[i];}
}

void afisare() //iarea datelor


{int i;
cout<<"sirul ordonat este: ";
for(i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}

7.3. Evaluare

TESTUL 1
1. Descriei n ce const metoda divide et impera i etapele ei.

2. Gsii erorile n funcia de mai jos.

int a[10];
int f(int i,int j)
{int m,x,y;
if(i<=j)
{x=f(i, (i+j)/2);
y=f((i+j)/2, j);
return a[(i+j)/2]*x*y;}
else
return 0;}
}

3. Se citesc n numere ntregi distincte ntr-un vector a. S se gseasc dac


exist, un indice i al vectorului pentru care a[i]=i, cu metoda divide et impera.

4. Se citesc n numere naturale. S se calculeze cu metoda divide et impera


suma elementelor prime.

12
TESTUL 2

1. Identificai ce s-a omis din definiia de mai jos.


Divide et impera este o metoda general de elaborare a algoritmilor. n cadrul
acestei metode distingem trei etape:
Descompunerea problemei ce trebuie rezolvat n dou sau mai multe
subcazuri (subprobleme) mai mici ale aceleiai probleme.
Rezolvarea succesiv a fiecru subcaz.

2. Gsii greala n funcia f de mai jos.

int f(int i,int j,int x)


{ int m;
if(li<ls)
{ m=(li+ls)/2;
if (x==a[m])
return 1;
else
if (x<a[m])
return cauta(li,m-1,x);
else
return cauta(m+1,ls,x);
}
else
return 0;
}

3. Se citesc n numere ntregi. S se calculeze cu metoda divide et impera


produsul numerelor care au ultima cifr egal cu x. Unde x este o cifr citit de
la tastatur.

4. S se determine folosind metoda divide et impera maximul elementelor


negative dintr-un ir de n elemente numere ntregi.

TESTUL 3

1. Se citete un ir de numere reale din fiierul DATE.IN. S se ordoneze irul


descresctor aplicndu-se metoda de sortare prin interclasare.

2. Fie un trunghi cu n linii (1<=n<=100). Pe fiecare linie se gsesc i numere ntregi.


S se determine suma minim fotmat din numere aflate pe un drum, ntre
numrul de pe prima linie i un numr de pe ultima linie.
Fiecare numr de pe acest drum este situat sub precedentul, la stnga sau
la dreapta acestuia.
Datele se citesc din fiierul DATE.IN astfel:
-pe prima linie se gsete n, numrul de linii
-pe urmtoarele n linii se gsesc elementele triunghiului.

13
7.4. Probleme propuse

1. S se numere elementele pare ale unui vector cu n numere ntregi, folosind


metoda divide et impera.

2. S se numere elementele prime ale unui vector care conine n numere ntregi,
folosind metoda divide et impera.

3. Fie a un vector ordonat cresctor. S se determine dac exist un element al


vectorului carea are suma cifrelor egal cu 5, folosind metoda divide et impera.

4. Se citete un vector cu n elemente numere reale. S se calculeze suma


elementelor aflate pe poziii impare.

5. S se determine simultan minimul i maximul unui vector cu n numere ntregi,


folosind metoda divide et impera.

6. S se calculeze:
an/2*an/2 pentru n par i n0
an={ a*an-1 pentru n impar i n0
1 pentru n=0
unde a i n sunt numere ntregi pozitive.

7. Ghicii numrul. Realizai un joc astfel nct calculatorul s poat ghici un numr
cuprins ntre 1 i 1000 , evident din ct mai puine ntrebri, la care dumneavoastr
s rspundei prin da sau nu. Intrebrile pot fi doar de forma:
- numrul este egal cu X?
- numrul este mai mare dect X?
- numrul este mai mic dect X?

14

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