Sunteți pe pagina 1din 40

Tablouri

bidimensionale
!
!
!
!
!
!

Capitolul

12

Definiie
Operaii cu tablouri bidimensionale
Careuri magice
Implementri sugerate
Probleme propuse
Soluiile problemelor

Am vzut c ntr-un tablou unidimensional se pot pstra mai multe valori de acelai
tip. Fie, de exemplu, mediile generale ale tuturor elevilor unei clase. Toate mediile
(numere reale) se denumesc cu acelai identificator, de exemplu MedGen, iar un element n aceast grupare se gsete pe baza poziiei ocupate n grupul de valori, aranjate liniar. Dac privim irul numelor, acestea, la rndul lor formeaz un alt ir, n care
fiecare element este un ir de caractere.
Exemplu
MedGen
Nume

Poziie 1
2
... 30
Valoare 9.33 8.20 ... 9.63
Poziie 1
2
... 30
Valoare Albu Ban ... Zeciu

Corespunztor acestui exemplu ne puteam referi la nota unui elev prin MedGen[nr],
unde nr este numrul de ordine din catalog al elevului respectiv. Aceast valoare este
indicele elementului n ir.
Ne propunem s referim toate mediile pe discipline ale fiecrui elev printr-o singur variabil. Conform catalogului (cunoscut din coal) avem urmtoarele date:

1
2
...
30

Albu
Ban
...
Zeciu

1 (Limba romn)
7.33
6.67
...
9.10

2 (Matematic)
9.20
7.33
...
...

... 12 (Educaie fizic


...
10
...
10
...
...
...
10

240

12. Tablouri bidimensionale

Mediile tuturor elevilor unei clase la toate disciplinele studiate pot fi pstrate ntr-o
singur structur de date n care valorile sunt aranjate liniar pe linii i coloane (o linie
corespunde unui elev, o coloan corespunde unei discipline studiate). n exemplul de
mai sus, linia 2 corespunde elevului Ban, n coloana 12 sunt scrise mediile la educaie
fizic.
Tabloul bidimensional este o structur de date n care fiecrui element i este asociat o pereche de indici, primul preciznd numrul de ordine al liniei n care se afl elementul, iar cel de-al doilea numrul de ordine al coloanei. Media aflat pe linia i i
coloana j se va nota cu Medie[i, j] i reprezint media elevului i la disciplina j. Oricrui tablou bidimensional i se aloc spaiu de memorie ntr-o zon continu de memorie, elementele aflndu-se n locaii succesive de memorie aezate linie dup linie.
Exemplu
Un tablou bidimensional avnd trei linii i patru coloane se va reprezenta n memorie astfel:

Linia 1

Linia 2

Linia 3

Vom da definiia tabloului bidimensional*), n caz general:

12.1. Definiie
Fie M = {1, 2, ..., m} i N = {1, 2, , n} mulimea primelor m, respectiv n numere naturale nenule. Considerm o mulime de elemente E ale cror tip de baz este T.
Se numete tablou bidimensional de dimensiune m n, avnd elemente de tipul T,
o funcie A: M N E.
Notm elementele cu aij, unde i M, j N. Aceste elemente sunt aranjate pe m
linii i n coloane, astfel nct acele elemente care au indicele de linie i, sunt plasate pe
aceeai linie i, iar cele avnd acelai indice de coloan j, pe aceeai coloan j:

a11 a 21

a
a 22
A = 21
...
...
a
m1 a m 2
*)

... a1n

... a 2 n

...

... a mn

...

Noiunea de tablou bidimensional deriv din noiunea de matrice (cunoscut din matematic).

12. Tablouri bidimensionale

241

Cazuri particulare
1) Dac n = 1, avem un tablou de dimensiuni m 1 care se numete tablou coloan i
este de forma:
a11

a 21

A=
...
a
m1

2) Dac m = 1, tabloul de dimensiune 1 n se numete tablou linie i este de forma:


A = (a11, a12, , a1n)
3) Dac m = n, avem un tablou de dimensiune n n, numit tablou ptratic.
Exemplu
Fie un tablou ptratic de dimensiune 6 (m = n = 6).
i=j
i<j
a11
a12
a13
a14
a15

a16

a21

a22

a23

a24

a25

a26

a31

a32

a33

a34

a35

a36

a41

a42

a43

a44

a45

a46

a51

a52

a53

a54

a55

a56

a61

a62

a63

a64

a65

a66

i>j

Elementele n cazul crora indicele de linie coincide cu indicele de coloan (a11,

a22, ..., ann) formeaz diagonala principal a tabloului.


Paralelele la diagonala principal a tabloului vor atinge acele elemente n cazul crora i = j + k, unde n + 1 < k < n 1. Pentru fiecare valoare a lui k, variind j, obinem o paralel la diagonala principal.
Elementele de deasupra diagonalei principale satisfac proprietatea i < j, iar cele
care se situeaz sub diagonala principal au proprietatea c indicii lor satisfac relaia i > j.

242

12. Tablouri bidimensionale

n mod similar, irul de elemente a1,n, a2,n-1, ..., an,1 formeaz diagonala secundar

a tabloului. n cazul acestora, indicii elementelor respect relaia i + j = n + 1.


n cazul elementelor aflate deasupra diagonalei secundare indicii au proprietatea
i + j < n + 1, iar cele care se afl sub diagonala principal au indici cu proprietatea
i + j > n + 1.
Observm c pentru a parcurge doar elementele de sub diagonala principal, indicii
de linie i de coloan variaz astfel nct s acopere un triunghi dreptunghic din
tablou. Acest triunghi are ipotenuza sub diagonala principal i cele dou catete sunt
coloana 1 i linia n. n concluzie, la acest triunghi de pe linia i vor participa elementele
de pe coloanele 1, 2, ..., i 1.

12.2. Operaii cu tablouri bidimensionale


n algoritmi vom prelucra tablouri bidimensionale n cele mai variate moduri. Vom
face distincie ntre operaii care acceseaz tabloul ca pe un ntreg i operaii care
acceseaz elementele tabloului. Dar nainte de toate un tablou trebuie declarat.

12.2.1. Declararea tablourilor bidimensionale


Declaraia are urmtoarea form general:
type TipTab=array[tip_indice1, tip_indice2] of tip_de_baz;
var tablou:TipTab;

unde prin tip_indice1, tip_indice2 se nelege tipul valorilor din care se alimenteaz indicii (este obligatoriu un tip ordinal), iar tip_de_baz este tipul elementelor tabloului.
Acest tip de baz poate fi orice: putem avea elemente de orice tip numeric, de caractere sau iruri de caractere, valori booleene, nregistrri (vezi tipul record), tablouri de
cele mai diverse tipuri etc.
tip_indice1, tip_indice2 pot fi identificatori de tip predefinit sau definit de utilizator
i, de asemenea, pot fi expresii, cu meniunea c n acestea pot interveni doar constante i constante simbolice:
Exemplu
const n=5;
var TipTablou=array[1..2*n,1..n] of Byte;
Numere=array[Boolean,Byte] of Integer;

Dac structura unui tablou este descris n seciunea var, atunci el va avea un tip
anonim. Asociind tipului respectiv un identificator de tip ntr-o declaraie type, acesta
va putea fi folosit n program, oriunde vrem s referim acest tip.

12. Tablouri bidimensionale

243

Reamintim c dou tablouri declarate n dou declaraii anonime diferite vor fi de


tipuri diferite, chiar dac n ele s-a descris aceeai structur.
Exemplu

type TipTablou=array[1..10,1..5] of Byte;


var x,y:TipTablou;
a:array[1..10,1..5] of Byte;
b,c:array[1..10,1..5] of Byte;

n programul care conine aceste declaraii, tablourile x i y vor fi considerate de


acelai tip (TipTablou), b i c, de asemenea vor avea un tip comun (anonim), iar a va
fi de tip anonim diferit de TipTablou, respectiv de tipul anonim al lui b i c.

12.2.2. Citirea tablourilor bidimensionale


n programe, de regul, prima operaie va fi citirea unui astfel de tablou. n limbajele
Pascal i C nu se poate citi o variabil de tip tablou. Aceast operaie se va realiza element cu element.
Subalgoritm Citire(n,x):
citete m,n
pentru i=1,m execut:
pentru j=1,n execut:
citete x[i,j]
sfrit pentru
sfrit pentru
sfrit subalgoritm

{ tabloul x are m linii i n coloane }

12.2.3. Afiarea tablourilor bidimensionale


Afiarea tablourilor se realizeaz asemntor. Dac dorim s realizm o afiare linie
dup linie a tabloului x de tipul tablou, avnd m linii i n coloane, n Pascal vom
scrie procedura n felul urmtor:
procedure Afiare(m,n:Byte; x:tablou);
begin
for i:=1 to m do begin
for j:=1 to n do
Write(x[i,j],' ');
WriteLn
end
end;

{ trecem la linie nou }

244

12. Tablouri bidimensionale

