# PBinfo #4253 – textOJI – Rezolvare C++

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

## Enunț

Vasile lucrează intens la un editor de texte. Un text este format din unul sau mai multe paragrafe. Orice paragraf se termină cu Enter şi oricare două cuvinte consecutive din acelaşi paragraf sunt separate prin spaţii (unul sau mai multe). În funcţie de modul de setare a paginii, numărul maxim de caractere care încap în pagină pe o linie este unic determinat (Max).
Funcţia pe care Vasile trebuie să o implementeze acum este alinierea în pagină a fiecărui paragraf din text la stânga şi la dreapta. Pentru aceasta el va trebui să împartă fiecare paragraf în linii separate de lungime Max (fiecare linie terminată cu Enter). Împărţirea se realizează punând numărul maxim posibil de cuvinte pe fiecare linie, fără împărţirea cuvintelor în silabe. Pentru aliniere stânga-dreapta, el trebuie să repartizeze spaţii în mod uniform între cuvintele de pe fiecare linie, astfel încât ultimul caracter de pe linie să fie diferit de spaţiu, iar numărul total de caractere de pe linie să fie egal cu Max. Excepţie face numai ultima linie din paragraf, care rămâne aliniată la stânga (cuvintele fiind separate printr-un singur spaţiu, chiar dacă linia nu este plină).
În general, este puţin probabil ca alinierea să fie realizabilă prin plasarea aceluiaşi număr de spaţii  între oricare două cuvinte consecutive de pe linie. Vasile consideră că este mai elegant ca, dacă între unele cuvinte consecutive trebuie plasat un spaţiu în plus faţă de alte perechi de cuvinte consecutive, acestea să fie plasate la începutul liniei.

Cerința
Scrieţi un program care să citească lungimea unei linii şi textul dat şi care să alinieze textul la stânga şi la dreapta.

Date de intrare
Fișierul de intrare textoji.in conține pe prima linie linie Max, lungimea maximă a unui rând. Pe următoarele linii este scris textul.

Date de ieșire
Fișierul de ieșire textoji.out va conține textul aliniat stânga-dreapta.

Restricții și precizări

2 ≤ Max ≤ 1000
Lungimea maximă a oricărui cuvânt din text este 50 caractere şi nu depăşeşte Max.
Lungimea unui paragraf nu depăşeşte 1000 de caractere.
Soluţia este unică.
Problema aceasta s-a dat la OJI clasa a IX-a deoarece pe atunci șirurile de caractere se studiau în primul an de liceu (erau 8 ore de informatică pe săptămână – ce vremuri!)

Exemplul 1:
textoji.in

20
Vasile are multe bomboane bune.
textoji.out

Vasile   are   multe 
bomboane bune.
Explicație
Pe prima linie au fost plasate câte 3 spaţii între cuvintele consecutive.

Exemplul 2:
textoji.in

20
Ana are mere.
Ion are multe pere galbene?
textoji.out

Ana are mere.
Ion  are  multe pere 
galbene?
Explicație
Între Ion şi are există 2 spaţii, între are şi multe – 2 spaţii, iar între multe şi pere – 1 spaţiu. Observaţi că paragraful Ana are mere. (care are lungimea mai mică decât 20) a rămas aliniat la stânga, iar ultima linie din fiecare paragraf rămâne aliniată la stânga, cuvintele consecutive fiind separate printr-un singur spaţiu.

## Cod sursă C++

```cpp
#include <bits/stdc++.h>
#define InFile "textoji.in"
#define OutFile "textoji.out"
#define NMax  1001
#define LgMax 26
using namespace std;
char prg[NMax];
ifstream fin(InFile);
ofstream fout(OutFile);
char cuv[NMax][LgMax];
int  Max, nrl, LgLinie;
void afiseaza_paragraf(void);
void afiseaza_linie(int);
int main()
{
/* voi citi textul paragraf cu paragraf;
fiecare paragraf citit va fi descompus in cuvinte
si afisat conform specificatiilor din enunt*/
fin>>Max; fin.get();
int gata=0;
while (!gata)
      {fin.getline(prg,NMax); //citesc un paragraf
       if (!fin.good()) gata=1;
          else
          afiseaza_paragraf();
      }
fin.close(); fout.close();
return 0;
}
void afiseaza_paragraf()
{char *p;
 int LgCuv;
 LgLinie=-1; nrl=0;
 /* extrag succesiv cuvintele din paragraful curent
  in vectorul cuv vor fi memorate succesiv cuvintele
  care incap pe aceeasi linie*/
 p=strtok(prg," ");
 while (p)
      {LgCuv=strlen(p);
       if (LgLinie+LgCuv+1<=Max)//cuvantul incape pe linia curenta
          {strcpy(cuv[nrl],p); nrl++; LgLinie+=LgCuv+1;}
          else
          {afiseaza_linie(0); //afisez linia curenta
           nrl=1; LgLinie=LgCuv; strcpy(cuv[0],p);
           //plasez cuvantul curent pe linia urmatoare
           }
       p=strtok(NULL," ");
       }
afiseaza_linie(1); //afisez si ultima linie din paragraf
}
void afiseaza_linie(int u)
//u=1 daca linia curenta este ultima din paragraf sau 0 altfel
{
int i, j, cate, rest, nrsp;
if (u)
   for (i=0; i<nrl-1; i++) fout<<cuv[i]<<' ';
   else
   {cate=Max-LgLinie; rest=cate%(nrl-1); nrsp=cate/(nrl-1);
    for (i=0; i<nrl-1;i++)
        {fout<<cuv[i];
         for (j=0; j<=nrsp;j++) fout<<' ';
         if (rest) {fout<<' ';rest--;}
        }
   }
if (nrl>0) fout<<cuv[nrl-1]<<endl;
   else fout<<endl;
}
```

## Resurse

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