Sie sind auf Seite 1von 8

Algoritmi si structuri de date (10-11.12.

2014) Informatica&Matematic, anul 1

ASD21AlgMatrLab

Algoritmi cu matrice (continuare)


R1.
Enunul problemei: S se descrie un algoritm pentru a determina cte linii au cel puin un
element negativ ntr-o matrice dat?
Metoda de rezolvare: Se parcurge fiecare linie a matricei i n cazul n care exist un element
negativ se contorizeaz linia. De exemplu, pentru matricea:
2
3
4
5
6
1

2 1 2 0
1
1
A = 1 0
1
2
3
4

2
3
4 1 5
1

1 2 3 4 5 6
sunt 4 linii (liniile 2, 3, 4, 5) care au cel puin un element negativ.
Descrierea algoritmului n pseudocod:
citete m,n,a11,,amn
contor 0
pentru i = 1,m repeta
pentru j = 1,n repeta
daca aij < 0 atunci
contor contor + 1
break
scrie contor

*initializarea contorului de linii


*pentru fiecare linie i
*parcurgem linia
*elementul curent este negativ
*contorizam linia curenta
*se trece la urmatoarea linie

Descrierea algoritmului n C++ (CodeBlocks):


#include <iostream>
using namespace std;
int main() {
int m,n,i,j,contor;
float a[10][10];
//citim dimensiunile si elementele matricei
cout<<"Dati numarul de linii: "; cin>>m;
cout<<"Dati numarul de coloane: "; cin>>n;
cout<<"Dati elementele matricei: "<<endl;
for (i=0;i<m;i++)
for (j=0;j<n;j++) cin>>a[i][j];
contor = 0;
//se initializeaza contorul liniilor
for (i=0;i<m;i++)
//pentru fiecare linie i
for (j=0;j<n;j++) //se parcurge linia
if (a[i][j]<0) { //daca elementul curent este negativ
contor++;
//se contorizeaza linia curenta
break;
//iesire din "for j" => se trece la urm. linie
}
cout<<"Nr.liniilor cu cel putin un nr negativ: "<<contor<<endl;
return 0;
}

Rulare:
Dati numarul de linii: 3 <Enter>
Dati numarul de coloane: 4 <Enter>
Dati elementele matricei:
1
2 3 4 <Enter>
1 -1 2 2 <Enter>
-1 -1 1 -1<Enter>
Numarul liniilor cu cel putin un nr negativ: 2

Algoritmi si structuri de date (10-11.12.2014) Informatica&Matematic, anul 1

ASD21AlgMatrLab

R2.
Enunul problemei: S se descrie un algoritm pentru a afia indicele liniilor ce conin cel puin
k elemente negative. n cazul n care nu exist astfel de linii se va afia un mesaj.
Metoda de rezolvare: De exemplu, pentru matricea
2
3
4
1

0 1 2 2
A = 1 2 3 0

3
0 1 2

1 2 3 4
i k=2 sunt 3 linii cu cel puin k elemente negative. O variant simpl a algorimului ar fi s se
parcurg liniile matricei i s se contorizeze elementele negative, iar n cazul n care acest
numr depete valoarea k s se afieze indicele liniei respective. Pentru a verifica dac nu
exist astfel de linii, se poate lua o variabila boolean care-i schimb valoarea n cazul n
care s-a afiat indicele unei linii corespunztoare. La final, dup parcurgerea tuturor liniilor,
dac aceast variabil nu i-a schimbat valoarea iniial, atunci se va afia un mesaj.
O descriere a algoritmului n pseudocod:
citete m,n,a11,,amn,k
exist fals
*presupunem ca nu exista linii corespunzatoare
pentru i = 1,m repeta
*pentru fiecare linie
contor_neg 0
*initializare contor pentru linia i
pentru j = 1,n repeta
*parcurgem linia
daca aij < 0 atunci
*elementul curent este negativ
contor_neg contor_neg + 1*contorizam elem. neg. curent
daca contor_neg >= k atunci
*sunt cel putin k elem. neg.
exista adevarat
*schimbam valoarea var. exista
scrie i
*afisam indicele liniei
daca exista = fals atunci
scrie "Nu exista linii cu cel putin k elem. negative"

O descriere a algoritmului n C++ (CodeBlocks):