12.2.4. Atribuirea
Atribuirea la nivel de tablou este permis doar dac identificatorii menionai n partea
stng i cea dreapt a operaiei de atribuire au acelai tip. De exemplu, conform declaraiilor din exemplul menionat, x poate primi valoarea lui y, iar b poate lua valoarea lui c. Putem scrie n program: x:=y; i b:=c; dar nu putem scrie a:=b;
innd cont de faptul c n multe aplicaii va fi necesar efectuarea unor operaii cu
elementele tablourilor bidimensionale, asemntor operaiilor din teoria matricelor n
matematic, vom prezenta cteva din aceste operaii.

12.2.5. Adunarea matricelor

Fie A i B dou matrice de dimensiune m n:


A = (aij), 1 i m, 1 j n,
B = (bij), 1 i m, 1 j n.
Definim matricea
C = (cij), 1 i m, 1 j n,
ale crei elemente sunt date de egalitile:
(*)
cij = aij + bij
oricare ar fi i = 1, 2, , m, j = 1, 2, , n.
Matricea C se numete suma dintre matricele A i B i se noteaz
C = A + B.
n program vom realiza adunarea element cu element, conform formulei (*).
Menionm c adunarea a dou matrice este comutativ: A + B = B + A i este asociativ: (A + B) + C = A + (B + C). Matricea element neutru fa de adunare se numete matrice nul i are toate elementele egale cu 0. Se va nota: 0mn.
O matrice format din elementul 0, mai puin pe diagonala principal, unde are numai valori egale cu 1, se numete matrice unitate i se noteaz cu In.

12.2.6. Matricea opus


Oricare ar fi matricea A, exist o matrice notat cu A astfel nct:
A + (A) = (A) + A = 0mn

12.3. Careuri magice


Exist o bogat tradiie a ptratelor magice. Referirile la primele ptrate magice se
pierd n negura timpurilor.
Definiie
Un careu de dimensiune n care conine numere de la 1 la n2 se numete magic, dac
suma numerelor de pe oricare linie a careului este egal cu suma numerelor de pe ori-

12. Tablouri bidimensionale

245

care coloan i sunt egale cu suma numerelor aflate pe oricare dintre cele dou diagonale. Aceast valoare se numete sum magic i se calculeaz cu formula:
sum_magic(n) = n (n2 + 1)/2.
Prezentm trei algoritmi diferii pentru generarea ptratelor magice, n funcie de
proprietatea lui n:
a) n este impar;
b) n este multiplu de 4;
c) n este par dar nu este multiplu de 4.

12.3.1. Ptratul magic de ordin impar


n cartea lui Feng Shui (Arta vieii n armonie cu natura), precum i n cartea lui Yi
Jing (Cartea schimbrilor) autorii consider c ptratul magic descoperit de Wu Hsia
a fost imaginat pe carapacea unei broate estoase. Acest ptrat magic este atribuit civilizaiei chineze dintre anii 2858 2738 nainte de Christos:

Traseul obinut prin parcurgerea n ordine a numerelor din acest careu magic este
cunoscut sub numele de drumul mpratului Ven. Urmrind acest traseu, putem
deduce modul de generare al oricrui careu magic de ordin impar. Se observ urmtoarele reguli:
Pornim din poziia avnd indicii 1 i n/2 (parte ntreag superioar).
Dac suntem pe prima linie, drumul continu pe ultima linie i pe coloana precedent, dac exist o astfel de coloan.
Dac suntem pe prima coloan, drumul continu pe ultima coloan i pe linia precedent, dac exist o astfel de linie.
n rest ncercm s avansm pe diagonal (paralel cu diagonala principal) spre
stnga-sus, dac avem poziie liber n careu n acea direcie. Cnd nu mai putem
avansa astfel, coborm cu o linie pe aceeai coloan.

12. Tablouri bidimensionale

246
Exemplu
n = 5,

paii 1, 2, 3, 4:
12

paii pn la pasul 17:

12

12
10
1

15

16 14

13

17

3
20

12 10

11

12.3.2. Ptratul magic de ordin multiplu de 4


Pentru a genera un ptrat magic de ordin n (n multiplu de 4), se aplic urmtorii pai:
Se genereaz ptratul de dimensiune n n care aezm numerele de la 1 la n2 n ordine pe linii.
Elementele aflate pe linii avnd numr de ordine pentru care restul mpririi la 4
este 0 sau 1 i coloane care nu au aceast proprietate, sau pe coloane avnd numr
de ordine pentru care restul mpririi la 4 este 0 sau 1 i linii care nu au aceast
proprietate, vor fi schimbate cu elementele aflate n poziii simetrice fa de mijlocul careului, aa cum se poate observa din figura urmtoare:
1

63

62

59

58

10

11

12

13

14

15

16

56

10

11

53

52

14

15

49

17

18

19

20

21

22

23

24

48

18

19

45

44

22

23

41

25

26

27

28

29

30

31

32

25

39

38

28

29

35

34

32

33

34

35

36

37

38

39

40

33

31

30

36

37

27

26

40

41

42

43

44

45

46

47

48

24

42

43

21

20

46

47

17

49

50

51

52

53

54

55

56

16

50

51

13

12

54

55

57

58

59

60

61

62

63

64

57

60

61

64

12.3.3. Ptrat magic de ordin n, unde n = 2 m (m numr impar)

Algoritmul de generare a unui ptrat magic de ordin n, unde n = 2 m i m este numr


impar, este o metod elegant, ajuns prima dat n Europa prin Siam.

12. Tablouri bidimensionale

247

Acest algoritm se aplic conform urmtorilor pai:


Se calculeaz valoarea lui m;
Se genereaz o matrice de litere (construcie ajuttoare) astfel:
primele [m / 2] +1 linii se completeaz cu litera L;
linia urmtoare se completeaz cu litera U;
restul liniilor se completeaz cu litera X;
litera L aflat n mijlocul careului se interschimb cu litera U aflat sub ea.
Exemplu
Dac n = 10, avem m = 5.

ptratul magic de dimensiune 2m se construiete urmrind algoritmul de generare


a ptratelor magice impare, considernd ptratul de dimensiune m (m este impar),
format din ptrate de dimensiune 2.
Fiecare ptrat de dimensiune 2 2 va avea ca i corespondent o liter L, U, sau
X i va fi completat n ordinea sugerat de aceast liter:
4
1
1
4
1
4
L:
U:
X:
2

Aplicm paii algoritmului Ven prezentat anterior:


1 4
4
3
2

12. Tablouri bidimensionale

248

Obinem:
60

57

32

29

96

93

68

65

58

59

30

31

94

95

66

67

64

61

56

53

28

25

20

17

92

89

62

63

54

55

26

27

18

19

90

91

88

85

80

77

49

52

24

21

16

13

86

87

78

79

50

51

22

23

14

15

12

81

84

76

73

45

48

37

40

10

11

82

83

74

75

46

47

38

39

33

36

97

100

69

72

41

44

35

34

99

98

71

70

43

42

12.4. Implementri sugerate


Pentru a v familiariza cu modul n care trebuie rezolvate problemele n cadrul crora
intervin operaii cu fiiere text, v sugerm s ncercai s implementai algoritmi pentru:
1. suma elementelor unui tablou bidimensional;
2. identificarea liniei i coloanei pe care se afl minimul/maximul unui tablou bidimensional;
3. suma elementelor de pe diagonala principal;
4. suma elementelor de pe diagonala secundar;
5. suma elementelor de deasupra (de dedesubtul) diagonalei principale;
6. suma elementelor de deasupra (de dedesubtul) diagonalei secundare;

12. Tablouri bidimensionale

249

7. determinarea sumei celor opt vecini ai unui element;


8. determinarea sumelor elementelor aflate n triunghiul de N, S, E i V delimitat de
diagonalele matricei;
9. rotirea unui tablou bidimensional cu 90 de grade;
10. determinarea matricei simetrice fa de diagonala principal (secundar);
11. nlocuirea elementelor din triunghiul de nord cu cele din triunghiul de vest (i variante);
12. parcurgerea pe diagonale a unei matrice;
13. parcurgerea n spiral a unei matrice;
14. calcularea sumelor de-a lungul laturilor matricelor ptratice;
15. verificarea unei proprieti globale a unui tablou bidimensional;
16. produsul a dou matrice de numere;
17. produsul a n matrice;
18. inversarea a dou linii/coloane ntr-o matrice;
19. ordonarea liniilor astfel nct elementele de pe diagonala principal/secundar s
fie n ordine cresctoare/descresctoare;
20. verificarea triunghiularitii unei matrice (inferior, superior triunghiular);
21. suma elementelor unui tablou n-dimensional;
22. identificarea coordonatelor unui element avnd o valoare dat (toate apariiile) ntr-un tablou n-dimensional;
23. verificarea proprietii de ptrat magic.

12.5. Probleme propuse


