# PBinfo #2444 – eq4 – Rezolvare C++

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

## Enunț

Se dă o expresie matematică în care pot să apară literele x, y, z, t, cifre și semnele + sau -.
Cifrele alăturate formează numere. Literele reprezintă variabile. O variabilă poate fi precedată de un număr. Între variabilă și numărul care o precede nu există alte caractere. Un grup format dintr-o literă și, eventual, un număr care o precede formează un monom. Un monom nu conține mai multe litere. Numărul care apare într-un monom se numește coeficient.
Expresia poate să conțină și numere care nu sunt urmate de o variabilă. Aceste numere se numesc termeni liberi. 
Expresia este deci alcătuită din monoame și termeni liberi. Fiecare monom și fiecare termen liber este precedat de unul dintre semnele + sau -.
Exemple: 
Expresii corecte: 
-x+100
+3x+2y-3z+7x-15-3+8z-7y
+10x-7y+3x-7+5z-8t-z-x-y+3

Expresii incorecte:
x+100 (x nu este precedat de + sau -)
+x+y-3zt (3zt nu este monom, deoarece conţine două litere)
-x + y -34*t + 5z - 5u (în expresie apar caractere nepermise, în acest caz spații, litera u și semnul *) 

Valoarea matematică a unei expresii este valoarea care se obține dacă înlocuim literele care apar în expresie cu valori numerice și efectuăm calculele. Valoarea unui monom se obține înmulțind coeficientul monomului cu valoarea pe care o are variabila care apare în respectivul monom. De exemplu, valoarea expresiei +3x pentru x=2  este 6.

Cerința
Fiind dată o expresie corectă, să se determine:
1. valoarea matematică a expresiei dacă x, y, z și t au valoarea 1.
2. numărul de cvartete distincte (x,y,z,t), de valori întregi care aparțin unui interval dat [a,b], pentru care expresia matematică corespunzătoare expresiei date este egală cu o valoare dată E. Două cvartete sunt distincte dacă există cel puţin o poziţie pentru care valorile corespunzătoare sunt diferite.

Date de intrare
Datele de intrare se citesc din fişierul eq4.in, care are următoarea structură:
- pe prima linie se află numărul natural C, care poate fi egal cu 1 sau 2, în funcţie de cerinţa ce trebuie rezolvată;
- pe a doua linie se află expresia dată;
- pe a treia linie se află valorile a b E, separate prin câte un spațiu. 

Date de ieșire
Datele de ieşire se vor scrie în fişierul eq4.out astfel:
- Dacă C=1, pe prima linie se va scrie răspunsul la cerința 1;
- Dacă C=2, pe prima linie se va scrie răspunsul la cerința 2.

Restricții și precizări

coeficienţii sunt numere naturale, având cel mult 4 cifre
2 ≤ lungimea expresiei ≤ 100000
-500 ≤ a ≤ b ≤ 500
-1015 ≤ E ≤ 1015
Testele care au C=1 totalizează 20 de puncte;
Testele care au C=2 totalizează 70 de puncte;
În cel puțin 30% dintre teste, în expresia dată apar cel mult trei dintre literele x, y, z sau t.
În concurs s-au acordat 10 puncte din oficiu. Aici se acordă 10 puncte pentru exemplele din enunț.

Exemplul 1:
eq4.in

1
+10x-7y+3x-7+5z-8t-z-x-y+3
-1 1 0
eq4.out

-4
Explicație
Se rezolvă cerința 1. Valoarea expresiei este: 10-7+3-7+5-8-1-1-1+3 = -4.

Exemplul 2:
eq4.in

1
-x+1
-1 1 0
eq4.out

0
Explicație
Se rezolvă cerința 1. Valoarea expresiei este -1+1 = 0.

Exemplul 3:
eq4.in

2
+10x-7y+3x-7+5z-8t-z-x-y+3
-1 1 0
eq4.out