#include <iostream>
using namespace std;
int main() {
int m,n,i,j,k,exista,contor_neg;
float a[10][10];
cout<<"Dati numarul de linii: "; cin>>m;
cout<<"Dati numarul de coloane: "; cin>>n;
cout<<"Dati elementele matricei: "<<endl;
for (i=0;i<m;i++)
for (j=0;j<n;j++) cin>>a[i][j];
cout<<"k = "; cin>>k;
cout<<"Liniile care au cel putin k elem. neg.: ";
exista = 0;
//presupunem ca nu exista linii corespunzatoare
for (i=0;i<m;i++) { //pentru fiecare linie i
contor_neg = 0;
//initializam numarul elem. negative
for (j=0;j<n;j++) //se parcurge linia
if (a[i][j]<0)contor_neg++; //contorizam elementele neg.
if (contor_neg >= k){//avem cel putin k elem. neg. pe lin. i
exista = 1;
//exista linii corespunzatoare
cout<<i+1<<" ";
//afisam indicele liniei
}
}
if (exista==0) cout<<"nu exista"<<endl;
return 0; }

Algoritmi si structuri de date (10-11.12.2014) Informatica&Matematic, anul 1

ASD21AlgMatrLab

O optimizare a acestui algoritm poate fi aceea n care parcurgerea liniei se continu doar dac
nu s-au gsit deja k elemente negative, iar linia este corespunztoare dac numrul de
elemente negative este egal cu k:
exista = 0;
//presupunem ca nu exista linii corespunzatoare
for (i=0;i<m;i++) { //pentru fiecare linie i
contor_neg = 0;
//initializam numarul elem. negative
for (j=0; j<n && contor_neg<k; j++)
//se parcurge linia
if (a[i][j]<0) contor_neg++; //contorizam elementele neg.
if (contor_neg == k) {
//avem k elem. neg. pe lin. i
{ exista = 1; cout<<i+1<<" "; }
}

Rulare:
Dati numarul de linii: 5 <Enter>
Dati numarul de coloane: 4 <Enter>
Dati elementele matricei:
1 2 3 4 <Enter>
0 -1 2 -2 <Enter>
-1 2 3 0 <Enter>
0 1 2 3 <Enter>
-1 1 1 1 <Enter>
k = 2 <Enter>
Liniile care au cel putin k elem. neg.: 2, 3, 5

sau
Dati numarul de linii: 3 <Enter>
Dati numarul de coloane: 3 <Enter>
Dati elementele matricei:
1 2 3 <Enter>
0 -1 2 <Enter>
-1 2 2 <Enter>
k = 2 <Enter>
Liniile care au cel putin k elem. neg.: nu exista

R3.
Enunul problemei: S se descrie un algoritm pentru a determina cte linii au toate elementele
egale ntr-o matrice dreptunghiular.
1
2
1

0
0
0
Metoda de rezolvare: De exemplu, pentru A =
, sunt 2 linii cu elemente egale.
1 1 1

1 1 1

n general, pentru o matrice A Mmn, algoritmul const n parcurgerea liniilor i determinarea


faptului c linia respectiv are sau nu elementele egale (adic aij = ai, j+1, pentru j = 1,2,...,n-1).
O descriere a algoritmului n pseudocod:
citete m,n,a11,,amn
contor 0
*initializare contor linii
pentru i = 1,m repeta
*pentru fiecare linie i
OK adevarat
*presupunem ca linia are elem.egale
pentru j = 1,n-1 repeta *parcurgem linia
daca aij ai,j+1 atunci *elem.curent este diferit de urmatorul
OK fals
*schimbam valoarea variabilei
break
*ieim de pe linia curenta
daca OK = adevarat atunci*sunt cel putin k elem. neg.
contor contor + 1
*contorizam linia curenta
scrie contor

Algoritmi si structuri de date (10-11.12.2014) Informatica&Matematic, anul 1

ASD21AlgMatrLab

O descriere a algoritmului n C++ (CodeBlocks):


#include <iostream>
using namespace std;
int main() {
int m,n,i,j,contor,OK;
float a[10][10];
//citim dimensiunile si elementele matricei
cout<<"Dati numarul de linii: "; cin>>m;
cout<<"Dati numarul de coloane: "; cin>>n;
cout<<"Dati elementele matricei: "<<endl;
for (i=0;i<m;i++)
for (j=0;j<n;j++) cin>>a[i][j];
contor = 0; //initializarea nr. de linii cu elementele egale
for (i=0;i<m;i++) {
//pentru fiecare linie i
OK = 1; //presupunem ca elem. liniei i sunt egale
for (j=0;j<=n-2;j++)
//parcurgem linia i
if (a[i][j] != a[i][j+1]) {//doua elemente vecine diferite
OK = 0;
//linia curenta nu are elem. egale
break;
//se iese din "for j" (de pe linia i)
}
//=> se trece la linia urmatoare
if (OK==1) contor++;
//la finalul liniei testam valoarea var. OK
}
cout<<"Numarul liniilor cu elementele egale: "<<contor<<endl;
return 0;
}

Rulare:
Dati numarul de linii: 4 <Enter>
Dati numarul de coloane: 3 <Enter>
Dati elementele matricei:
1 1 2 <Enter>
0 0 0 <Enter>
1 1 1 <Enter>
-1 1 1 <Enter>
Numarul liniilor cu elementele egale: 2

R4.
Enunul problemei: S se descrie un algoritm pentru a determina suma elementelor prime mai
mici sau egale dect k ntr-o matrice dreptunghiular.
2 3
1

4 6
0
i k = 7, suma elementelor
Metoda de rezolvare: De exemplu, pentru A =
7 1 8

2 0 11

prime mai mici sau egale dect k este: 2 + 3 + 7 = 12. Algoritmul const n parcurgerea
elementelor matricei i dac elementul curent este prim i este mai mic sau egal cu k atunci se
nsumeaz. Ar fi de preferat ca n cadrul unei expresii logice compuse, prima condiie testat
s fie cea cu valoarea cel mult k cci este mai puin complex dect testarea primalitii.
O descriere a algoritmului n C++ (CodeBlocks):
#include <iostream>
using namespace std;
int Prim(int n)
{
if (n<=1) return 0; //testam inclusiv pentru numere negative
//else

Algoritmi si structuri de date (10-11.12.2014) Informatica&Matematic, anul 1

for (int i=2; i*i<=n; (i==2)?i=3:(i+=2))


if (n%i==0) return 0;
return 1;

ASD21AlgMatrLab

//sau i++

}
int main()
{
int m,n,i,j,k,a[10][10],S;
cout<<"Dati numarul de linii: "; cin>>m;
cout<<"Dati numarul de coloane: "; cin>>n;
cout<<"Dati elementele matricei: "<<endl;
for (i=0;i<m;i++)
for (j=0;j<n;j++) cin>>a[i][j];
cout<<"k = "; cin>>k;
S=0;
for (i=0;i<m;i++)
for (j=0;j<n;j++)
if (a[i][j]<=k && Prim(a[i][j])==1) S += a[i][j];
cout<<"suma elementelor prime <=k: "<<S<<endl;
return 0;
}

Rulare:
Dati numarul de linii: 3
Dati numarul de coloane: 4
Dati elementele matricei:
1 2 3 4 <Enter>
5 6 7 8 <Enter>
9 10 11 12 <Enter>
k = 5 <Enter>
suma elementelor prime <=k: 10

R5.
Enunul problemei: S se descrie un algoritm pentru a interschimba dou linii p i q
specificate dintr-o matrice dreptunghiular.
Metoda de rezolvare: Algoritmul const n parcurgerea simultan a celor dou linii (linia p:
ap1, ap2, ..., apj, ..., apn i linia q: aq1, aq2, ..., aqj, ..., aqn) dintr-o matrice cu m linii i n coloane i
interschimbarea a cte dou componente din cele dou linii (apj aqj).
O descriere a algoritmului n C++ (CodeBlocks):
#include <iostream>
#include <iomanip>
using namespace std;
void InterschimbareLinii(int p, int q,float a[10][10],int n) {
//interschimba liniile p si q intr-o matrice cu n coloane
float aux;
for (int j=0;j<n;j++) {
//parcurgem simultan liniile p si q
aux = a[p][j]; //interschimbam elementele a[p][j] cu a[q][j]
a[p][j] = a[q][j];
a[q][j] = aux;
}
}
void Afisare(float a[10][10],int m,int n) {
for (int i=0;i<m;i++) {//pentru fiecare linie
for (int j=0;j<n;j++) cout<<setw(3)<<a[i][j]; //afisam linia
cout<<endl;
//trecem pe randul urmator
}
}

Algoritmi si structuri de date (10-11.12.2014) Informatica&Matematic, anul 1

ASD21AlgMatrLab

int main() {
int m,n,i,j,p,q;
float a[10][10];
cout<<"Dati numarul de linii: "; cin>>m;
cout<<"Dati numarul de coloane: "; cin>>n;
cout<<"Dati elementele matricei: "<<endl;
for (i=0;i<m;i++)
for (j=0;j<n;j++) cin>>a[i][j];
cout<<"p = "; cin>>p; p--; //diferenta de indici fata de C/C++
cout<<"q = "; cin>>q; q--;
InterschimbareLinii(p,q,a,n);
cout<<"Matricea dupa interschimbarea liniilor p si q:"<<endl;
Afisare(a,m,n);
return 0;
}

Rulare:
Dati numarul de linii: 4 <Enter>
Dati numarul de coloane: 3 <Enter>
Dati elementele matricei:
1 1 1 <Enter>
2 2 2 <Enter>
3 3 3 <Enter>
4 4 4 <Enter>
p=2
q=4
Matricea dupa interschimbarea liniilor p si q:
1 1 1
4 4 4
3 3 3
2 2 2

R6.
Enunul problemei: S se descrie un algoritm pentru a stabili dac o matrice ptrat este ptrat
magic sau nu, adic suma pe fiecare linie, coloan au diagonale este aceeai.
Metoda de rezolvare: De exemplu, matricea:
2 9 4

A = 7 5 3
6 1 8

este ptrat magic, 15 fiind fiecare sum a elementelelor de pe diagonala principal, secundar,
orice linie i orice coloan.
O descriere a algoritmului n C++ (CodeBlocks):
#include <iostream>
using namespace std;
float SumaDiag1(float a[10][10],int n) {
//calculeaza suma pe diagonala principala
float S=0;
for (int i=0;i<n;i++) S += a[i][i];
return S;
}
float SumaDiag2(float a[10][10],int n) {
//calculeaza suma pe diagonala secundara
float S=0;
for (int i=0;i<n;i++) S += a[i][n-1-i];
return S; }

Algoritmi si structuri de date (10-11.12.2014) Informatica&Matematic, anul 1

ASD21AlgMatrLab

float SumaLinie(int p, float a[10][10],int n) {


//calculeaza suma pe linia p intr-o matrice patrata de dim.n
float S=0;
for (int j=0;j<n;j++) S += a[p][j];
return S;
}
float SumaColoana(int q, float a[10][10],int n) {
//calculeaza suma pe coloana q intr-o matrice patrata de dim.n
float S=0;
for (int i=0;i<n;i++) S += a[i][q];
return S;
}
int main() {
int n,i,j;
float a[10][10],S;
cout<<endl<<endl<<"Dati dimensiunea matricei: "; cin>>n;
cout<<"Dati elementele matricei: "<<endl;
for (i=0;i<n;i++)
for (j=0;j<n;j++) cin>>a[i][j];
S = SumaDiag1(a,n); //retinem in S suma elem de pe diag.princ.
if (SumaDiag2(a,n)!=S)
//daca suma elem. de pe diagonala secundara nu este egala cu S
cout<<"Nu este patrat magic";
else
{
for (i=0;i<n;i++) //parcurgem simultan liniile si col.
if (SumaLinie(i,a,n)!=S || SumaColoana(i,a,n)!=S)
//suma elem. de pe linia i sau coloana i nu este egala cu S
{cout<<"Nu este patrat magic";
break;
}
if (i==n) //daca inainte n-au fost iesiri fortate din for
//atunci din for se iese cu valoarea n
cout<<"Este patrat magic"<<endl;
}
return 0;
}

Rulare:
Dati numarul de linii: 3 <Enter>
Dati elementele matricei:
2 9 4 <Enter>
7 5 3 <Enter>
6 1 8 <Enter>
Este patrat magic
sau
Dati numarul de linii: 3 <Enter>
Dati elementele matricei:
1 2 3 <Enter>
1 2 3 <Enter>
1 2 3 <Enter>
Nu este patrat magic

Algoritmi si structuri de date (10-11.12.2014) Informatica&Matematic, anul 1

ASD21AlgMatrLab

R7.
Enunul problemei: Pe o tabl de ah (cu liniile numerotate de la 1 la 8 i coloanele de la A la
H) se dau coordonatele a doi nebuni, unul alb i unul negru. S se descrie un algoritm pentru a
stabili dac cei doi nebuni se atac sau nu.
Metoda de rezolvare: De exemplu, dac un nebun este pe poziia D3 i al doilea n poziia
G6, acetia se atac, ns dac acetia sunt n poziiile D3 i G5 nu se atac. Algoritmul const
n a stabili dac cele dou piese sunt pe o paralel cu diagonala principal, adic formeaz un
triunghi dreptunghic isoscel cu paralele la axele orizontal i vertical ( |c1-c2| = |n1-n2| ).
(c1, n1) 450
450
(c2, n2)
O descriere a algoritmului n C++ (CodeBlocks):
#include <iostream>
#include <stdlib.h> //pt abs altfel in C++: apel ambiguu
using namespace std;
int main()
{
char c1,c2;
int n1,n2;
cout<<"Dati pozitia primului nebun: ";
cin>>c1>>n1;
cout<<"Dati pozitia celui de-al doilea nebun: ";
cin>>c2>>n2;
if (abs(c1-c2) == abs(n1-n2))
//coordonatele coloanelor se convertesc in
//codurile ASCII corespunzatoare ('A'->65, ..., 'H'->72)
//apoi se calculeaza diferenta dintre ele => lungime latura
cout<<"Cei doi nebuni se pot ataca"<<endl;
else
cout<<"Cei doi nebuni nu se pot ataca"<<endl;
return 0;
}
Rulare:
Dati pozitia primului nebun: D 3 <Enter>
Dati pozitia celui de-al doilea nebun: G 6 <Enter>
Cei doi nebuni se pot ataca

Das könnte Ihnen auch gefallen