# PBinfo #1458 – ecuatii_grad_2 – Rezolvare C++

Sursa: Codul lui Andrei
Limbaj: C++
Autor rezolvare: Darius

## Enunț

Cerința
Dându-se o ecuaţie de gradul 2, să se scrie un program care determină soluţiile acestei ecuaţii. 

Date de intrare
Fișierul de intrare ecuatii.in conține pe prima linie un şir de caractere de forma ax^2+bx+c, reprezentând o ecuaţie de gradul 2: \(\scriptsize ax^2+bx+c=0\)

Date de ieșire
Fișierul de ieșire ecuatii.out va conține soluţiile acestei ecuaţii, cu 2 zecimale exacte, sperate printr-un spaţiu. Dacă ecuaţia nu are soluţii reale, se va afişa -1. Dacă ecuaţia are o singură soluţie reală, se va afişa numai aceasta, cu 2 zecimale exacte.

Restricții și precizări

a, b, c ∈ [-10  3  , 10  3  ], a≠0
Dacă valorile a şi b nu sunt precizate (ex: x^2+x+1=0), acestea vor fi egale cu 1 sau -1, în funcţie de semn (vedeţi exemplele)
Dacă ecuaţia are 2 soluţii reale, se va afişa cea mai mică, urmată de cea mai mare

Exemple:


 

 ecuatii.in 
 ecuatii.out 
 ecuaţie 


 1 
 3x^2-x-4 
 -1.00 1.33 
\(\scriptsize 3x^2-x-4=0\) 


 2 
 x^2-8x+16 
 4.00 
\(\scriptsize x^2-8×+16=0\) 


 3 
 -x^2-8x+16 
 -9.66 1.66
\(\scriptsize -x^2-8×+16=0\) 


 4 
 3x^2-x+0 
 0.00 0.33
\(\scriptsize 3x^2-x=0\) 


 5 
 4x^2+x+16 
 -1
\(\scriptsize 4x^2+x+16=0\) 


 6 
 x^2+0x-4 
 -2.00 2.00
\(\scriptsize x^2-4=0\)

## Cod sursă C++

```cpp
// o posibila solutie pentru problema ecuatii_grad_2 #1458 @pbinfo
// programul poate fi imbunatatit
// compilat cu Code::Blocks 13.12
#include <cstring>  // strlen, strcpy
#include <cmath>    // sqrt
#include <cstdio>   // scanf, printf cu numar definit de zecimale
#include <cstdlib>  // atoi
double min(double a, double b) {
    return (a > b) ? b : a;
}
double max(double a, double b) {
    return (a > b) ? a : b;
}
//------------------------------------------------------------------------------------------------------------
// determinam coeficientul (de tip int) din sierul initial (de tip char*)
// verificare=1 se foloseste la a si b, unde sirInitial poate contine doar '+' (sau nu contine nimic) pentru 1 si '-' pentru -1
int determinare(char sirInitial[], int verificare=1) {
    int lungime = strlen(sirInitial);
    if(verificare) {
        if( lungime == 0 )
            return 1;
        if( lungime == 1 && sirInitial[0] == '-' )
            return -1;
    }
    if(lungime == 1 && sirInitial[0] == '+')
        return 1;
    return atoi(sirInitial);
}
//------------------------------------------------------------------------------------------------------------
// ecuatie[] este de forma "ax^2+bx+c", asa ca atribuim variabilelor a, b, c, transmise prin referinta, valorile aferente
void separare(char ecuatie[], int &a, int &b, int &c) {
    int lungime = strlen(ecuatie), lungimeCoeficienti[3] = {0}, pozitie = 0;
    char coeficienti[3][100]; // coeficienti[0] -> a, coeficient[1] -> b, coeficienti[2] -> c
    while( ecuatie[pozitie] != 'x' ) // separare sir a
        coeficienti[0][ lungimeCoeficienti[0]++ ] = ecuatie[pozitie++];
    coeficienti[0][ lungimeCoeficienti[0] ] = '\0';
    pozitie += 3;
    while( ecuatie[pozitie] != 'x' ) // separare sir b
        coeficienti[1][ lungimeCoeficienti[1]++ ] = ecuatie[pozitie++];
    coeficienti[1][ lungimeCoeficienti[1] ] = '\0';
    pozitie += 1;
    while( pozitie < lungime ) // separare sir c
        coeficienti[2][ lungimeCoeficienti[2]++ ] = ecuatie[pozitie++];
    coeficienti[2][lungimeCoeficienti[2]] = '\0';
    a = determinare(coeficienti[0]);
    b = determinare(coeficienti[1]);
    c = determinare(coeficienti[2], 0);
}
//------------------------------------------------------------------------------------------------------------
// Programul principal (citirea ecuatiei din fisier, separarea coeficientilor, determinarea rezultatului)
int main(void) {
    freopen("ecuatii.in", "r", stdin);
    freopen("ecuatii.out", "w", stdout);
    char ecuatie[100];
    int a, b, c;
    gets(ecuatie);
    separare(ecuatie, a, b, c);
    // solutiile reale ale ecuatiei
    double x1, x2;
    // afisarea solutiilor
    int delta = b * b - 4 * a * c;
    if( delta < 0 )
        printf("-1"); // ecuatia nu are solutie
    else if(delta == 0) // ecuatia are o singura solutie
        printf("%.2f", (double) (-b) / (2 * a));
    else { // ecuatia are doua solutii -> o afisam pe cea mai mica, urmata de cea mai mare
        double radDelta = sqrt(delta);
        x1 = (-b + radDelta) / (2*a);
        x2 = (-b - radDelta) / (2*a);
        printf("%.2f %.2f", min(x1, x2), max(x1, x2));
    }
    return 0;
}
```

## Resurse

- [Pagina originală](https://codulluiandrei.ro/rezolvari/pbinfo/1458)
- [Sursa C++](https://codulluiandrei.ro/rezolvari/pbinfo/1458/cod.cpp)
- [Sursa pe GitHub](https://raw.githubusercontent.com/codulluiandrei/pbinfo/main/pbinfo-1458/main.cpp)
- [Cursuri de informatică pentru BAC](https://codulluiandrei.ro/academia/info-curs/pachet-cpp/)
