# PBinfo #4583 – criptare2 – Rezolvare C++

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

## Enunț

Ana și Bogdan sunt pasionați de criptarea mesajelor. Ei au studiat mai multe metode de criptare. Ultimul algoritm pe care l-au studiat presupune să scrie un cuvânt cu litere mari ale alfabetului englez. Apoi, sub acest cuvânt să scrie toate permutările sale circulare cu o poziție spre stânga obținând astfel o matrice de caractere. Ordonează lexicografic liniile matricii, memorează ultima coloană și adaugă la finalul șirului astfel obținut numărul liniei pe care a ajuns cuvântul inițial, șirul rezultat fiind denumit cript-ul șirului inițial. Analizând matricea de caractere obținută ei au observat că în matrice se obțin submatrici cu proprietatea că în cele patru colțuri ale lor se află același caracter.

Cerința
Să se scrie un program care citește un număr natural c, reprezentând cerința care trebuie să fie rezolvată, apoi citește un cuvânt. Programul rezolvă următoarele cerințe:
1.	Dacă c = 1, șirul citit este un cuvânt necriptat, programul va determina și va afișa cript-ul obținut conform algoritmului descris anterior. 
2.	Dacă c = 2, șirul citit este un cript, programul va determina și va afișa cuvântul necriptat.
3.	Dacă c = 3, șirul citit este un cuvânt necriptat, programul va determina matricea de caractere obținută conform algoritmului descris anterior și va afișa numărul maxim de elemente dintr-o submatrice cu proprietatea că în colțurile sale se află același caracter. 

Date de intrare
Pe prima linie a fişierului de intrare criptare.in este scrisă cerința (1, 2 sau 3). Pe linia a doua a fișierului este scris un cuvânt. Dacă cerința este 1 sau 3 cuvântul este necriptat, dacă cerința este 2 cuvântul este un cript.

Date de ieșire
Dacă cerința este 1, pe prima linie a fișierului de ieșire criptare.out va fi scris criptul cuvântului citit. Dacă cerința este 2 pe prima linie va fi scris cuvântul necriptat. Dacă cerința este 3 pe prima linie va fi scris un număr natural reprezentând numărul maxim de elemente dintr-o submatice care are în colțurile sale același caracter.

Restricții și precizări

3 ≤ lungimea cuvântului aflat pe prima linie a fișierului ≤ 100
În matricea de cuvinte liniile şi coloanele se numerotează de la 0.
Dacă șirul inițial apare pe mai multe linii ale matricei, se va considera că prima apariție reprezintă șirul inițial.

Exemplul 1:
criptare.in

1
ANA
criptare.out

NAA1
Explicație
Permutare circulară		Ordonare ->	NAA1
ANA				AAN
NAA				ANA
AAN				NAA

Exemplul 2:
criptare.in

1
ANA
criptare.out

NAA1
Exemplul 3:
criptare.in

3
MERE
criptare.out

6
Explicație
Permutare circulară		Ordonare
MERE				EMER
EREM				EREM
REME				MERE
EMER				REME

## Cod sursă C++

```cpp
#include <fstream>
#include<cstring>
#include<algorithm>
using namespace std;
ifstream fin("criptare.in");
ofstream fout("criptare.out");
int n, i, c, j, poz, nr, A[101], ord[101], fr[26], amax, nraria;
char s[101], cs[101], cuv[101][101], rez[101], cmax;
int imax, jmax, kmax, undef;
void aria(char c)
{
     int i,j,unde,k;
     for(i=0; i<n; i++)
        for(j=i; j<n; j++)
        {
                unde=-1;///unde gasesc prima data acelasi caracter
                for(k=0; k<n; k++)
                    if(cuv[i][k]==c&&cuv[j][k]==c){
                    if(unde==-1)unde=k;
                    if(unde>=0&&(k-unde+1)*(j-i+1)>amax){amax=(k-unde+1)*(j-i+1);}
                    }
        }
}
int main()
{
    fin>>c>>s;
    if(c==1)
    {
        strcpy(cuv[0], s);
        n=strlen(s);
        ///permut circular
        for(i=1; i<n; i++)
        {
            for(int j=0; j<n-1; j++)
                cuv[i][j]=cuv[i-1][j+1];
            cuv[i][n-1]=cuv[i-1][0];
        }
        ///ordonare lexicografica
        for(i=0; i<n-1; i++)
            for(j=i+1; j<n; j++)
                if(strcmp(cuv[i], cuv[j])>0)swap(cuv[i], cuv[j]);
        for(i=0; i<n; i++)
            if(strcmp(cuv[i], s)==0)
            {
                poz=i;
                break;
            }
        for(i=0; i<n; i++)
            fout<<cuv[i][n-1];
        fout<<poz;
    }
    if(c==2)
    {
        ///determin prima cifra din stanga
        n=strlen(s);
        for(i=0; i<n; i++)
            if(s[i]>='0'&&s[i]<='9')
            {
                poz=i;
                break;
            }
        nr=0;
        for(i=poz; i<n; i++)
            nr=nr*10+(s[i]-'0');
        s[poz]='\0';
        n=strlen(s);
        for(i=0; i<n; i++)
            ord[i]=i;
        ///ordonez crescator caracterele din s
        strcpy(cs,s);
        for(i=0; i<n-1; i++)
            for(j=i+1; j<n; j++)
                if(s[i]>s[j]||s[i]==s[j]&&ord[i]>ord[j])
                {
                    swap(s[i],s[j]);
                    swap(ord[i],ord[j]);
                }
        ///construiesc sirul decriptat
        for(i=0; i<n; i++)A[i]=ord[i];
        int t=nr;
        for(i=0; i<n; i++)
        {
            rez[i]=cs[A[t]];
            t=A[t];
        }
        fout<<rez;
    }
    if(c==3)
    {
        strcpy(cuv[0], s);
        n=strlen(s);
        for(i=0; i<n; i++)fr[s[i]-'A']++;
        ///permut circular
        for(i=1; i<n; i++)
        {
            for(int j=0; j<n-1; j++)
                cuv[i][j]=cuv[i-1][j+1];
            cuv[i][n-1]=cuv[i-1][0];
        }
        ///ordonare lexicografica
        for(i=0; i<n-1; i++)
            for(j=i+1; j<n; j++)
                if(strcmp(cuv[i], cuv[j])>0)swap(cuv[i], cuv[j]);
        for(char c='A'; c<='Z'; c++)
            if(fr[c-'A']!=0)
            {
                aria(c);
            }
        fout<<amax;
    }
    return 0;
}
```

## Resurse

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