Sunteți pe pagina 1din 4

Divide et impera

Divide et impera se bazeaz pe principiul descompunerii problemei n dou sau mai multe
subprobleme (mai uoare), care se rezolv, iar soluia pentru problema iniial se obine
combinnd soluiile subproblemelor. De multe ori, subproblemele sunt de acelai tip i pentru
fiecare din ele se poate aplica aceeai tactic a descompunerii n (alte) subprobleme, pn
cnd (n urma descompunerilor repetate) se ajunge la probleme care admit rezolvare imediat.
Nu toate problemele pot fi rezolvate prin utilizarea acestei tehnici. Se poate afirma c
numrul celor rezolvabile prin "divide et impera" este relativ mic, tocmai datorit cerinei ca
problema s admit o descompunere repetat.
Divide et impera este o tehnic ce admite o implementare recursiv. Principiul general
prin care se elaboreaz algoritmi recursivi este: "ce se ntmpl la un nivel, se ntmpl la
orice nivel" (avnd grij s asigurm condiiile de terminare). Aadar, un algoritm prin divide
et impera se elaboreaz astfel: la un anumit nivel avem dou posibiliti:
1. s-a ajuns la o problem care admite o rezolvare imediat (condiia de terminare), caz
n care se rezolv i se revine din apel;
2. nu s-a ajuns n situaia de la punctul 1, caz n care problema curent este descompus
n (dou sau mai multe) subprobleme, pentru fiecare din ele urmeaz un apel recursiv
al funciei, dup care combinarea rezultatelor are loc fie pentru fiecare subproblem,
fie la final, naintea revenirii din apel.

Aplicatii
1. Se citeste un numar real x. Sa se calculeze radical de ordinul 3 din x folosind un algoritm
de tip Divide et impera.
#include<iostream>
using namespace std;
double r3(double x, double s, double d)
{
if(d-s<=0.0001) return d;
else
{ double m=(s+d)/2;
if(m*m*m<x) return r3(x,m,d);
else return r3(x,s,m);
}
}
int main()
{ double x;
cin>>x;
if(x>0) if(x<1) cout<<r3(x,0,1);
else cout<<r3(x,0,x);
else if(x>-1) cout<<r3(x,-1,0);
else cout<<r3(x,x,0);
system("pause");
return 0;
}

2. Se citeste un vector cu n elemente numere naturale. Sa se determine elementul minim din


vector folosind Divide et impera.
#include<iostream>
using namespace std;
int min(int a[100],int s , int d)
{
if ( s == d ) return a[s];
else
{
int m = (s+d)/2;
int m1 = min(a,s,m);
int m2 = min(a,m+1,d);
if ( m1 < m2 ) return m1;
else return m2;
}
}
int main()
{
int a[100];
int n ;
cin>> n;
for (int i = 0 ; i < n ;i++)
cin>>a[i];
cout << min(a,1,n);
system("pause");
return 0;
}
3. Se citeste un vector cu n elemente numere naturale. Sa se calculeze CMMDC al
elementelor vectorului folosind Divide et impera.
#include<iostream>
using namespace std;
int cmmdc(int a[100], int s, int d)
{ if(s==d) return a[s];
else
{ int x,y;
x=cmmdc(a,s,(s+d)/2);
y=cmmdc(a,(s+d)/2+1,d);
while(x!=y)
if(x>y) x=x-y;
else y=y-x;
return x;
}

}
int main()
{
int a[100],n,i;
cin>>n;
for(i=1;i<=n;i++) cin>>a[i];
cout<<cmmdc(a,1,n);
system("pause");
return 0;
}
4. Sa se calculeze folosind metoda divide et impera suma elementelor unui vector.
#include<iostream.h>
int v[20],n;
int suma(int li,int ls)
{int m, d1 ,d2;
if(li!=ls)
{m=(li+ls)/2;
d1=suma(li,m);
d2=suma(m+1,ls);
return d1+d2;
}
else
return v[li];
}
void main()
{
cout<<"n=";
cin>>n;
for(int i=1;i<=n;i++)
{cout<<"v["<<i<<"]=";
cin>>v[i];}
cout<<"suma celor "<<n<<" elemente ale vectorului "<<suma(1,n);
}
5.Utilizand metoda divide et impera, sa se sorteze prin interclasare un sir
#include<iostream.h>
int a[20],n; void mergesort(int i,int m,int j){int b[20],x=i,k=1,y=m+1;
while(x<=m && y<=j)
if (a[x]<a[y])
b[k++]=a[x++];
else
b[k++]=a[y++];
while (x<=m)
b[k++]=a[x++];
while (y<=j)
b[k++]=a[y++];

int t=i;
for (k=1;k<=(j-i)+1;k++)
a[t++]=b[k];
}
void divimp(int i,int j)
{if (i<j)
{int m=(i+j)/2;
divimp(i,m);
divimp(m+1,j);
mergesort(i,m,j);}
} void main()
{
cout<<"n=";
cin>>n;
for(int i=1;i<=n;i++)
{cout<<"a["<<i<<"]=";
cin>>a[i];
}
divimp(1,n);
cout<<"vectorul sortat este: "<<endl;
for(i=1;i<=n;i++)
cout<<a[i]<<' ';
}

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