# PBinfo #2899 – timbre – Rezolvare C++

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

## Enunț

Vasilică a devenit filatelist pasionat. Din acest motiv toți prietenii i-au adus de ziua lui timbre, foarte multe timbre. Acum încearcă să organizeze timbrele primite. Fiecare timbru face parte dintr-o serie și are o valoare. Timbre distincte din aceeași serie au valori distincte. Este posibil ca Vasilică să fi primit și dubluri (adică să fi primit același timbru de mai multe ori). Valoarea unei serii este egală cu suma valorilor timbrelor distincte din seria respectivă. Dublurile nu contribuie la valoarea seriei, dar Vasilică le poate folosi pentru a face schimb de timbre cu alți filateliști.

Cerința
Cunoscând lista timbrelor primite, scrieți un program care să rezolve următoarele cerințe:
1. determină numărul de serii distincte din care fac parte timbrele primite;
2. determină numărul de timbre unicat (care nu au dublură);
3. determină seriile cu cea mai mare valoare.

Date de intrare
Fișierul de intrare timbre.in conţine pe prima linie cerinţa care trebuie să fie rezolvată (1, 2 sau 3). Pe a doua linie se află un număr natural N, reprezentând numărul de timbre primite de Vasilică. Pe fiecare dintre următoarele N linii este descris câte un timbru sub forma serie valoare, unde serie reprezintă denumirea seriei din care face parte timbrul respectiv, iar valoare este un număr reprezentând valoarea timbrului respectiv; seria și valoarea sunt separate printr-un singur spațiu.

Date de ieșire
Dacă cerința este 1 sau 2, fișierul de ieșire timbre.out va conține pe prima linie un număr reprezentând răspunsul la cerința respectivă. Dacă cerința este 3,  fișierul de ieșire timbre.out va conține denumirile seriilor cu valoarea cea mai mare, câte o denumire pe o linie, în ordine lexicografică.

Restricții și precizări

1 ≤ N ≤ 100
Valorile timbrelor sunt numere naturale nenule mai mici sau egale cu 1000.
Denumirile seriilor sunt formate din cel mult 50 de caractere (litere, cifre, spațiu, cratimă).
Pentru fiecare cerință se acordă 30% din punctajul obținut pe teste.

Exemplul 1:
timbre.in

1
9
Cap-de-bour 4
Romania 100 10
Cap-de-bour 7
Cap-de-bour 4
Romania 100 5
Romania 100 5
Romania 100 5
CRACIUN 2018 15
Romania 100 10
timbre.out

3
Explicație
Există trei serii distincte (Cap-de-bour, Romania 100 și CRACIUN 2018).

Exemplul 2:
timbre.in

2
9
Cap-de-bour 4
Romania 100 10
Cap-de-bour 7
Cap-de-bour 4
Romania 100 5
Romania 100 5
Romania 100 5
CRACIUN 2018 15
Romania 100 10
timbre.out

2
Explicație
În aceste serii există doar două timbre unicat (timbrul cu valoarea 7 din seria Cap-de-bour și cel din seria CRACIUN 2018). 

Exemplul 3:
timbre.in

3
9
Cap-de-bour 4
Romania 100 10
Cap-de-bour 7
Cap-de-bour 4
Romania 100 5
Romania 100 5
Romania 100 5
CRACIUN 2018 15
Romania 100 10
timbre.out

CRACIUN 2018
Romania 100
Explicație
Seriile având valoarea cea mai mare (15) sunt (în ordine lexicografică) CRACIUN 2018 și Romania 100.

## Cod sursă C++

```cpp
#include <fstream>
#include <stdlib.h>
#include <vector>
#include <utility>
#include <cstring>
#include <string>
#include <algorithm>
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define NMAX 101
#define LMAX 60
#define MAX(a,b) (a)>(b)?(a):(b)
using namespace std;
ifstream fin("timbre.in");
ofstream fout("timbre.out");
struct timbru
{
    char serie[LMAX];
    vector<pii>valori;
    int valoare;
};
vector<string>rez;
timbru timbre[NMAX];
int nrt;
int cerinta, n;
char t[LMAX];
int lg, valoare;
bool gasit, dublura;
void c1();
void c2();
void c3();
int main()
{
    char ch;
    fin>>cerinta;
    fin>>n;
    fin.get(ch);
    for (int i=0;i<n;++i)
    {
        fin.getline(t, LMAX);
        lg = strlen(t);
        for (int j=lg-1;j>=0;--j)
        {
            if (t[j] == ' ')
            {
                t[j] = 0;
                valoare = atoi(t+j+1);
                break;
            }
        }
        gasit = false;
        for (int j=0;j<nrt;++j)
        {
            if (!strcmp(timbre[j].serie, t))
            {
                gasit = true;
                dublura = false;
                for (int k=0;k<timbre[j].valori.size();++k)
                {
                    if(timbre[j].valori[k].first == valoare)
                    {
                        ++timbre[j].valori[k].second;
                        dublura = true;
                        break;
                    }
                }
                if (!dublura)
                {
                    timbre[j].valori.pb(mp(valoare, 1));
                    timbre[j].valoare += valoare;
                }
                break;
            }
        }
        if (!gasit)
        {
            strcpy(timbre[nrt].serie, t);
            timbre[nrt].valori.pb(mp(valoare, 1));
            timbre[nrt].valoare += valoare;
            ++nrt;
        }
    }
    switch(cerinta)
    {
    case 1:
        c1();
        break;
    case 2:
        c2();
        break;
    case 3:
        c3();
        break;
    default:
        break;
    }
    fin.close();
    fout.close();
    return 0;
}
void c1()
{
    fout<<nrt<<'\n';
}
void c2()
{
    int af = 0;
    for (int i=0;i<nrt;++i)
    {
        for(int j=0;j<timbre[i].valori.size();++j)
        {
            if (timbre[i].valori[j].second == 1)
            {
                ++af;
            }
        }
    }
    fout<<af<<'\n';
}
void c3()
{
    int vMax = 0;
    for (int i=0;i<nrt;++i)
    {
        vMax = MAX(vMax, timbre[i].valoare);
    }
    for (int i=0;i<nrt;++i)
    {
        if (timbre[i].valoare == vMax)
        {
            string act(timbre[i].serie);
            rez.pb(act);
        }
    }
    sort(rez.begin(), rez.end());
    for (auto x:rez)
    {
        fout<<x<<'\n';
    }
}
```

## Resurse

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