Se consideră un text memorat într-o matrice M
, definită prin coordonatele colţului stânga sus (x1,y1)
şi coordonatele colţului dreapta jos (x2,y2)
.
Prin aplicarea unui algoritm de compresie, matricei M
i se asociază un şir de caractere, notat C
M
. Şirul de caractere C
M
este construit prin aplicarea următoarelor reguli:
- dacă matricea
M
are o singură linie şi o singură coloană atunciC
M
conţine numai caracterul memorat în matrice; - dacă toate elementele matricei sunt identice atunci întreaga matrice
M
se comprimă şiC
M
este şirulkc
, undek
reprezintă numărul de caractere din matrice, iarc
caracterul memorat; - dacă matricea este formată din caractere diferite şi are cel puţin două linii şi două coloane atunci:
- matricea este împărţită în
4
submatriceA
,B
,C
,D
după cum este ilustrat în figura alăturată, unde coordonatele colţului stânga sus ale submatriceiA
sunt(x1,y1)
, iar coordonatele colţului dreapta jos sunt((x2+x1)/2,(y2+y1)/2)
; C
M
este şirul*C
A
C
B
C
C
C
D
undeC
A
,C
B
,C
C
,C
D
sunt şirurile de caractere obţinute, în ordine, prin compresia matricelorA
,B
,C
,D
utilizând acelaşi algoritm;
- matricea este împărţită în
- dacă matricea este formată din caractere diferite, are o singură linie şi mai multe coloane atunci
C
M
este şirul*C
A
C
B
undeA
,B
,C
A
,C
B
au semnificaţia descrisă la punctul 3.; - dacă matricea este formată din caractere diferite, are mai multe linii şi o singură coloană atunci
C
M
este şirul*C
A
C
C
undeA
,C
,C
A
,C
C
au semnificaţia descrisă la punctul 3.;
Cerinţă
Dat fiind şirul de caractere C
M
ce se obţine în urma aplicării algoritmului de compresie asupra unei matrice M de dimensiune NxN
să se determine:
- numărul de împărţiri care au fost necesare pentru obţinerea textului compresat;
- matricea iniţială din care provine textul compresat.
Date de intrare
Fișierul de intrare compresie.in
conţine pe prima linie un şir de caractere ce reprezintă textul compresat.
Date de ieșire
Fișierul de ieșire compresie.out
va conține:
- pe prima linie un număr natural ce reprezintă numărul
nr
de împărţiri care au fost necesare pentru obţinerea textului compresat; - pe următoarele
N
linii se găsesc câteN
caractere, litere mici ale alfabetului englez, neseparate prin spații, ce reprezintă, în ordine, liniile matricei iniţiale.
Restricții și precizări
2 ≤ N ≤ 1000
0 ≤ nr ≤ 1000000
2 ≤
lungimea şirului compresat≤ 1000000
- Textul memorat iniţial în matricea
M
conţine numai caractere din mulţimea literelor mici{a...z}
.
Exemplul 1
compresie.in
*4b*bbab4a*abbb
compresie.out
3 bbbb bbab aaab aabb
Explicație
Au fost efectuate 3 împărţiri:
- \( M = * \left( \begin{array}{cc}
b & b \\
b & b \end{array} \right)
\left( \begin{array}{cc}
b & b \\
a & b \end{array} \right)
\left( \begin{array}{cc}
a & a \\
a & a \end{array} \right)
\left( \begin{array}{cc}
a & b \\
b & b \end{array} \right) \) - \(
\left( \begin{array}{cc}
b & b \\
a & b \end{array} \right)
= * (b)(b)(a)(b) \) - \(
\left( \begin{array}{cc}
a & b \\
b & b \end{array} \right)
= * (a)(b)(b)(b) \)
Exemplul 2
compresie.in
*4a*ab*aba
compresie.out
3 aaa aab aba
Explicație
Au fost efectuate 3 împărţiri:
- \( M = * \left( \begin{array}{cc}
a & a \\
a & a \end{array} \right)
\left( \begin{array}{c}
a \\
b \end{array} \right)
\left( \begin{array}{cc}
a & b \end{array} \right)
\left( \begin{array}{c}
a \end{array} \right) \) - \(
\left( \begin{array}{c}
a \\
b \end{array} \right)
= * (a)(b) \) - \(
\left( \begin{array}{cc}
a & b \end{array} \right)
= * (a)(b) \)
Cum e corect?
cout < "As la info";
cout << "As la info";
cout >> "As la info";
Felicitări! Poți mai mult?
Avem sute de probleme pentru tine, fiecare cu explicații ușor de înțeles.
Greșit, dar nu-i bai!
Antrenează-te cu sutele de probleme pe care ți le-am pregătit. Îți explicăm fiecare problemă în parte.
Rezolvare
Iată rezolvarea de 100 de puncte pentru problema Compresie:
/*
Solutie prof. Eugen Nodea
streamuri
*/
# include <fstream>
# include <cmath>
# include <cstring>
using namespace std;
ifstream f("compresie.in");
ofstream g("compresie.out");
char s[1000001];
char M[1001][1001];
int L, N, nr, i, j, k;
void reconstruieste(short x1,short y1, short x2, short y2)
{
short mx, my, x, i, j;
//conditia de oprire
if (x1<=x2 && y1<=y2 && k<L)
{
//stapaneste
if (x1==x2 && y1==y2) M[x1][y1] = s[k++];
else
if (s[k]>='0' && s[k] <='9')
{
x = 0;
while (s[k]>='0' && s[k]<='9')
{
x = x*10 + (s[k] - '0');
++k;
}
//completez submatricea
for (i=x1; i<=x2; ++i)
for (j=y1; j<=y2; ++j)
M[i][j] = s[k];
++k;
}
else //s[k] == '*'
{
//divide
mx = (x2 + x1) >> 1; my = (y2 + y1) >> 1;
++k;
// reconstruiesc submatricile A,B,C,D
reconstruieste(x1, y1, mx, my); //A
reconstruieste(x1, my + 1, mx, y2); //B
reconstruieste(mx + 1, y1, x2, my); //C
reconstruieste(mx + 1, my + 1, x2, y2); //D
}
}
}
int main()
{
f.getline(s, 1000001);
f.close();
L = strlen(s);
//punctul 1
k = 0; nr = 0; j = 0;
for (i=0; i < L; ++i)
if (s[i] == '*') ++nr;
else if (s[i]>='0' && s[i]<='9') k = k*10 + (s[i] - '0');
else if (s[i]>='a' && s[i]<='z')
{
if (s[i-1]<'a' && k) j+=k, k=0;
else ++j;
}
N = (int) sqrt((double) j);
g << nr << "\n";
//punctul 3
k=0;
reconstruieste(1,1,N,N);
for (i=1; i<=N; ++i)
{
for (j=1; j<=N; ++j)
g << M[i][j];
g << "\n";
}
g.close();
return 0;
}
Atenție
Enunțurile afișate pe această pagină aparțin exclusiv site-ului PbInfo. Astfel, pentru ștergerea conținutului, puteți să ne contactați la adresa .
Rezolvarea problemei #1032 Compresie
Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #1032 Compresie de pe PbInfo.ro. Atenție: nu încurajăm copiatul codului! Totuși, credem cu tărie că analizarea unei soluții corecte este o metodă foarte ușoară de a învăța informatică, astfel că oferim sursele pentru peste 1500 de probleme de pe platforma PbInfo.ro.
Pentru rezolvări PbInfo de la peste 1500 de probleme, vă invităm să intrați pe site-ul nostru!