12.5.1. Petera
O peter are n ncperi numerotate de la 1 la n. ntre anumite ncperi s-au amenajat
coridoare de acces, altele au rmas izolate. Administratorul complexului turistic cruia
i s-a dat n grij petera ar vrea s tie rspunsul la urmtoarele ntrebri:
1. Care sunt ncperile n care intr cele mai multe coridoare?
2. Care sunt ncperile unde petera se nfund?
3. Care sunt ncperile izolate?
Date de intrare
Prima linie a fiierului de intrare PESTERA.IN conine numrul natural nenul n al ncperilor peterii. Pe urmtoarele n linii sunt scrise cte n valori 0 i 1, valorile elementelor unui tablou bidimensional p. Valorile 0 i 1 au urmtoarea semnificaie:
pij = 1, dac ntre ncperea i i ncperea j exist cale de acces amenajat.
pij = 0, n caz contrar.
Valorile scrise pe o aceeai linie din fiier sunt desprite prin cte un spaiu.

250

12. Tablouri bidimensionale

Date de ieire
Pe prima linie a fiierului de ieire PESTERA.OUT se vor scrie numerele de ordine ale
ncperilor n care intr sau din care ies un acelai numr maxim de coridoare.
Pe a doua linie se vor afla numerele de ordine ale ncperilor n care petera se
nfund. n cazul n care nu exist astfel de ncperi, n fiier se va scrie mesajul 'Nu
exista'.
A treia linie a fiierului (i ultima) va conine numerele de ordine ale ncperilor
izolate. Dac asemenea ncperi nu exist, se va afia mesajul: 'Nu exista.'
Restricii i precizri
1 n 100.
Exemple
PESTERA1.IN
5
0 0 1 0 0
0 0 0 0 0
1 0 0 0 1
0 0 0 0 1
0 0 1 1 0
PESTERA2.IN
5
0 1 1 0 0
1 0 0 0 0
1 0 0 0 1
0 0 0 0 1
0 0 1 1 0

PESTERA1.OUT
3 5
1 4
2

PESTERA2.OUT
1 3 5
2 4
Nu exista.

12.5.2. Acvariul cu peti


ntr-un acvariu sunt introdui n peti de diferite specii, printre care i unele carnivore.
Pentru fiecare pete se cunosc petii pe care acesta i-ar mnca (n cazul n care mnnc ali peti). Deoarece nu toi petii sunt foarte nfometai, nu se cunoate ordinea
n care acetia se vor ataca. Stabilii speciile de peti care, dup un interval de timp,
vor rmne n via n mod sigur!
Date de intrare
Pe prima linie a fiierului de intrare PESTI.IN se gsete numrul natural nenul n, reprezentnd numrul de peti. Pe urmtoarele n linii se afl elementele tabloului bidimensional p, avnd valori 0 i 1 (desprite prin spaii) cu urmtoarea semnificaie:
pij = 1, dac specia i mnnc specia j.
pij = 0, n caz contrar.

12. Tablouri bidimensionale

251

Date de ieire
Pe prima linie a fiierului de ieire PESTI.OUT se va scrie un ir de numere, separate
prin cte un spaiu, reprezentnd numerele de ordine a speciilor de peti care supravieuiesc n mod sigur n acvariu.
Restricii i precizri
1 n 100;
Dac un pete de specia i mnnc peti de specia j i specia j mnnc peti de
specia i, nici unul nu rmne n mod sigur n via, deoarece nu tim nimic referitor
la ordinea n care ei se vor mnca ntre ei.
Exemplu
PESTI.IN
6
0 0 1 0 0
0 0 0 0 0
0 1 0 0 0
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0

0
0
0
1
0
0

PESTI.OUT
4 5

Explicaie
Petele 1 mnnc petele 3.
Petele 2 nu este carnivor.
Petele 3 mnnc petele 2.
Petele 4 mnnc petele 1 i 6.
Petele 5 i petele 6 nu sunt carnivori.
Deci, deoarece petii 1, 2, 3 i 6 pot fi
mncai de ali peti, rmn n via cu
siguran petii 4 i 5.

12.5.3. Tir sportiv


Un matematician, iubitor de tir sportiv, i-a pus problema construirii unei inte ptrate
de latur n n care punctajele s fie distribuite dup reguli matematice proprii. El mai
nti a generat irul punctajelor pe baza unei reguli, obinnd: 2, 3, 4, 2, 5, 6, 3, 7, 8, 4,
9, 3, 10, 5, 11, 12, 6, ...

22 11 23 ...

21

10

10

20

11

18

12

17 8

16 5

15 7

14 13 6

12. Tablouri bidimensionale

252

Se observ c fiecare numr natural neprim este urmat de cel mai mare divizor
(prim sau nu) al su. Pentru o bun distribuie a acestor numere, matematicianul s-a
gndit s le aeze pe inta ptratic de-a lungul unei spirale, ncepnd din colul stnga-sus, continund spre dreapta, apoi n jos, urmnd apoi marginea de jos de la dreapta
la stnga, apoi n sus i continund spirala ct timp este posibil.
Scriei un program care construiete inta pentru un ptrat de latur n, respectnd
regulile matematicianului.
Date de intrare
n fiierul de intrare TIR.IN se gsete numrul natural nenul n, reprezentnd lungimea laturii intei.
Date de ieire
inta generat se va scrie sub forma unui tablou bidimensional n fiierul de ieire
TIR.OUT, unde pe linia i se vor scrie elementele situate pe cea de-a i-a linie n int.
Numerele scrise pe linii vor fi separate prin cte un spaiu.
Restricii i precizri
1 n 150.
Exemplu
TIR.IN
5

TIR.OUT
2 3 4 2
12 6 13 14
11 8 17 7
5 16 5 15
10 3 9 4

5
6
3
7
8

12.5.4. Biliard

O bil este lovit cu tacul pe o mas de biliard dreptunghiular, de dimensiune m n


ntr-o direcie oblic (dreapta-sus, dreapta-jos, stnga-jos sau stnga-sus). Atunci cnd
bila se lovete de o margine a mesei, cu excepia colurilor, ea ricoeaz, noul traseu al
ei formnd un unghi de 90 cu vechiul traseu. Dac bila ajunge ntr-un col, ea iese de
pe mas. Cunoscnd dimensiunile mesei, poziia de plecare a bilei i direcia de deplasare iniial, s se simuleze micarea bilei pn la ieirea de pe mas, sau pn cnd se
observ c traseul acesteia intr n ciclu.

Date de intrare
Prima linie a fiierului de intrare BILIARD.IN conine numerele m i n, reprezentnd
dimensiunea mesei. Pe linia a doua se gsesc coordonatele poziiei iniiale a bilei, iar
pe a treia linie se afl o cifr din mulimea {1, 2, 3, 4}, reprezentnd direcia de pornire a bilei: 1 corespunde direciei dreapta-sus, 2 direciei dreapta-jos, 3 direciei stngajos, iar 4 direciei stnga-sus.

12. Tablouri bidimensionale

253

Date de ieire
Fiierul de ieire BILIARD.OUT va conine traseul bilei sub forma unui tablou bidimensional de dimensiuni corespunztoare mesei. Fiecare linie a tabloului se va scrie
pe linie nou n fiier. Elementul corespunztor poziiei iniiale a bilei se marcheaz cu
1, urmtoarea poziie atins de bil conform direciei de micare cu 2 etc. n cazul n
care bila trece a doua oar printr-o poziie, se pstreaz primul marcaj. Poziiile nestrbtute vor conine valoarea 0.
Dac bila nu poate iei de pe mas, deoarece traseul ei formeaz un ciclu, n fiier
se va scrie mesajul 'Bila nu poate iesi de pe masa.', apoi se va scrie n fiier tabloul bidimensional corespunztor micrilor bilei.
Restricii i precizri
1 m, n 100.
Exemple

BILIARD1.IN
3 3
2 1
1

BILIARD1.OUT
Bila nu poate iesi de pe masa.
0 2 0
1 0 3
0 4 0

BILIARD2.IN
5 7
4 2
1

BILIARD2.OUT
12 0 0 0 4 0
0 11 0 3 0 5
0 0 2 0 0 0
0 1 0 9 0 7
0 0 0 0 8 0

0
0
6
0
0

12.5.5. Puncte a
Se numete punct a ntr-un tablou bidimensional, poziia n care elementul este minim pe coloana lui i maxim pe linie, sau invers. Scriei un program care determin
toate punctele a ntr-o matrice bidimensional dreptunghiular.
Date de intrare
Prima linie a fiierului de intrare SA.IN conine numerele m i n, reprezentnd dimensiunile tabloului. Pe fiecare dintre urmtoarele m linii se afl cte n numere ntregi,
desprite prin cte un spaiu, reprezentnd elementele matricei.
Date de ieire
Fiierul de ieire SA.OUT va conine attea linii cte puncte a s-au gsit. Corespunztor unui astfel de punct n fiier se vor scrie dou numere naturale, desprite printr-un
spaiu, reprezentnd indicii punctului a. Dac tabloul dat nu are nici un punct a, n
fiier se va scrie mesajul 'Nu exista punct sa.'.

