Informatică, întrebare adresată de ionutg38, 9 ani în urmă

Se dau a și b numere naturale nenule, cu a < b. Să se determine soluțiile ecuației 1/x+1/y+1/z=a/b, unde x,y,z sunt numere naturale nenule.
Date de intrare
Programul citește de la tastatură numerele naturale nenule a și b, separate prin spațiu.

Date de ieșire
Programul va afișa pe ecran, pe linii separate, soluțiile ecuației în ordinea crescătoare a valorilor lui x, iar la valori egale ale lui x în ordinea crescătoare a valorilor lui y . În cazul în care problema nu are soluţii se va afişa mesajul NU ARE SOLUTII.

Restricții și precizări
1 ≤ a < b ≤ 100
Se vor afișa numai soluțiile cu x ≤ y ≤ z numere naturale



Exemplu
Intrare

2 3
Ieșire

2 7 42
2 8 24
2 9 18
2 10 15
2 12 12
3 4 12
3 6 6
4 4 6

Răspunsuri la întrebare

Răspuns de blindseeker90
3
Sa simplificam ecuatia respectiva.Sa presupunem ca stim valoarea lui xAtunci ecuatia in cele doua variabile y si z va fi\frac{1}{y}+\frac{1}{z}=\frac{z}{yz}+\frac{y}{yz}=\frac{y+z}{yz}=\frac{a}{b}-\frac{1}{x}=\frac{ax-b}{bx} Mai intai impartim denumitorul si numitorul din partea dreapta a egalitatii ca sa simplificam problema. Sa presupunem ca obtinem fractia in dreapta e/fAcum, sa notam cel mai mare divizor comun dintre y si z cu dcmmdc(y,z)=d. Atunci y=m*d si z=n*d, unde m si n sunt alti divizori despre care stim ca sunt primi intre ei, altfel ar fi inclusi in dcmmdc(m,n)=1Atunci fractia din dreapta devine\frac{y+z}{yz}=\frac{m*d+n*d}{m*d*n*d}=\frac{d(m+n)}{d*d*m*n}=\frac{m+n}{d*m*n}=\frac{e}{f} unde e si f sunt prime intre eleAtunci il putem determina pe d
d=\frac{f(m+n)}{e*m*n}
Pentru ca variabila e nu este divizor al lui f, si m*n nu este divizor al lui m+n, inseamna ca m si n sunt divizori ai lui f.
Luam la rand toti divizorii lui f si il determinam in fiecare caz pe d
Daca d este un numar intreg, atunci inseamna ca si y=d*m si z=d*n sunt numere intregi si gasim tripleta
Pentru x, incepem cu x=2, si apoi il tot crestem pana la 100.
Acesta e codul in C

#include <iostream>
#include <cmath>
using namespace std;


int verifica(int x,int y,int z){
return(x<=y&&y<=z);
}

int cmmdc(int a,int b){
int temp;
while(b>0){
temp=b;
b=a%b;
a=temp;
}
return a;
}
int main(){
int a,b,x,m,n,denumitor,numitor,numitor_divizor_comun,sol=0;
float d;
cout<<"Introduceti cele doua numere:";
cin>>a>>b;
x=2;
while(x<100){
denumitor=a*x-b;
numitor=b*x;
numitor_divizor_comun=cmmdc(denumitor,numitor);
denumitor=denumitor/numitor_divizor_comun;
numitor=numitor/numitor_divizor_comun;
for(m=1;m<=numitor;m++){
for(n=numitor;n>=1;n--){
if(numitor%n==0&&numitor%m==0&&m*n<=numitor){
d=(float)((m+n)*numitor)/(m*n*denumitor);
if(d-(int)d==0&&verifica(x,d*m,d*n)==1){
sol=1;
cout<<x<<" "<<d*m<<" "<<" "<<d*n<<endl;
}
}
}
}

x++;
}
if(sol==0){
cout<<"NU SUNT SOLUTII";
}
return 0;
}

ionutg38: Pe exemplu solutia 2 12 12 o da de doua ori. Pe cateva teste depaseste si limita de timp. Oricum, multumesc. Mai incerc si eu sa rezolv.
ionutg38: La indicatii de rezolvare zice asa:
ionutg38: Dacă x ≤ y ≤ z deducem că x ≤ 3*b/a și x ≥ b/a. Pentru fiecare valoare a lui x se scoate din ecuație y în funcție de z și se pune condiția ca y să fie număr natural. Apare astfel o condiție ca z*(a*x-b)-b*x să fie divizorul lui (b*x) 2 . Luând pe rând acești divizori se obțin valorile lui y și z. În final se ordonează soluțiile obținute.
ionutg38: E vorba de problema #983 Ecuatie de pe pbinfo.ro
ionutg38: (b*x) 2 e de fapt (b*x) la patrat, adica (b*x) ^2
ionutg38: Nu era (b*x)^2 ci b*x*z (la indicatii era gresit redactat. Am rezolvat problema. Iata sursa C++
ionutg38: #include <iostream>
using namespace std;
int a,b,x;
unsigned long long int y,z,numarator,numitor;
int main()
{
cin>>a>>b;
int vi,vf;
if(b%a==0)
vi=b/a-1,vf=3*(b/a);
else
vi=(int)(b/a)-1,vf=(int)(3*(b/a+1));
int ok=1;
for(x=vi;x<=vf;++x)
for(z=x;z<=30000;++z)
{
numarator=b*x*z;
numitor=a*x*z-b*z-b*x;
if(numitor>0&&numarator%numitor==0)
{
y=numarator/numitor;
if(y>=z)
{
ok=0;
cout<<x<<' '<<z<<' '<<y<<'\n';
}
else
break;
}
}
if(ok)
cout<<"NU ARE SOLUTII";
return 0;
}
ionutg38: Poate are nevoie si altcineva
Alte întrebări interesante