# PBinfo #4777 – sponsor – Rezolvare C++

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

## Enunț

A devenit o obișnuință ca orice competiție să aibă un număr de sponsori. De exemplu, JBOI 2022, Balcaniada de Informatică pentru juniori, desfășurată în România, la Botoșani, a beneficiat de sprijinul a șapte importanți sponsori. Lista acestor sponsori este publicată în orice material publicitar care se referă la competiția respectivă. Și competiția noastră OMI 2025 beneficiază de sprijinul a N sponsori. Parcurgând lista de sponsori, am constat că, selectând anumiți sponsori din listă și aranjându-i într-o anumită ordine, primele litere din numele sponsorilor selectați formează cuvintele “OLIMPIADADE”, iar ultimele litere cuvântul “INFORMATICA”.

Cerința
Scrieți un program care să determine numărul de posibilități de selectare din lista de sponsori a acelora care respectă această proprietate, precum și soluția minimă lexicografic.

Date de intrare
Fișierul de intrare sponsor.in are pe prima linie două valori naturale C și N separate printr-un spațiu, reprezentând cerința (1 sau 2) respectiv numărul de sponsori. Pe următoarele N linii se află numele celor N sponsori, câte un sponsor pe linie.

Date de ieșire
Fișierul de ieșire sponsor.out conține pe prima linie, dacă cerința este 1, numărul M de posibilități de a selecta dintre cei N sponsori o listă care să respecte proprietatea descrisă. Dacă cerința este 2, fișierul de ieșire va conține o listă de 11 sponsori care respectă proprietatea descrisă, scrisă corect, câte un sponsor pe linie.

Restricții și precizări

11 ≤ N ≤ 50
orice nume de sponsor are maximum 30 de caractere și apare o singură dată în listă
numele sponsorilor conține numai litere mari și alte caractere imprimabile (cod ASCII din mulțimea [32, 127]); primul și ultimul caracter al numelui sunt litere
pentru toate testele există cel puțin o soluție
pentru cerința 1 se acordă 49 puncte, iar pentru cerința 2 se acordă 41 puncte; 10 puncte se acordă pentru exemplele din enunț

Exemplul 1:
sponsor.in

1 12
ICONOGRAF
OCHELARI PENTRU OCHI
LAN
ASTAZI
MANGO
PAR
IMPRESIONISM
ABBA
DECAPOTAT
DEMISEC
ELBA
IF
sponsor.out

2
Explicație
Cerința 1, sunt 12 sponsori, există 2 posibilități de a selecta lista. Cele 2 posibilități sunt:

OCHELARI PENTRU OCHI	OCHELARI PENTRU OCHI
LAN			LAN
ICONOGRAF		IF
MANGO			MANGO
PAR			PAR
IMPRESIONISM		IMPRESIONISM
ABBA			ABBA
DECAPOTAT		DECAPOTAT
AMANDOI			AMANDOI
DEMI_SEC		DEMI_SEC
ELBA			ELBA

Exemplul 2:
sponsor.in

2 12
ICONOGRAF
OCHELARI PENTRU OCHI
LAN
AMANDOI
MANGO
PAR
IMPRESIONISM
ABBA
DECAPOTAT
DEMI_SEC
ELBA
IF
sponsor.out

OCHELARI PENTRU OCHI
LAN
ICONOGRAF
MANGO
PAR
IMPRESIONISM
ABBA
DECAPOTAT
AMANDOI
DEMI_SEC
ELBA
Explicație
Cerința 2, a fost afișată soluția minimă lexicografic dintre cele 2 posibilități de a selecta sponsorii
ICONOGRAF < IF deoarece litera C < litera F

## Cod sursă C++

```cpp
//Serban Marinel
#include <fstream>
#include <cassert>
using namespace std;
#define MAX 100
char s[MAX][50];                       //retin sponsorii
int Lg[MAX];                           //evidenta numar caractere
char Cap[11] =   {'O', 'L', 'I', 'M', 'P', 'I', 'A', 'D', 'A', 'D', 'E'};
char Coada[11] = {'I', 'N', 'F', 'O', 'R', 'M', 'A', 'T', 'I', 'C', 'A'};
int Cerinta, NrS, NrSol, SCorect, Cati[12];
ifstream fin ("sponsor.in");
ofstream fout ("sponsor.out");
void Citeste();
void Scrie();
int main()
{
   Citeste();
   Scrie();
   return 0;
}
void Citeste()
{
   int i, Lung, ok, k;
   char sp[50];
   fin >> Cerinta >> NrS;
   assert(Cerinta == 1 || Cerinta == 2);
   assert(11 <= NrS && NrS <= 50);
   fin.get();                    //citesc numarul de sponsori si CR
   SCorect = -1;
   for (i = 0; i < NrS; i++)     //citesc cei NrS sponsori si ii retin pe cei buni
   {
      fin.getline (sp, 50);      //citesc un sponsor
      Lung = 0;
      while (sp[Lung] != 0) Lung++;
      Lung--;                    //numarul de caractere
	  assert(1 <= Lung && Lung <= 32);
      ok = 0;                    //verific daca poate fi intr-o solutie
      for (k = 0; k < 11 && !ok; k++)
         if (sp[0] == Cap[k] && sp[Lung] == Coada[k])
            ok = 1;
      if (ok)                    //daca DA, il retin
      {
         SCorect++;
         for (k = 0; k <= Lung; k++)
            s[SCorect][k] = sp[k];
         Lg[SCorect] = Lung;    //lungimea nume sponsor i
         switch (sp[0])         //calculez de cate ori apare combinatia
         {
            case 'O': if (sp[Lung] == 'I') Cati[0]++; break;
            case 'L': if (sp[Lung] == 'N') Cati[1]++; break;
            case 'I': if (sp[Lung] == 'F') Cati[2]++;
                      else
                        if (sp[Lung] == 'M') Cati[5]++; break;
            case 'M': if (sp[Lung] == 'O') Cati[3]++; break;
            case 'P': if (sp[Lung] == 'R') Cati[4]++; break;
            case 'A': if (sp[Lung] == 'A') Cati[6]++;
                      else
                        if (sp[Lung] == 'I') Cati[8]++; break;
            case 'D': if (sp[Lung] == 'T') Cati[7]++;
                      else
                        if (sp[Lung] == 'C') Cati[9]++; break;
            case 'E': if (sp[Lung] == 'A') Cati[10]++; break;
         }
      }
   }
}
void Scrie()
{
   int i, j, k;
   if (Cerinta == 1)
   {
      NrSol = 1;                  //calculez numarul de solutii
      for (i = 0; i < 11; i++) NrSol *= Cati[i];
      fout << NrSol << '\n';      //si le afisez
   }
   else
   {
       //ordonez
       for (i = 0; i < SCorect; i++)//sortare prin selectie
          for (j = i + 1; j <= SCorect; j++)
          {
              k = 0;
              while (s[i][k] == s[j][k] && k <= min(Lg[i], Lg[j])) k++;
              if (s[i][k] > s[j][k])
              {
                  swap (s[i], s[j]);
                  swap (Lg[i], Lg[j]);
              }
          }
       //afisez
       for (i = 0; i < 11; i++)        //caut in ordine cele 11 cuvinte
         for (k = 0; k <= SCorect; k++)//in sirul de cuvinte posibile
            if (s[k][0] == Cap[i] && s[k][Lg[k]] == Coada[i])//la primul gasit
            {
               fout << s[k] << '\n';//afisez cuvantul
               break;
            }
   }
}
```

## Resurse

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