12. Tablouri bidimensionale

254
Restricii i precizri
1 n 100;
1 m 100;
Numerele tabloului sunt distincte.
Exemple
SA.IN
3 4
2 -1 3 0
1 0 4 0
5 -8 9 1

SA.OUT
1 3
2 2

12.5.6. Rame de tablouri care trebuie suprapuse

ntr-un spaiu dreptunghiular de dimensiune m n trebuie aezate una dup alta p rame de tablouri de dimensiune dat. Ramele se pot aeza unele peste altele, astfel nct
laturile lor vor fi paralele cu marginile spaiului de depozitare.
S se afieze, sub forma precizat la date de ieire ceea ce va vedea din ramele suprapuse o persoan care se va uita la teancul de rame dintr-o poziie situat deasupra
spaiului n care acestea s-au aezat.
Date de intrare
De pe prima linie a fiierului de intrare RAME.IN se vor citi numerele m i n, reprezentnd dimensiunile spaiului n care se aeaz ramele. Pe urmtoarea linie se afl numrul natural p, reprezentnd numrul ramelor care trebuie suprapuse. Urmtoarele p linii
conin fiecare coordonatele colului stnga-sus (indicele de linie i de coloan) al unei
rame, lungimea (n numr de linii) i limea (n numr de coloane) a ramei.
Date de ieire
n fiierul de ieire RAME.OUT se va scrie un tablou bidimensional de caractere, reprezentnd imaginea cu ramele suprapuse. Pentru o ram se va specifica doar chenarul ei.
Acestea se vor codifica cu literele mari ale alfabetului englez n ordinea n care sunt
descrise n fiierul de intrare, ncepnd cu litera 'A'. Atunci cnd o ram se suprapune
peste una aezat deja i va acoperi caracterele din chenar n poziiile n care cele dou
rame se intersecteaz pe limea unui singur caracter (coloan).
Restricii i precizri
1 m 100;
1 n 100;
1 p 25;
Dac dimensiunile unei rame depesc spaiul de depozitare, rama respectiv nu
va fi depozitat, iar litera care i corespunde nu va fi utilizat.

12. Tablouri bidimensionale

255

Exemplu
RAME.IN
12 9
3
3 1 8 7
2 3 4 3
1 4 12 6

RAME.OUT
A
A
A
A
A
A
A
A

B
B
B
B

C
C
C
C
C
C
C
C
C
C
C
C

C
B
B
B
B

A
A
A
A
A
A
A
A

C
C
C
C
C
C
C
C
C
C
C
C

12.5.7. Rame de tablouri suprapuse

ntr-un spaiu dreptunghiular de dimensiune m n au fost aezate una dup alta p rame
de tablouri. Ramele pot fi aezate unele peste altele, astfel nct laturile lor vor fi paralele cu marginile spaiului de depozitare.
Cunoscnd imaginea pe care o vede din ramele suprapuse o persoan care se uit la
teancul de rame dintr-o poziie situat deasupra spaiului n care acestea s-au aezat, s
se determine ordinea n care este posibil ridicarea tuturor ramelor. Se tie c fiecare
ram este descris n mod unic folosind o liter mare a alfabetului englez i c atunci
cnd au fost suprapuse dou rame se va vedea complet numai rama de deasupra.
Date de intrare
De pe prima linie a fiierului de intrare RAME.IN se citesc dimensiunile m i n a spaiului n care aezm ramele. De pe urmtoarele m linii se citete imaginea pe care o vede persoana. Codificarea imaginii este realizat ntr-un tablou bidimensional corespunztor spaiului de depozitare n care pentru o ram se va specifica doar chenarul ei.
Acestea sunt codificate cu literele mari ale alfabetului englez n ordinea n care au fost
depozitate. Atunci cnd o ram s-a suprapus peste una aezat deja ea acoper caracterele din chenar n poziiile n care cele dou rame se intersecteaz pe limea unui singur caracter (coloan).
Date de ieire
Fiierul RAME.OUT va conine un ir de litere mari ale alfabetului englez, desprite
printr-un spaiu, care corespund ramelor n ordinea n care acestea se pot ridica.
Restricii i precizri
1 m 100;
1 n 100;

12. Tablouri bidimensionale

256

1 p 25;
Din fiecare latur a fiecrei rame se vede cel puin un punct.

Exemplu

RAME.IN
12 9
O
V O
K K V O
K
V O
K
V O
K
O
K
O
K
O
K
O
K K K O
O
O

O O O O O
V
O
V K K
O
V
K
O
V
K
O
K
O
K
O
K
O
K
O
K K K
O
O
O O O O O

RAME.OUT
O V K

12.5.8. Prelucrare de imagine


O imagine alb-negru este preluat codificat ntr-un tablou bidimensional de valori 0
sau 1 de dimensiune m m. Asupra acestei imagini se pot efectua urmtoarele transformri:
Transformarea video Invers: valorile 0 se transform n 1 iar valorile 1 n 0.
Rotire cu 90: se creeaz un tablou rotit n sensul acelor de ceasornic.
Zoom: imaginea se mrete la dimensiunea 2m 2m.
Se definete o secven de transformri ca fiind o succesiune de litere I, R i Z.
S se afieze tabloul bidimensional la care s-a ajuns n urma unui ir de transformri cerute.
Date de intrare
De pe prima linie a fiierului de intrare IMAG.IN se citete un numr natural m, reprezentnd dimensiunea tabloului. Pe urmtoarele m linii se afl elementele tabloului bidimensional corespunztor unei imagini, linie dup linie. Elementele sunt separate
prin cte un spaiu.
Din fiierul de intrare TRANS.IN se citete succesiunea de litere I, R i Z corespunztoare unor transformri dorite. Aceste caractere nu sunt desprite de spaiu.
Date de ieire
Pe prima linie a fiierului IMAG.OUT se vor scrie dimensiunile actuale ale tabloului.
Pe urmtoarele linii se vor afla elementele tabloului bidimensional obinute ca urmare
a transformrilor efectuate.

12. Tablouri bidimensionale

257

Restricii i precizri
1 m 100 (indiferent de transformrile aplicate);
literele sunt majuscule din alfabetul englez.
Exemple
IMAG.IN
8
0 0 0 0
0 1 0 0
1 1 1 0
0 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
0 0 0 0

0
0
0
0
0
0
1
0

0
0
1
0
0
1
0
0

0
1
1
0
1
0
0
0

0
0
1
0
0
0
0
0

IMAG.IN
4
1 1 1 1
1 0 0 1
1 0 0 1
1 1 1 1

TRANS.IN
RIR

TRANS.IN
Z

IMAG.OUT
8
1 1 1 1 1
1 1 1 0 0
1 1 0 1 1
1 0 1 1 1
1 1 1 1 1
0 0 0 1 1
1 0 1 1 1
1 1 1 1 1

1
1
0
1
1
0
1
1

1
1
1
0
1
0
0
1

1
1
1
1
1
0
1
1

IMAG.OUT
8
1 1 1 1 1
1 1 1 1 1
1 1 0 0 0
1 1 0 0 0
1 1 0 0 0
1 1 0 0 0
1 1 1 1 1
1 1 1 1 1

1
1
0
0
0
0
1
1

1
1
1
1
1
1
1
1

1
1
1
1
1
1
1
1

12.5.9. Careu magic


S se genereze un ptrat magic de dimensiune n, unde n este un numr ntreg pozitiv.
Date de intrare
n fiierul de intrare MAG.IN se gsete numrul n, reprezentnd dimensiunea careului
care trebuie generat.
Date de ieire
Pe prima linie a fiierului de ieire MAG.OUT se va afla numrul n. Pe urmtoarele n linii se vor scrie numerele de pe cele n linii ale careului, dou numere fiind separate
prin cte un spaiu.
Restricii i precizri
1 n 40.

12. Tablouri bidimensionale

258
Exemple
MAG.IN
6

MAG.IN
4

MAG.IN
3

MAG.OUT
6
6 32 3
7 11 27
19 14 16
18 20 22
25 29 10
36 5 33
MAG.OUT
4
4 14 15
9 7 6
5 11 10
16 2 3

34
28
15
21
9
4

35
8
23
17
26
2

1
30
24
13
12
31

1
12
8
13

MAG.OUT
3
4 9 2
3 5 7
8 1 6

Explicaie
n este numr par fr a fi
multiplu de 4.

Explicaie
n este multiplu de 4.

Explicaie
n este numr impar.

12.6. Soluiile problemelor propuse


12.5.1. Petera
Vom descompune problema n subprobleme i vom proiecta pentru fiecare subproblem rezolvri pe care le vom implementa folosind subprograme.
1. Tabloul bidimensional care conine particularitile peterii l citim din fiier.
Subalgoritm Citire(n,p):
citete n
pentru i=1,n execut:
pentru j=1,n execut:
citete p[i,j]
sfrit pentru
sfrit pentru
sfrit subalgoritm

