Documente Academic
Documente Profesional
Documente Cultură
0912 Tablouri Bidimensionale
0912 Tablouri Bidimensionale
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
...
...
240
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
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).
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
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
242
n mod similar, irul de elemente a1,n, a2,n-1, ..., an,1 formeaz diagonala secundar
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.
243
244
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.
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.
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.
246
Exemplu
n = 5,
paii 1, 2, 3, 4:
12
12
12
10
1
15
16 14
13
17
3
20
12 10
11
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
247
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
249
250
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.
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.
22 11 23 ...
21
10
10
20
11
18
12
17 8
16 5
15 7
14 13 6
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
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.
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.'.
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
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.
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
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;
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
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
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.
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
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
261
262
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.
263
sfrit ct timp
altfel n este numr impar atunci
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.
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 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:
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 }
266
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):
267
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)
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.
268
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 }
270
dac ch c atunci
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
271
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
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
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
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
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
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
276
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
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