Sunteți pe pagina 1din 9

LABORATOR 3

ALGORITMUL LUI LEE

Exemplu: Problema Șoarecele și Cașcavalul

Se dă un labirint sub forma unei matrice cu m linii și n coloane, unde


dacă o celulă este 0, aceasta se consideră accesibilă de către șoarece,
iar dacă este – 1, atunci e inaccesibilă. De asemenea, se dau
coordonatele pozițiilor în care se află inițial șoarecele și bucata de
brânză. La fiecare pas, șoarecele se poate deplasa într-una dintre
pozițiile imediat vecine la nord, sud, est sau vest, cu condiția ca aceasta
să fie accesibilă și, desigur, să se afle în interiorul matricei.

Important

• Să se determine lungimea minimă a


unui drum de la șoarece la brânză,
precum și un astfel drum.

• Dacă nu se poate ajunge la brânză


(este înconjurată de obstacole), se
va afișa 0.

Această problemă a fost explicată la lecția de teorie, prin urmare acum


vom prezenta două modalități de implementare a algoritmului lui Lee:

A. Sursa clasică

#include <fstream>
using namespace std;
const int DMAX = 500;
ifstream fin("lee.in");
ofstream fout("lee.out");
// Vectorii de deplasare
const int addLin[] = {-1, 0, 1, 0};
const int addCol[] = {0, 1, 0, -1};

1 din 9 Profesor A.D.


struct Pos {
int lin, col;
};
Pos a, b;
int m, n;
int mat[DMAX][DMAX];
int in, sf;
Pos q[DMAX * DMAX];
int vf;
Pos st[DMAX * DMAX];
// Subprogramul de citire a datelor din fișier
void citeste() {
fin >> m >> n;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
fin >> mat[i][j];
fin >> a.lin >> a.col;
fin >> b.lin >> b.col;
}
// Subprogramul de a înconjura obstacolele
void inconjoara() {
for (int i = 0; i <= m + 1; i++)
mat[i][0] = mat[i][n + 1] = -1;
for (int j = 1; j <= n; j++)
mat[0][j] = mat[m + 1][j] = -1;
}
void lee() {
q[0] = a; in = sf = 0;
mat[a.lin][a.col] = 1;
Pos pos;
while (in <= sf && !mat[b.lin][b.col]) {
pos = q[in++];
for (int k = 0; k < 4; k++) {
Pos ngh;
ngh.lin = pos.lin + addLin[k];
ngh.col = pos.col + addCol[k];
if (!mat[ngh.lin][ngh.col]) {
mat[ngh.lin][ngh.col] = mat[pos.lin][pos.col] + 1;
q[++sf] = ngh;
}
}
}
}
// Subprogramul de afișare a datelor în fișier
void afiseaza() {
Pos pos = st[++vf] = b;
while (mat[pos.lin][pos.col] > 1)

2 din 9 Profesor A.D.


for (int k = 0; k < 4; k++) {
Pos ngh;
ngh.lin = pos.lin + addLin[k];
ngh.col = pos.col + addCol[k];
if (mat[ngh.lin][ngh.col] == mat[pos.lin][pos.col] - 1)
{
st[++vf] = pos = ngh; break;
}
}
fout << mat[b.lin][b.col] << '\n';
while (vf) {
fout << st[vf].lin << ' ' << st[vf].col << '\n';
vf--;
}
}
// Programul principal
int main() {
citeste();
inconjoara();
lee();
afiseaza();
fout.close();
return 0;
}

Soluția obținută în urma execuției codului C++ este:

3 din 9 Profesor A.D.


B. Sursa cu STL pentru coadă și construcția drumului recursiv

#include <bits/stdc++.h>
using namespace std;
const int DMAX = 500;
ifstream fin("lee.in");
ofstream fout("lee.out");
// Vectorii de deplasare
const int addLin[] = {-1, 0, 1, 0};
const int addCol[] = {0, 1, 0, -1};
struct Pos {
int lin, col;
};
int m, n, mat[DMAX][DMAX];
Pos a, b;
queue<Pos> q;
// Subprogramul de citire a datelor din fișier
void citeste() {
fin >> m >> n;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
fin >> mat[i][j];
fin >> a.lin >> a.col; fin >> b.lin >> b.col;
}
// Subprogramul de a înconjura obstacolele
void inconjoara() {
for (int i = 0; i <= m + 1; i++)
mat[i][0] = mat[i][n + 1] = -1;
for (int j = 1; j <= n; j++)
mat[0][j] = mat[m + 1][j] = -1;
}
void lee() {
q.push(a);
mat[a.lin][a.col] = 1;
while (!q.empty() && !mat[b.lin][b.col]) {
Pos pos = q.front();
q.pop();
for (int k = 0; k < 4; k++) {
Pos ngh;
ngh.lin = pos.lin + addLin[k];
ngh.col = pos.col + addCol[k];
if (!mat[ngh.lin][ngh.col]) {
mat[ngh.lin][ngh.col] = mat[pos.lin][pos.col] + 1;
q.push(ngh);
}
}
}

4 din 9 Profesor A.D.


}
// Subprogramul de afișare a datelor în fișier
void afiseaza(Pos pos) {
if (pos.lin == a.lin && pos.col == a.col) {
fout << a.lin << ' ' << a.col << '\n';
return;
}
for (int k = 0; k < 4; k++) {
Pos ngh;
ngh.lin = pos.lin + addLin[k];
ngh.col = pos.col + addCol[k];
if (mat[ngh.lin][ngh.col] == mat[pos.lin][pos.col] - 1) {
afiseaza(ngh);
fout << pos.lin << ' ' << pos.col << '\n';
return;
}
}
}
// Programul principal
int main() {
citeste(); inconjoara(); lee();
fout << mat[b.lin][b.col] << '\n'; afiseaza(b);
fout.close(); return 0;
}