2. Numrm coridoarele care intr n ncperi. Cunoatem semnificaia valorilor


pij, deci, pentru a determina numrul coridoarelor care se ntlnesc n ncperea
i (pentru i fixat i valori posibile i =1, 2, , n), vom aduna valorile pij, unde
j = 1, 2, , n, adic vom aduna elementele pe linii.

12. Tablouri bidimensionale

259

Subalgoritm Numrare(n,p,nr_coridoare):
pentru i=1,n execut:
nr_coridoare[i] 0
pentru j=1,n execut:
nr_coridoare[i] nr_coridoare[i] + p[i,j]
sfrit pentru
sfrit pentru
sfrit subalgoritm

3. Determinm valoarea maxim a numerelor care reprezint numrul coridoarelor care se ntlnesc ntr-o ncpere.
Subalgoritm Maxim(n,nr_coridoare,max):
max nr_coridoare[1]
pentru i=2,n execut:
dac nr_coridoare[i] > max atunci
max nr_coridoare[i]
sfrit dac
sfrit pentru
sfrit subalgoritm

4. Selectarea numerelor de ordine ale ncperilor n care intr sau ies un acelai
numr maxim de coridoare se realizeaz cu un algoritm de selectare:
Subalgoritm CareMax(n,nr_coridoare,max):
pentru i=1,n execut:
dac nr_coridoare[i] = max atunci
scrie i
sfrit dac
sfrit pentru
sfrit subalgoritm

5. Determinm ncperile n care petera se nfund, folosind irul construit anterior. Dac valoarea elementului avnd indicele i este egal cu 1 (am putut veni
de undeva pe un coridor pn aici), atunci petera se nfund n ncperea i.
Subalgoritm Se_nfund(n,nr_coridoare):
gsit fals
pentru i=1,n execut:
dac nr_coridoare[i] = 1 atunci
scrie i
gsit adevrat
sfrit dac
sfrit pentru

260

12. Tablouri bidimensionale

dac nu gsit atunci


scrie 'Nu exista.'
sfrit dac
sfrit subalgoritm

6. Depistarea ncperilor izolate o realizm cu ajutorul aceluiai ir, cutnd elemente egale cu 0 (nu intr, nu iese nici un coridor).
Subalgoritm Izolate(n,nr_coridoare):
gsit fals
pentru i=1,n execut:
dac nr_coridoare[i] = 0 atunci
scrie i
gsit adevrat
sfrit dac
sfrit pentru
dac nu gsit atunci
scrie 'Nu exista.'
sfrit dac
sfrit subalgoritm

12.6.2. Acvariul cu peti


Este evident c, din cauza c nu tim nimic despre ordinea n care se mnnc petii,
pentru a depista speciile care rmn sigur n via, este suficient s cutm n tabloul
dat coloanele care nu conin nici o valoare 1. Indicii acestor coloane reprezint numerele de ordine ale speciilor cutate.
Vom parcurge tabloul dat pe linii i vom marca ntr-o variabil boolean (victim)
cu valoarea adevrat, dac pe linia respectiv gsim cel puin o valoare 1. Cu alte cuvinte, petii care pot fi mncai de un alt pete, indiferent care, sunt marcai ca victime.
Aceast prelucrare o putem realiza n paralel cu citirea datelor. De asemenea, nainte
s trecem la alt linie, n cazul n care petele de indice i nu este victim, l scriem n
fiier.
Algoritm Citire_cu_Prelucrare(n,p,victim):
citete n
pentru i=1,n execut:
victim fals
pentru j=1,n execut:
citete p[i,j]
dac p[i,j] = 1 atunci
victim adevrat
sfrit dac
sfrit pentru

12. Tablouri bidimensionale


dac nu victim atunci
scrie i
sfrit dac
sfrit pentru
sfrit subalgoritm

261

{ afiarea speciilor supravieuitoare }

12.6.3. Tir sportiv


Pentru rezolvarea acestei probleme este util s crem n prealabil irul de numere dup
regula enunat. Pentru valori mici ale lui n irul va fi creat ntr-un tablou unidimensional, pentru valori mari ale lui n putem crea irul respectiv ntr-un fiier de tip text.
De asemenea, lsm pe seama cititorilor s realizeze o implementare n care numerele
generate se scriu direct pe int, evitnd astfel utilizarea unui ir (sau fiier) de lucru.
n pseudocodul descris n continuare nu verificm separat dac numrul este prim
sau nu, ci n primul rnd, dup ce orice numr curent k s-a scris n ir, vom cuta
primul su cel mai mic divizor, urmnd s folosim n ir ctul mpririi ntregi al lui k
la acesta (adic pe cel mai mare divizor). Dac nu gsim un astfel de divizor, nseamn
c numrul nu este prim, iar divizorul gsit l scriem n fiier.
Subalgoritm Generareir(nn):
{ nn = n*n, numrul numerelor pe int }
{ i = numr numere generate }
i 0
k 2
{ k = numerele pe care le scriem n fiier, primul numr este 2 }
ct timp i<nn execut:
{ crete contorul ptrelelor ocupate }
i i + 1
scrie k
{ l scriem pe k n fiier }
rad parte ntreag din rdcina ptrat a lui k
dac k este numr par atunci
divizor 2
altfel
divizor 3
{ cel mai MIC divizor al lui k }
ct timp (k mod divizor 0) i (divizor rad) execut:
divizor divizor + 2
{ divizori impari }
sfrit ct timp
sfrit dac
dac divizor rad atunci
{ avem un divizor }
i i + 1
{ ne pregtim s scriem un numr n fiier }
dac i nn atunci
{ l scriem numai dac avem nevoie de el }
{ scriem cel mai MARE divizor }
scrie k div divizor
sfrit dac
sfrit dac
k k + 1
{ urmtorul numr }
sfrit ct timp
sfrit subalgoritm

262

12. Tablouri bidimensionale

Avnd numerele necesare intei generate n fiier, le vom citi unul cte unul i le
vom aeza n tabloul bidimensional pe poziia corespunztoare parcurgerii acestuia n
spiral.
Vom reine cteva proprieti pe care le vom fructifica n algoritm:
1. Mai nti observm c aceast spiral se termin, fie dup o parcurgere a ultimelor
poziii din stnga spre dreapta (dimensiunea tabloului este numr impar), fie dup o
parcurgere a ultimelor poziii din dreapta spre stnga (dimensiunea tabloului este numr par).
n figurile de mai jos sunt prezentate cele dou cazuri, pentru n = 3, respectiv n = 4.

2. O alt observaie se refer la faptul c, atunci cnd suntem pe cercul exterior al


spiralei, avem de parcurs linia 1 de la primul su element la ultimul, a n-a coloan de
la al doilea element al su (primul a fost parcurs atunci cnd am lucrat pe linia 1) la ultimul, apoi a n-a linie de la penultimul element la primul. n final, vom parcurge prima
coloan de la penultimul su element pn la al doilea (ultimul a fost parcurs atunci
cnd am prelucrat ultima linie, iar primul atunci cnd am prelucrat linia 1). Ceea ce
este i mai important de observat se refer la faptul c atunci cnd vom parcurge un
cerc interior, imediat urmtor exteriorului, toate limitele de nceput cresc cu 1, iar
limitele de sfrit scad cu 1. n consecin, vom iniializa dou variabile (primul cu 1
i ultimul cu n) care i vor schimba valorile dup nchiderea unui cerc a spiralei
(primul primul + 1, ultimul ultimul - 1).
Din observaia 1. rezult c vom ncepe aezarea numerelor din fiier, indiferent de
paritatea lui n parcurgnd elementele tabloului pe linia de indice primul spre dreapta.
Ar urma parcurgerea de sus n jos a coloanei de indice ultimul, dar aceast parcurgere
nu ntotdeauna este posibil (necesar) i anume, dac n este impar, dup o asemenea
parcurgere se termin prelucrarea. Subalgoritmul care creeaz inta este urmtorul:
Subalgoritm Creareint(n,nn,inta):
primul 1
ultimul n
folosite 0

parcurgem prima linie de la stnga la dreapta


dac n este numr impar atunci
ct timp folosite < nn execut:
{ n variabila folosite numrm poziiile prelucrate pe int }
parcurgem coloana de indice ultimul de sus n jos

12. Tablouri bidimensionale

263

parcurgem linia de indice ultimul de la dreapta la stnga


parcurgem coloana de indice primul de jos n sus
primul primul + 1
ultimul ultimul - 1
parcurgem linia de indice primul de la stnga la dreapta

sfrit ct timp
altfel n este numr impar atunci

parcurgem ultima coloan de sus n jos


parcurgem ultima linie de la dreapta la stnga
ct timp folosite < nn execut:
{ n variabila folosite numrm poziiile prelucrate pe int }
parcurgem coloana de indice primul de jos n sus
primul primul + 1
ultimul ultimul - 1
parcurgem linia de indice primul de la stnga la dreapta
parcurgem coloana de indice ultimul de sus n jos
parcurgem linia de indice ultimul de la dreapta la stnga
sfrit ct timp
sfrit dac
sfrit subalgoritm