8
Explicație
Se rezolvă cerința 2. Sunt 8 cvartete: (-1,-1,0,-1), (0,-1,-1,0), (0,-1,1,1), (0,0,-1,-1), (0,0,1,0), (0,1,1,-1), (1,0,0,1), (1,1,0,0) pentru care expresia este egală cu 0.

Exemplul 4:
eq4.in

2
-x+1+0z
-1 1 0
eq4.out

27
Explicație
Se rezolvă cerința 2. Sunt 27 cvartete: (1,-1,-1,-1), (1,-1,-1,0), (1,-1,-1,1), (1,-1,0,-1), (1,-1,0,0), (1,-1,0,1) etc. pentru care expresia este egala cu 0.

## Cod sursă C++

```cpp
#include <fstream>
#include <algorithm>
#include <string>
using namespace std;
int valori[1100000];
string expr;
int cx,cy,cz,ct,tl,a,b,E;
int nrcrt,semn,ceri;
ifstream f("eq4.in");
ofstream g("eq4.out");
long long rezultat;
int main()
{
    f >> ceri;
    f >> expr;
    expr+='+';
    f >> a >> b >> E;
    semn = +1;
    for (int i=0;i<expr.size();i++)
    {
        if (expr[i]=='+')
        {
            tl = tl + semn*nrcrt;
            nrcrt = 0;
            semn = +1;
        }
        if (expr[i]=='-')
        {
            tl = tl + semn*nrcrt;
            nrcrt = 0;
            semn = -1;
        }
        if (expr[i]>='0' && expr[i]<='9')
            nrcrt = 10*nrcrt+expr[i]-'0';
        if (expr[i]=='x')
        {
            if (expr[i-1]=='+' )
                nrcrt=1;
            if (expr[i-1]=='-')
                nrcrt=1;
                cx = cx + semn*nrcrt;
                nrcrt = 0;
        }
        if (expr[i]=='y')
        {
            if (expr[i-1]=='+' )
                nrcrt=1;
            if (expr[i-1]=='-')
                nrcrt=1;
            cy = cy + semn*nrcrt;
            nrcrt = 0;
        }
        if (expr[i]=='z')
        {
            if (expr[i-1]=='+' )
                nrcrt=1;
            if (expr[i-1]=='-')
                nrcrt=1;
            cz = cz + semn*nrcrt;
            nrcrt = 0;
        }
        if (expr[i]=='t')
        {
            if (expr[i-1]=='+' )
                nrcrt=1;
            if (expr[i-1]=='-')
                nrcrt=1;
            ct = ct + semn*nrcrt;
            nrcrt = 0;
        }
    }
    ///cout << cx << ' ' << cy << ' ' << cz << ' ' << ct << ' ' << tl << endl;
    if (ceri==1)
    {
        ///cout << cx+cy+cz+ct+tl<<endl;
        g << cx+cy+cz+ct+tl<<endl;
        return 0;
    }
    int poz=0;
    for (int x=a;x<=b;x++)
        for (int y=a;y<=b;y++)
        {
            int val = E - cx*x -cy*y;
            valori[poz]=val;
           /// cout << x << ' ' << y << ' ' << val << endl;
            poz++;
        }
        ///cout << endl;
    sort(valori,valori+poz);
    ///for (int i=0;i<poz;i++) cout << valori[i]<<' ';
    ///cout << endl;
    for (int z=a;z<=b;z++)
        for (int t=a;t<=b;t++)
        {
            int val = cz*z + ct*t + tl;
            if (val<valori[0]||val>valori[poz-1])
                continue;
            int pozsup = upper_bound(valori,valori+poz,val)-valori;
            int pozinf = lower_bound(valori,valori+poz,val)-valori;
            int nrap = pozsup - pozinf;
            rezultat += nrap;
           /// cout << z<<' '<<t<<' '<<val<<' '<<nrap<<' ' <<rezultat<<endl;
        }
    ///cout << rezultat << endl;
    g << rezultat << endl;
    return 0;
}
```

## Resurse

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