Soluția obținută în urma execuției codului C++ este:

5 din 9 Profesor A.D.


SARCINA PENTRU LECȚIA DE LABORATOR

Subgrupa 1

1) Zorel, fericit că a trecut examenul la „Programarea structurată”,


pleacă în oraș să sărbătorească. Este atât de fericit, încât nu se
mulțumește cu un simplu traseu între terase, ci vrea un ciclu pentru a fi
sigur că poate continua să petreacă cât timp dorește. Din păcate,
drumurile dintre terase au costuri diferite și nu sunt bidirecționale. Zorel
nu este interesat neapărat să minimizeze costul acestui ciclu, ci dorește să
minimizeze costul mediu al ciclului (evident, vrea să meargă cât mai puțin
între terase, adică costul ciclului âmparțit la numărul de terase să fie
minim). Ajutați-l și de această dată pe Zorel și vă va cinsti toată ziua.
2) În ultima ecranizare a celebrei piese shakespeariene Romeo şi Julieta
trăiesc într-un oraş modern, comunică prin e-mail şi chiar învaţă să
programeze. Într-o secvenţă tulburătoare sunt prezentate frământările
interioare ale celor doi eroi încercând fără succes să scrie un program
care să determine un punct optim de întâlnire. Ei au analizat harta
oraşului şi au reprezentat-o sub forma unei matrice cu n linii şi m
coloane, în matrice fiind marcate cu spaţiu zonele prin care se poate trece
(străzi lipsite de pericole) şi cu X zonele prin care nu se poate trece. De
asemenea, în matrice au marcat cu R locul în care se află locuinţa lui
Romeo, iar cu J locul în care se află locuinţa Julietei. Ei se pot deplasa
numai prin zonele care sunt marcate cu spaţiu, din poziţia curentă în
oricare dintre cele 8 poziţii învecinate (pe orizontală, verticală sau
diagonale). Cum lui Romeo nu îi place să aştepte şi nici să se lase aşteptat
n-ar fi tocmai bine, ei au hotărât că trebuie să aleagă un punct de
întâlnire în care atât Romeo, cât şi Julieta să poată ajunge în acelaşi timp,
plecând de acasă. Fiindcă la întâlniri amândoi vin într-un suflet, ei
estimează timpul necesar pentru a ajunge la întâlnire prin numărul de
elemente din matrice care constituie drumul cel mai scurt de acasă până
la punctul de întâlnire. Şi cum probabil există mai multe puncte de
întâlnire posibile, ei vor să îl aleagă pe cel în care timpul necesar pentru a
ajunge la punctul de întâlnire este minim. Scrieţi un program care să
determine o poziţie pe hartă la care Romeo şi Julieta pot să ajungă în
acelaşi timp. Dacă există mai multe soluţii, programul trebuie să
determine o soluţie pentru care timpul este minim.

6 din 9 Profesor A.D.


Subgrupa 2

1) Ana si Ion au o pasiune comuna pentru sah si joaca ori de câte ori au
timp liber. Fiind persoane non-conformiste, si-au comandat table de sah
de diferite dimensiuni, si seturi de piese speciale. Daca nu au timp sa
termine o partida, pastreaza pe tabla de sah piesele asa cum sunt si
continua a doua zi. De data aceasta, a aparut o problema - Ionel, fiul lor,
a rasturnat din greseala tabla de sah - si ei încearca sa reconstituie acum
ultima configuratie. Ion îsi aminteste cu precizie cu arata ieri la începutul
jocului configuratia tablei de sah, precum si mutarile pe care el le-a facut.
Ana îsi aminteste ca a jucat ciudat - tot jocul a mutat aceeasi piesa, o
tura. Nu îsi aminteste exact pozitiile în care a mutat, dar îsi aminteste
directiile în care s-a deplasat tura. Scrieti un program care sa determine
pozitiile în care s-ar putea afla la final tura mutata de Ana.
2) Eternul si fascinantul teren de lupta dintre cei doi protagonisti celebri,
pisica si soarecele, este din nou in atentia soricelului. Acesta studiaza
harta curtii pentru a gasi o modalitate de deplasare prin curte cat mai
lipsita de pericole. Harta este un dreptunghi de dimensiuni intregi m x n,
impartit in celule patrate de latura 1; o celula este precizata printr-o
pereche de numere intregi - numarul liniei si numarul coloanei in care se
gaseste (liniile si coloanele sunt numerotate incepand de la 1). Pe harta
sunt insemnate celulele in care pisica obisnuieste sa stea la panda.
Gradul de periculozitate al unei celule este in functie de distanta pana la
cel mai apropiat punct de panda al pisicii, mai exact este lungimea curtii
+ latimea curtii - distanta pana la cel mai apropiat punct de panda.
Gradul de periculozitate al unui drum este dat de suma gradelor de
periculozitate ale celulelor traversate. Atat soricelul cat si pisica se pot
deplasa de la o celula la una invecinata pe orizontala sau verticala, iar
distanta dintre doua celule este data de numarul minim de celule
traversate intr-o deplasare de la o celula la cealalta minus 1. De exemplu
distanta dintre celulele (1,1) si (2,2) este 2. Scrieti un program care
determina un drum de la celula (1,1) - coltul stanga-sus, la celula (m,n) -
coltul dreapta-jos cu gradul de periculozitate minim.