Parcurgerile menionate mai sus nu sunt problematice. Trebuie doar s avem grij
s nu prelucrm un acelai element de dou ori, deoarece astfel am suprascrie anumite
valori i n final nu ne-ar ajunge numerele generate n fiier. Pentru exemplificare, s
vedem parcurgerea de jos n sus:
Subalgoritm JosSus(primul,ultimul,folosite):
pentru i=ultimul-1,primul+1,-1 execut:
{ pasul este 1! }
folosite folosite + 1
citete nr
{ se citete numrul curent din fiierul de manevr }
int[i,primul] nr
{ elementul de pe linia i i coloana primul n tabloul corespunztor intei }
sfrit pentru
sfrit subalgoritm

12.6.4. Biliard
Rezolvarea problemei necesit simularea anumitor deplasri de-a lungul unor linii care
sunt paralele cu diagonalele ptratului decupat de micarea bilei din tabloul bidimensional dreptunghiular, corespunztor mesei i o stpnire corect a schimbrilor
de direcie atunci cnd bila se lovete de marginea mesei.

12. Tablouri bidimensionale

264

Vom defini dou iruri de cte patru elemente n care vom pstra valorile care trebuie adunate coordonatei x, respectiv coordonatei y, pentru a ne deplasa pe o direcie
dat d. Deplasarea n cele patru direcii le putem codifica n felul urmtor:
d

poziia curent
noua poziie

i, j
i 1, j + 1
scade linia
crete coloana
1
1

i, j
i + 1, j + 1
crete linia
crete coloana
1
1

i, j
i + 1, j 1
crete linia
scade coloana
1
1

i, j
i 1, j 1
scade linia
scade coloana
1
1

Dx
Dy

La fiecare pas, coordonatele i i j se modific n i + Dx[d], respectiv j + Dy[d].


Acest mod de reprezentare ne va uura gestionarea schimbrilor de direcie.
Observm c la ntlnirea unei margini a mesei, corespunztoare unei margini verticale n tablou, direcia de deplasare se modific astfel:
direcia 3 se transform n direcia 2, i invers:

direcia 1 se transform n direcia 4 i 4 n 1:

La ntlnirea unei margini a mesei, corespunztoare unei margini orizontale n tablou, direcia 1 se schimb n direcia 2 i 2 n 1, iar direcia 4 se transform n 3 i 3
n 4. Vom asigura schimbarea direciei cu o structur de tip repet, care se va executa pn cnd bila iese printr-un col sau intr n ciclu.
n subalgoritmul urmtor, n variabila pas generm valoarea care marcheaz momentul n care bila traverseaz un anumit punct de pe mas. Dac mingea ar urma si reia traseul i astfel s intre n ciclu infinit, variabila boolean infinit primete valoarea adevrat. Pentru a avea control asupra momentului n care bila iese de pe mas
(ajunge ntr-un col) ne folosim de o funcie boolean:

12. Tablouri bidimensionale

265

Subalgoritm Afar:
Afar ((i = 1) sau (i = m)) i ((j = 1) sau (j = n))
sfrit subalgoritm

Rezolvarea problemei const n simularea micrii bilei. Anterior apelului subalgoritmului Micare s-au citit datele de intrare i s-a iniializat tabloul a cu elemente nule.
Subalgoritm Micare(m,n,i,j,a,infinit):
x dx[dir]
y dy[dir]
pas 1
{ contorul pentru marcarea poziiilor strbtute }
a[i,j] pas
se_repet fals
infinit fals
ct timp mingea nu a ieit afar i nu infinit execut:
pas pas + 1
{ crete contorul de poziii }
{ deplasare pe direcia dir, pn la ntlnirea unei margini }
i i + x
j j + y
dac (i = 0) sau (i > m) atunci{ bila s-a lovit de o margine orizontal }
x -x
i i+2*x
sfrit dac
dac (j = 0) sau (j > n) atunci{ bila s-a lovit de o margine vertical }
y -y
j j + 2*y
sfrit dac
{ dac aceast poziie nu a fost strbtut nc }
dac a[i,j]=0 atunci
se repet fals
{ o marcm }
a[i,j] pas
altfel
{ dac aceast poziie a mai fost marcat i este pe o margine }
dac se_repet i (a[i,j] = 2) atunci
infinit adevrat
{ bila a intrat n micare ciclic deoarece }

{ din poziia marcat cu 1 a ajuns n poziia marcat cu 2 }


altfel
dac a[i,j] = 1 atunci
se_repet adevrat
altfel se_repet fals
sfrit dac
sfrit dac
sfrit dac
sfrit ct timp
sfrit subalgoritm

266

12. Tablouri bidimensionale

Afiarea tabloului a, corespunztor mesei de biliard, este precedat de verificarea


variabilei infinit pentru a stabili dac se va scrie mesajul referitor la micarea bilei:
Subalgoritm Afiare:
dac infinit atunci
scrie 'Mingea nu poate iesi de pe masa.'
sfrit dac
pentru i=1,m execut:
pentru j=1,n execut:
scrie a[i,j]
sfrit pentru
sfrit pentru
sfrit subalgoritm

12.6.5. Puncte a
Subproblemele n care descompunem aceast problem sunt:
1. citirea tabloului;
2. determinarea minimului pe o linie a tabloului;
3. determinarea maximului pe o coloan a tabloului;
4. determinarea maximului pe o linie a tabloului;
5. determinarea minimului pe o coloan a tabloului;
6. compararea rezultatelor obinute la punctul 2. i 3;
7. compararea rezultatelor obinute la punctul 4. i 5.
Observm c trebuie s cutm un minim (sau un maxim) ntr-o linie (respectiv ntr-o coloan) din matrice. Aceast observaie ne sugereaz s transformm tabloul
bidimensional, ntr-un ir de linii, folosindu-ne de declaraiile de tip i de variabile:
type linie=array[1..4] of Integer;
TipTab=array[1..3] of linie;
var t:TipTab;
sir:linie;

Astfel linia i din tabloul t se va putea transmite ca parametru de tip linie subprogramelor care determin minimul (respectiv maximul) din linia respectiv. Din pcate
nu putem proceda la fel n cazul coloanelor dect dac le transformm temporar, cu un
subprogram simplu, n ir de tip linie:
Subalgoritm Transform(m,k,t,ir):

{ transform coloana k din tablou n ir de tip linie }


pentru i=1,m execut:
{ coloanele au m elemente }
ir[i] t[i,k]
sfrit pentru
sfrit subalgoritm

12. Tablouri bidimensionale

267

Funciile max(n,ir,poz) i min(n,ir,poz) determin valoarea maxim,


respectiv minim dintr-un ir, returnnd totodat i poziia unde s-a gsit maximul,
respectiv minimul.
n algoritm vom traversa tabloul linie dup linie. Pentru fiecare linie i, vom determina minimul (minim) i poziia lui pe linie (pozmin), apoi vom transforma coloana de
indice pozmin n ir i vom cuta maximul lui (maxim). Dac cele dou valori sunt
egale (minim = maxim), afim indicele liniei (i) i indicele coloanei (pozmax). Procedm la fel, cutnd maximul pe linie i minimul pe coloana pe care am gsit maximul.
Algoritm Puncte_a:

Citirea datelor de intrare (m, n, t)


gsit fals
pentru i=1,m execut:
minim min(n,t[i],pozmin)

{ minimul pe linia i se afl pe coloana pozmin }


{ transformm coloana pozmin n ir }
{ maximul de pe coloana pozmin }

transform(m,pozmin,t,ir)
maxim max(m,ir,pozmax)
dac minim = maxim atunci
scrie i,' ',pozmax
gsit adevrat
sfrit dac
maxim max(n,t[i],pozmax)

{ maximul pe linia i se afl pe coloana pozmax }


{ transformm coloana pozmax n ir }
{ minimul de pe coloana pozmax }

transform(m,pozmax,t,ir)
minim min(m,ir,pozmin)
dac maxim = minim atunci
scrie i,' ',pozmax
gsit adevrat
sfrit dac
sfrit pentru
dac nu gsit atunci
scrie 'Nu exista puncte sa.'
sfrit dac
sfrit algoritm

Variabila gsit primete valoarea adevrat dac am gsit un punct a. A fost nevoie
de reinerea faptului c am reuit s determinm un rezultat pentru a scrie mesajul solicitat n cazul n care nu exist punct a n tablou.

12. Tablouri bidimensionale

268

12.6.6. Rame de suprapus


