|
Dac? a ?i b sunt numere prime între ele ?i x0, y0 constituie o solu?ie pentru ax+by=c, atunci totalitatea solu?iilor se poate reprezenta sub forma: x= x0+bt, y= y0 –at, unde t este un num?r întreg oarecare. O solu?ie a ecua?iei se poate ob?ine cu ajutorul penultimei frac?ii de aproximare pentru reprezentarea sub form? de frac?ie continu? a lui a/b. Considerând c? penultima frac?ie este m/n, x0=nc, y0=-mc.
Exemplu:
Fie ecua?ia: 43x+19y=2.
Frac?iile de aproximare ale lui 43/19 sunt: 7/3, 9/4, 43/19.
Din frac?ia 9/4 se ob?ine x0=4*2=8, y0=-9*2=-18. Astfel, solu?ia general? se poate scrie de forma: x=8+19t ?i y=-18-43t, unde t este un num?r oarecare.
Implementare
Algoritmul de mai sus este valabil, dup? cum am precizat, în cazul când cele 2 numere a ?i b sunt prime între ele. Dac? dorim rezolvarea unei ecua?ii în care cele 2 numere nu sunt neap?rat prime între ele, se poate proceda în felul urm?tor: se calculeaz? cel mai mare divizor comun al lor (sigur este diferit de 1), iar apoi se evalueaz? dac? ecua?ie poate sau nu avea solu?ii, în func?ie de valoarea lui c. Dac? c este divizibil cu cmmdc-ul celor 2 numere, atunci se simplific? întreaga ecua?ie cu cmmdc ?i problema se reduce la cea prezentat? mai sus. Dac? c nu se împarte exact la cmmdc, atunci putem spune c? ecua?ia nu are solu?ii întregi.
Pe lâng? aceasta, intervin o serie de cazuri critice în care algoritmul de mai sus nu poate fi aplicat, cum ar fi de exemplu cazurile în care nu exist? penultima frac?ie. Dar se poate calcula solu?ia ?i în aceste cazuri:
• a=0, b=0
În acest caz solu?ia depinde valoarea lui c:
? c=0 => x ?i y poate fi orice num?r întreg
? c ? 0 => nu exist? solu?ii
• a=0, b? 0
Ecua?ia devine: by=c. Deci y se poate calcula, ?inând îns? cont c? vorbim numai de numere întregi.
• a?0, b= 0
Analog cu cazul anterior.
Dac? unul dintre numerele a sau b are valoarea 1 nu se mai poate vorbi de penultima frac?ie de aproximare, deci ?i aceste cazuri trebuie tratate separat.
O alt? observa?ie este aceea c? frac?ia de aproximare (m/n) aproximeaz? frac?ia (a/b) în plus sau în minus. De aceea în la sfâr?it trebuie s? corectez rezultatul în func?ie de aceasta, ?inând seama ?i de semnul frac?iei a/b.
Sursa programului
#include
#include
#include
long int v[100];
//obtine penultima fractie de aproximare
void get_mn(long int &a,long int &b,int k)
{
if (k>0) { long int aux=v[k-1]*b+a;
a=b;b=aux;
get_mn(a,b,k-1);
}
else a=a+b-(b=a);
}
long int _cmmdc(long int a,long int b)
{
while (a!=b)
if (a>b) a-=b;
else b-=a;
return a;
}
void stop()
{
printf("Nu exista solutii...\n");
}
int solutii(long int a,long int b,long int c,
long int &x0,long int &n1,long int &y0,long int &n2)
{
long int m,n,cmmdc=1,_a,_b;
int nr=-1;
_a=labs(a);_b=labs(b);
if ((_a>1)&&(_b>1)) cmmdc=_cmmdc(_a,_b);
if (cmmdc!=1){
if (c%cmmdc) {stop();return 0;}
else a/=cmmdc,b/=cmmdc,c/=cmmdc;
}
m=a;n=b;
if (!(a*b))
if (!a) if (!b)
{
//0=c
if (!c) printf("x,y?Z\n");
else stop();
return 0;
}
else
{ // by=c
if (c%b) stop();
else { printf("x?Z\n");
printf("y=%ld\n",c/b);
}
return 0;
}
else
{ //ax=c
if (c%a) stop();
else {printf("x=%ld\n",c/a);
printf("y?Z\n");
}
return 0;
|