7 din 9 Profesor A.D.


SARCINA PENTRU TEMA PENTRU ACASĂ

Problema Panda
O rezervaţie de urşi panda, privită de sus,
are formă dreptunghiulară şi este
compusă din n rânduri identice, iar pe
fiecare rând sunt m ţarcuri identice cu
baza pătrată. Ţarcurile sunt îngrădite şi
sunt prevăzute cu uşi către toate cele 4
ţarcuri vecine. Uşile sunt prevăzute cu
câte un cod de acces, ca atare acestea se
închid şi se deschid automat.
Prin acest sistem, unele ţarcuri sunt accesibile ursuleţilor, iar altele
le sunt interzise acestora. În T ţarcuri se găseşte mâncare pentru ursuleţi.
Ursuleţii din rezervaţie poartă câte un microcip care le deschide automat
uşile ţarcurilor unde pot intra şi închide automat uşile ţarcurilor interzise.
Un ţarc este accesibil ursuleţului dacă ultimele S cifre ale reprezentărilor
binare ale codului ţarcului şi ale codului K de pe microcip sunt
complementare.

Exemplu:
pentru S=8, 11101011 şi 00010100 sunt complementare.

Într-un ţarc este un ursuleţ căruia i s-a făcut foame. Ursuleţul se


deplasează doar paralel cu laturile dreptunghiului. Trecerea dintr-un ţarc
în altul vecin cu el se face într-o secundă.
Cunoscând n şi m dimensiunile rezervaţiei, codurile de acces de la
fiecare dintre cele n*m ţarcuri, coordonatele celor T ţarcuri cu mâncare,
coordonatele ţarcului L şi C unde se află iniţial ursuleţul, codul K al
microcipului său şi numărul S, determinaţi:
a) Numărul X de ţarcuri care îndeplinesc proprietatea că ultimele S
cifre din reprezentarea binară a codului lor sunt complementare cu
ultimele S cifre din reprezentarea binară a codului K purtat de
ursuleţ, cu excepţia ţarcului în care se află acesta iniţial.
b) Numărul minim de secunde Smin în care poate ajunge la un ţarc cu
mâncare precum şi numărul de ţarcuri cu mâncare nt la care poate
ajunge în acest timp minim.

8 din 9 Profesor A.D.


***SARCINI SUPLIMENTARE***

Problema Lanterna
Un agent secret are o harta pe care sunt marcate N obiective
militare. El se afla, initial, langa obiectivul numerotat cu 1 (baza
militara proprie) si trebuie sa ajunga la obiectivul numerotat cu N (baza
militara inamica). Pentru aceasta, el va folosi drumurile existente,
fiecare drum legand 2 obiective distincte.
Fiind o misiune secreta, deplasarea
agentului va avea loc noaptea; de aceea, el
are nevoie de o lanterna. Pentru aceasta, el
are de ales intre K tipuri de lanterne - o
lanterna de tipul W (1 ≤ W ≤ K) are baterii
care permit consumul a W watti; dupa
consumul acestor watti, lanterna nu mai
lumineaza. Din fericire, unele dintre obiective
sunt baze militare prietene, astfel ca, o data
ajuns acolo, el isi poate reincarca complet
bateriile. Agentul trebuie sa aiba grija ca,
inainte de merge pe un drum intre doua
obiective, cantitatea de watti pe care o mai
poate consuma sa fie mai mare sau egala cu
cantitatea de watti pe care o va consuma pe drumul respectiv.
Cunoscand drumurile dintre obiective si, pentru fiecare drum,
durata necesara parcurgerii drumului si numarul de watti consumati de
lanterna, determinati tipul de lanterna cu numarul cel mai mic, astfel
incat durata deplasarii sa fie minima (sa presupunem ca acest tip este
W; aceasta inseamna ca daca ar alege o lanterna de un tip mai mic
decat W, durata deplasarii ar fi strict mai mare, iar daca ar alege o
lanterna de un tip mai mare decat W, durata deplasarii ar fi mai mare
sau egala).

9 din 9 Profesor A.D.

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