Algoritmul urmtor traseaz ramele pe rnd cu literele mari ale alfabetului englez,
ncepnd cu litera 'A' i le depune ntr-un tablou bidimensional de caractere. Tabloul
va fi n prealabil iniializat cu caracterul spaiu (' ').
n implementarea propus desenm prima ram n spaiul de depozitare, apoi n
acelai tablou desenm a doua ram. Nu este nevoie de verificri, caracterul c curent
fie suprascrie un caracter spaiu, fie un caracter aparinnd unei rame aezate deja.
Subalgoritm Rame_de_suprapus:
c 'A'
pentru k=1,p execut:
citete y1,x1
{ indicele de linie i de coloan a colului stnga-sus }
citete Ly,Lx
{ lungimile laturilor ramei curente }
{ indicele de linie a colului dreapta-jos }
y2 y1 + Ly 1
x2 x1 + Lx 1
{ indicele de coloan a colului dreapta-jos }
dac (x2 n) i (y2 m) atunci
{ desenm rama }
pentru i=y1,y2 execut:
a[i,x1] c
{ verticala din stnga }
{ verticala din dreapta }
a[i,x2] c
sfrit pentru
pentru j=x1+1,x2-1 execut:
a[y1,j] c
{ orizontala de sus }
{ orizontala de jos }
a[y2,j] c
sfrit pentru
sfrit dac

{ caracterul cu care se va trasa urmtoarea ram }


c succesorul caracterului c
sfrit pentru
sfrit subalgoritm

12.6.7. Rame suprapuse


Problema este descompus n subprobleme, dup cum urmeaz:
Citirea datelor de intrare (dimensiunile spaiului de depozitare i tabloul de
caractere;
Determinarea coordonatelor colurilor ramelor;
Determinarea poziiilor relative a ramelor (suprapunerile);
Afiarea caracterelor cu care s-au desenat ramele, n ordinea n care acestea se pot
ridica.
Notm cu minxi, minyi, maxxi, maxyi coordonatele colului stnga-sus i a celui din
dreapta-jos a celei de a i-a rame. Aceste valori se pot iniializa cu coordonatele spaiului de depozitare, deoarece sigur vom gsi cel puin o ram mai mic dect spaiul.

12. Tablouri bidimensionale

269

Subalgoritm Dimensiuni(m,n,minx,miny,maxx,maxy):
pentru c='A','Z' execut:
minx[c] n
{ iniializarea coordonatelor colurilor }
miny[c] m
maxx[c] 0
maxy[c] 0
sfrit pentru
pentru i=1,m execut:
{ determinarea coordonatelor colurilor }
pentru j=1,n execut:

{ determinm coordonatele colurilor ramei din care face parte poziia curent }
c a[i,j]
dac minx[c] >
minx[c] j
sfrit dac
dac miny[c] >
miny[c] i
sfrit dac
dac maxx[c] <
maxx[c] j
sfrit dac
dac maxy[c] <
maxy[c] i
sfrit dac
sfrit pentru
sfrit pentru
sfrit subalgoritm

j atunci
i atunci
j atunci
i atunci

Pentru a determina poziiile relative ale ramelor, vom construi un tablou de constante logice peste, n care valoarea elementului pestexy va fi adevrat dac rama desenat cu caracterul y este deasupra ramei desenate cu caracterul x. Acest tablou se iniializeaz cu fals pentru toate ramele (toate caracterele cu care este posibil desenarea
unei rame). Vom realiza cutri pentru fiecare caracter posibil ntre limitele dimensiunilor ramei desenate cu caracterul curent. Cutrile trebuie efectuate n ambele direcii
(orizontal i vertical).
Subalgoritm Poziii_Relative(peste,minx,miny,maxy,maxy):
pentru c='A','Z' execut:
pentru ch='A','Z' execut:
peste[c,ch] fals { deocamdat nu am descoperit nici o suprapunere }
sfrit pentru
sfrit pentru
pentru c='A','Z' execut:
{ determinm suprapunerile }
pentru i=miny[c],maxy[c] execut: { rama desenat cu caracterul c }
ch a[i,minx[c]]
{ caracter din desenul ramei desenate cu c }

12. Tablouri bidimensionale

270
dac ch c atunci

{ dac ntlnim ch n desenul ramei desenate cu c }


{ rama desenat cu ch este deasupra ramei desenate cu c }
peste[c,ch] adevrat

sfrit dac
ch a[i,maxx[c]]
dac ch c atunci
peste[c,ch] adevrat
sfrit dac
sfrit pentru
pentru j=minx[c]+1,maxx[c]-1 execut:
ch a[miny[c],j]
dac ch c atunci
peste[c,ch] adevrat
sfrit dac
ch a[maxy[c],j]
dac ch c atunci
peste[c,ch] adevrat
sfrit dac
sfrit pentru
sfrit pentru
sfrit subalgoritm

Afiarea n aceast problem necesit cteva verificri n plus. De asemenea, va


trebui s inem evidena ramelor afiate deja (n irul de afiat, avnd valori booleene),
pentru a evita afiarea lor repetat. Acest ir se iniializeaz cu fals. Dac o ram nu
are nici una deasupra ei, poate fi ridicat i, deci, afiat. Vom continua afirile ct
timp mai exist ram neafiat. Dup afiarea ramei desenate cu caracterul y, ridicarea
ei va nsemna modificarea valorii lui pestexy, care va deveni fals.
Subalgoritm Afiare(peste,minx,miny,maxx,maxy):
pentru c='A','Z' execut:
{ dac maxx > 0, nseamn c exist ram desenat cu c }
dac maxx[c] > 0 atunci
{ deci trebuie afiat }
deafiat[c] adevrat
altfel
deafiat[c] false
sfrit dac
sfrit pentru
avemdeafiat adevrat
ct timp avemdeafiat execut: { ct timp avem rame de afiat, le afim }
avemdeafiat fals

12. Tablouri bidimensionale

271

pentru c:='A','Z' execut:


dac deafiat[c] atunci
ok adevrat
ch 'A'
ct timp ok i (ch 'Z') execut:

{ verificm dac rama desenat cu c poate fi ridicat }


dac peste[c,ch] atunci
ok fals
sfrit dac
ch succesorul lui ch
sfrit ct timp
dac ok atunci
scrie c
pentru ch='A','Z' execut:
peste[ch,c] fals
sfrit dac
deafiat[c] fals
avemdeafiat adevrat
sfrit dac
sfrit dac
sfrit pentru
sfrit ct timp
sfrit subalgoritm

{ dac da, o afim i o ridicm }

{ nu mai trebuie afiat }

12.6.8. Prelucrare imagine


ntruct cerinele acestei probleme sunt formulate pe subpuncte separate, se descriu n
continuare algoritmi separai pentru fiecare transformare n parte. Am notat cu a tabloul bidimensional ptratic coninnd imaginea, iar cu m dimensiunea acestuia.
A. Inversarea valorilor 0 cu valori 1 i viceversa
n mod normal, inversarea valorilor se face parcurgnd tabloul, iar dac elementul are
valoarea 0 aceasta se schimb n 1 i invers:
dac a[i,j] = 1 atunci a[i,j] 0
altfel a[i,j] 1

Aceast schimbare de valoare se poate exprima sintetic aplicnd operatorii pe bii


astfel: a[i,j] a[i,j] xor 1. Exprimrile sunt echivalente deoarece:
0 xor 1 = 1 i 1 xor 1 = 0.
n aceste condiii, pseudocodul algoritmului de inversare este urmtorul:

12. Tablouri bidimensionale

272
Subalgoritm Invers(m,a)
pentru i=1,m execut:
pentru j=1,m execut:
a[i,j] a[i,j] xor 1
sfrit pentru
sfrit pentru
sfrit subalgoritm

B. Rotirea tabloului cu 900 n sensul acelor de ceasornic


Pentru a roti toate elementele tabloului trebuie s lum pe rnd fiecare element i s-l
aezm ntr-un alt tablou bidimensional pe poziia potrivit. Dezavantajul acestei
variante de algoritm este consumul excesiv de spaiu de memorie. Se prezint n
continuare o variant mai economicoas care se bazeaz pe rotirea succesiv a celor
patru puncte.
Dac pentru un element se aranjeaz patru
aij
4
elemente la locul lor (folosind o variabil auxiliar), nseamn c trebuie repetat aceast operaie
doar pentru o ptrime din elementele tablou1
lui. Se parcurge, de exemplu, numai triunghiul
3
superior dintre diagonale, inclusiv diagonala
principal. Elementul aij se salveaz n variabila
2
auxiliar dup care se efectueaz cele trei atribuiri evideniate pe figur.
Exemple

m = 4: a11
a21
a31
a41

a12
a22
a32
a42

a13
a23
a33
a43

a14 m = 5:
a24
a34
a44

a11
a21
a31
a41
a51

a12
a22
a32
a42
a52

a13
a23
a33
a43
a53

a14
a24
a34
a44
a54

a15
a25
a35
a45
a55

m = 4: a21 se va nlocui cu a42 care se va nlocui cu a34 care se va nlocui cu a13.


m = 5: a21 se va nlocui cu a52 care se va nlocui cu a45 care se va nlocui cu a14.

n concluzie, indicele de linie devine indice de coloan, iar indicele de coloan ne


ajut la calcularea noului indice de linie: m fostul indice coloan + 1.
n ceea ce privete parcurgerea triunghiului dintre diagonalele tabloului (fr elementele de pe diagonala secundar): indicele de linie variaz ntre prima linie i linia
de mijloc (sau deasupra mijlocului atunci cnd dimensiunea tabloului este par), iar
indicele de coloan pornete de la elementul de pe diagonala principal i i crete pn
la m i.

12. Tablouri bidimensionale


m = 4: a11
a21
a31
a41

a12
a22
a32
a42

273

a13
a23
a33
a43

a14 m = 5:
a24
a34
a44

a11
a21
a31
a41
a51

a12
a22
a32
a42
a52

a13
a23
a33
a43
a53

a14
a24
a34
a44
a54

a15
a25
a35
a45
a55

Prezentm n continuare pseudocodul corespunztor algoritmului descris.


Subalgoritm Rotete(m,a):
pentru i=1,[m/2] + rest[m/2] execut:
pentru j=i,M-i execut:
{ pentru o ptrime din elementele tabloului }
i1 i
j1 j
aux a[i,j]
{ se pstreaz elementul de pornire }
pentru k=1,3 execut:
{ se iniializeaz indicii de unde se ia valoarea }
i2 m - j1 + 1
j2 i1
a[i1,j1] a[i2,j2]
{ mutare }
i1 i2
{ se iniializeaz indicii unde se va pune valoarea }
{ la urmtoarea iteraie }
j1 j2
sfrit pentru
a[i2,j2] aux
sfrit pentru
sfrit pentru
sfrit subalgoritm

C. Dublarea imaginii (Zoom)


Pentru a extinde tabloul pe un tablou de dou ori mai mare se vor construi n noul
tablou cte patru elemente cu acea valoare, aezate n forma unei matrice ptratice de
dimensiune 2.
De exemplu, un element avnd valoarea 1 n matricea iniial se nlocuiete cu:
1 1
0 1

Ne propunem n continuare s determinm modalitatea n care se obin indicii elementelor matricei mrite din matricea iniial.
indici de linie:
indici de 1
coloan: 2

1
1
0

2
0
1

indici de linie:
indici de 1
coloan: 2
3
4

1
1
1
0
0

2
1
1
0
0

3
0
0
1
1

4
0
0
1
1

Elementului a11 i corespund elementele a11, a12, a21, a22. Elementului a12 i corespund elementele a13, a14, a23, a24. Generaliznd cele observate, elementului aij i corespund elementele a2i 1, 2j 1, a2i 1, 2j, a2i, 2j 1, a2i, 2j.

274

12. Tablouri bidimensionale

Subalgoritm Zoom(m,a):
pentru i=1,m execut:
pentru j=1,m execut:
b[2*i-1,2*j-1] a[i,j]
{ b tablou auxiliar }
b[2*i-1,2*j] a[i,j]
b[2*i,2*j-1] a[i,j]
b[2*i,2*j] [i,j]
sfrit pentru
sfrit pentru
m 2*m
a b
{ atribuire la nivel de tablou, suprascriem vechiul a cu b }
sfrit subalgoritm

n algoritmul care va apela subalgoritmii prezentai am notat cu transformare caracterul care conine codul transformrii curente.
Algoritm Prelucrare:
...
{ se citesc dimensiunea i elementele tabloului dat }
ct timp nu s-a ajuns la sfritul fiierului execut:
citete transformare
dac transformare = 'I' atunci
Invers(m,a)
altfel
dac transformare = 'R' atunci
Rotete(m,a)
altfel
dac transformare = 'Z' atunci
Zoom(m,a)
sfrit dac
sfrit dac
sfrit dac
sfrit ct timp
...
{ se afieaz tabloul bidimensional obinut }
sfrit algoritm

12.6.9. Careu Magic


Algoritmul de rezolvare a acestei probleme ncepe prin a testa dimensiunea careului de
generat. n funcie de proprietatea pe care acest numr o are: impar, par multiplu de 4
sau par fr a fi multiplu de 4, aplicm algoritmul prezentat la teorie.
S urmrim descrierea implementrilor pentru fiecare dintre cei trei algoritmi.
a. Drumul mpratului Ven sau generarea ptratelor magice de ordin impar
Descriem n continuare o variant de generare a unui ptrat magic de ordin impar care
respect drumul mpratului Ven. Careul magic l generm n tabloul a. Algoritmul

12. Tablouri bidimensionale

275

atribuie pe rnd valorile cuprinse n intervalul [1, n2] variabilei nr, urmnd ca aceast
valoare s se atribuie elementelor careului pe baza regulilor precizate.
Subalgoritm Ven:
y n
x [(n+1)/2]
nr 1
pentru i=1,n execut:
a[y,x] nr
pentru j=1,n-1 execut:
dac x = 1 atunci
x n
altfel
x x 1
sfrit dac
dac y = 1 atunci
y n
altfel
y y 1
sfrit dac
nr nr + 1
a[y,x] nr
sfrit pentru
dac y = n atunci
y 1
altfel
y y + 1
sfrit dac
nr nr + 1
sfrit pentru
sfrit subalgoritm

b. Careul magic de dimensiune par (n = 4 m)


Pentru a genera careul magic de dimensiune par, pornim de la matricea de ordin n
format cu numerele 1, 2, , n2 aezate n ordine pe linii.
Din descrierea algoritmului se desprinde c elementele aflate pe linii avnd numr
de ordine pentru care restul mpririi la 4 este 0 sau 1 i coloane care nu au aceast
proprietate sau pe coloane avnd numr de ordine pentru care restul mpririi la 4 este
0 sau 1 i linii care nu au aceast proprietate trebuie schimbate cu elementele aflate n
poziii simetrice fa de mijlocul careului. Aceast proprietate privind poziia elementului o vom exprima folosind operatorul logic xor. Schimbarea cu elementul simetric
se asigur folosind valoarea variabilei nn.

276

12. Tablouri bidimensionale

Subalgoritm Magic4M:
nr 1
nn n*n + 1
pentru i=1,n execut:
pentru j=1,n execut:
dac (rest[i/4] 1) xor (rest[j/4] 1) atunci
a[i,j] nn - nr
altfel
a[i,j] nr
sfrit dac
nr nr + 1
sfrit pentru
sfrit pentru
sfrit subalgoritm

c. Ptrat magic de ordin n, unde n = 2 m i m este numr impar


S urmrim paii algoritmului de generare a unui ptrat magic de ordin n, unde n = 2 m
i m este numr impar. Trebuie s mprim careul n careuri mici de dimensiune 2 2,
asupra crora decidem n ce form se vor completa. Aceast form se stabilete n
subalgoritmul Forma(x,y,nr), apelat de subalgoritmul urmtor:
Subalgoritm CareuMagic2M:
n [n/2]
y 1
x [(n+1)/2]
nr 1
pentru i=1,n execut:
Forma(x,y,nr)
pentru j=1,n-1 execut:
dac x = 1 atunci
x n
altfel
x x - 1
sfrit dac
dac y = 1 atunci
y n
altfel
y y - 1
sfrit dac
Forma(x,y,nr)
sfrit pentru
dac y = n atunci
y 1

12. Tablouri bidimensionale

277

altfel
y y + 1
sfrit dac
sfrit pentru
n n*2
sfrit subalgoritm
Subalgoritm Forma(x,y,nr):
dac y > [n/2] + 2 atunci
FormaX(x,y,nr)
altfel
dac y = [n/2] + 2 atunci
dac x = [(n+1)/2] atunci
FormaL(x,y,nr)
altfel
FormaU(x,y,nr)
sfrit dac
altfel
dac y = [n/2] + 1 atunci
dac x = [n/2] + 1 atunci
FormaU(x,y,nr)
altfel
FormaL(x,y,nr)
sfrit dac
altfel
FormaL(x,y,nr)
sfrit dac
sfrit dac
sfrit dac
nr nr + 4
sfrit subalgoritm
Subalgoritm FormaL(x,y,nr):
a[2*y-1,2*x-1] nr + 2
a[2*y-1,2*x ] nr + 1
a[2*y ,2*x-1] nr
a[2*y ,2*x ] nr + 3
sfrit subalgoritm
Subalgoritm FormaU(x,y,nr):
a[2*y-1,2*x-1] nr + 2
a[2*y-1,2*x ] nr + 1
a[2*y ,2*x-1] nr + 3
a[2*y ,2*x ] nr
sfrit subalgoritm

{ XXXXX }
{ UULUU }

{ LLULL }

{ LLLLL }

278
Subalgoritm FormaX(x,y,nr):
a[2*y-1,2*x-1] nr + 1
a[2*y-1,2*x ] nr + 2
a[2*y ,2*x-1] nr + 3
a[2*y ,2*x ] nr
sfrit subalgoritm

12. Tablouri bidimensionale

S-ar putea să vă placă și