Sunteți pe pagina 1din 14

Chițu Ioan

10LF321

Structuri de date
Tema 1
1. Se consideră doi vectori v1 cu nr1 elemente și v2 cu nr2 elemente. Vectorul v1 este sortat
crescător și vectorul v2 este sortat descrescător. Să se obțină un al treilea vector v3 care
conține atât elementele lui v1 cât și elementele lui v2 care este sortat crescător. Folosiți o
metodă eficientă. (1p)
#include <iostream>

void citire(double*& v1, int& nr1, double*& v2, int& nr2)


{
std::cin >> nr1;
v1 = new double[nr1];
for (int i = 0; i < nr1; ++i)
std::cin >> v1[i];
std::cin >> nr2;
v2 = new double[nr2];
for (int i = 0; i < nr2; ++i)
std::cin >> v2[i];
}
//Complexitate O(nr1+nr2)
double* interclasare(double* v1, int nr1, double* v2, int nr2)
{
double* v3 = new double[nr1 + nr2];
int i = 0, j = nr2 - 1, k = 0;
while (i < nr1 and j >= 0)
if (v1[i] > v2[j])
v3[k++] = v2[j--];
else
v3[k++] = v1[i++];
while (i < nr1)
v3[k++] = v2[j--];
while (j >= 0)
v3[k++] = v2[j--];
return v3;
}
void afisare(double* v, int n)
{
for (int i = 0; i < n; ++i)
std::cout << v[i] << ' ';
}
int main()
{
int nr1, nr2;
double* v1, * v2, * v3;
citire(v1, nr1, v2, nr2);
v3 = interclasare(v1, nr1, v2, nr2);
afisare(v3, nr1 + nr2);
delete[]v1;
delete[]v2;
delete[]v3;
}

2. Se consideră un vector conținând nr numere naturale. Scrieți o funcție cere are ca


parametru vectorul și dimensiunea acestuia și care returnează cel mai mare număr natural
care se poate forma cu toate cifrele pare ale numerelor existente în vector. Folosiți un
algoritm eficient. (1p)
#include <iostream>
#include <algorithm>

void citire(int*& v, int& nr)


{
std::cin >> nr;
v = new int[nr];
for (int i = 0; i < nr; ++i)
std::cin >> v[i];
}
void realocare_o_unitate(int*& v, int n)
{
int* copie = new int[n];
for (int i = 0; i < n; ++i)
copie[i] = v[i];
if(v)
delete[]v;
v = new int[n + 1];
for (int i = 0; i < n; ++i)
v[i] = copie[i];
delete[]copie;
}
//determinare cifre pare: O(n*nr_cifre), sortare: O(nlogn), formare numar: O(n)
// => O(n*nr_cifre), unde nr_cifre este numărul de cifre însumat al tuturor
// celor n numere
int formare_numar(int* v, int n)
{
int nr_cif = 0, * cif{};
for (int i = 0; i < n; ++i)
if (v[i] == 0)
{
realocare_o_unitate(cif, nr_cif);
cif[nr_cif++] = v[i];
}
else
while (v[i])
if (v[i] % 2 == 0)
{
realocare_o_unitate(cif, nr_cif);
cif[nr_cif++] = v[i] % 10;
v[i] /= 10;
}
else
v[i] /= 10;
if (!cif)
return -1;
std::sort(cif, cif + nr_cif, std::greater<int>());
int numar = cif[0];
for (int i = 1; i < nr_cif; ++i)
numar = numar * 10 + cif[i];
delete[]cif;
return numar;
}

int main()
{
int nr;
int* v;
citire(v, nr);
int numar = formare_numar(v, nr);
std::cout << numar;
delete[]v;
return 0;
}

3. Se citesc dintr-un fișier un număr de elevi. Fiecare elev are un nume, un prenume și 3
note, numere naturale. Se va folosi pentru elev un tuple cu câmpurile nume și prenume
de tip string și cu trei câmpuri de note de tip int. elevii vor fi memorați într-un obiect de
tip std::vector<std::tuple<std::string, std::string, int, int, int>>. Să se sorteze vectorul
de elevi descrescător după medie și să se afișeze frumos, punând în evidență elevii c ote
mai mici decât 5. (2p)
#include <iostream>
#include <algorithm>
#include <vector>
#include <tuple>
#include <iomanip>
#include <fstream>

void citire_date(std::vector<std::tuple<std::string, std::string, int, int, int>>&date)


{
std::ifstream fin("elevi.in");
std::string nume, prenume;
int nota1, nota2, nota3;
while (fin >> nume >> prenume >> nota1 >> nota2 >> nota3)
date.push_back({ nume , prenume , nota1 , nota2 , nota3 });
}

//O(1)
double media(int nota1, int nota2, int nota3)
{
return (nota1 + nota2 + nota3) / 3.0;
}
bool comparator(std::tuple<std::string, std::string, int, int, int>a, \
std::tuple<std::string, std::string, int, int, int>b)
{
return media(std::get<2>(a), std::get<3>(a), std::get<4>(a)) > \
media(std::get<2>(b), std::get<3>(b), std::get<4>(b));
}
void afisare(std::vector<std::tuple<std::string, std::string, int, int, int>>date)
{
std::cout << std::setw(98);
std::cout << std::setfill('-') << ' ' << std::endl;
std::cout << "| NUME PRENUME ELEV" << std::setw(18) << std::setfill(' ') << ' ';
std::cout << "| NOTA 1 | NOTA 2 | NOTA 3 | MEDIA | MENTIUNE";
std::cout << std::setw(15) << std::setfill(' ') << '|' << std::endl;
std::cout << std::setw(98) << std::setprecision(2);
std::cout << std::setfill('-') << ' ' << std::endl;
for (auto a : date)
{
int dist1 = 0, dist2 = 0, dist3 = 0, dist4 = 0;
std::string mentiune = "";
double med = media(std::get<2>(a), std::get<3>(a), std::get<4>(a));
if (std::get<2>(a) <= 5 or std::get<3>(a) <= 5 or std::get<4>(a) <= 5)
mentiune = "Elevul are note sub 5";
if (std::get<2>(a) < 10)
dist1 = 1;
if (std::get<3>(a) < 10)
dist2 = 1;
if (std::get<4>(a) < 10)
dist3 = 1;
if (med == int(med))
if (med == 10)
dist4 = 2;
else
dist4 = 3;
std::cout << "| " << std::get<0>(a) << ' ' << std::get<1>(a);
std::cout << std::setw(36 - std::get<0>(a).size() - std::get<1>(a).size());
std::cout << std::setfill(' ');
std::cout << "| " << std::get<2>(a) << std::setw(7 + dist1) << std::setfill(' ');
std::cout << "| " << std::get<3>(a) << std::setw(7 + dist2) << std::setfill(' ');
std::cout << "| " << std::get<4>(a) << std::setw(7 + dist3) << std::setfill(' ');
std::cout << "| " << std::setprecision(3) << med << std::setw(4 + dist4);
std::cout <<std::setfill(' ');
std::cout << "| " << mentiune << std::setw(23 - mentiune.size()) << std::setfill(' ');
std::cout << '|';
std::cout << std::endl << std::setw(98);
std::cout << std::setfill('-') << ' ' << std::endl;
}
}
int main()
{
std::vector<std::tuple<std::string, std::string, int, int, int>>elev;
citire_date(elev);
//O(nlogn)
std::sort(elev.begin(), elev.end(), comparator);
afisare(elev);
return 0;
}

4. Utilizând tipul de date std::pair<float, float> să se citească coordonatele a două puncte


p1 și p2 din sistemul cartezian XOY și să se rezolve următoarele cerințe:
a) Să se verifice dacă cele două puncte se află în același cadran (0.5p)
b) Să se calculeze distanța euclidiană dintre cele două puncte (0.5p)
c) Să se calculeze unghiul pe care îl face dreapta ce conține segmentul p1p2 cu axa Ox
(1p)

#include <iostream>
#include <cmath>
constexpr auto PI = 3.14159265359;

void citire_puncte(std::pair<float, float>& p1, std::pair<float, float>& p2)


{
std::cout << "Cordonatele primului punct: ";
std::cin >> p1.first >> p1.second;
std::cout << "Coordonatele celui de-al doilea punct: ";
std::cin >> p2.first >> p2.second;
}
//O(1)
int cadran(std::pair<float, float>p)
{
if (p.first == 0 and p.second == 0)
return 0;
if (p.first > 0 and p.second >= 0)
return 1;
if (p.first <= 0 and p.second > 0)
return 2;
if (p.first < 0 and p.second <= 0)
return 3;
if (p.first >= 0 and p.second < 0)
return 4;
}
//O(1)
bool acelasi_cadran(std::pair<float, float>p1, std::pair<float, float>p2)
{
if (cadran(p1) == cadran(p2))
return 1;
return 0;
}
//O(1)
float dist_eucl(std::pair<float, float>p1, std::pair<float, float>p2)
{
if (p1.first == p2.first)
if (p1.second == p2.second)
return 0;
else
return abs(p1.second - p2.second);
if (p1.second == p2.second)
return abs(p1.first - p2.first);
return sqrt(pow(p1.first - p2.first, 2) + pow(p1.second - p2.second, 2));
}
//O(atan2)
float unghi(std::pair<float, float>p1, std::pair<float, float>p2)
{
float dx = p2.first - p1.first;
float dy = p2.second - p1.second;
//panta este (y2-y1)/(x2-x1)=tan(alpha)
return atan2(dy, dx) / PI * 180;
}
int main()
{
std::pair<float, float>p1, p2;
citire_puncte(p1, p2);
if (acelasi_cadran(p1, p2))
std::cout << "Punctele se afla in acelasi cadran\n";
else
std::cout << "Punctele se afla in cadrane diferite\n";
std::cout << "Distanta euclidiana dintre cele doua puncte este " << dist_eucl(p1, p2);
std::cout << "\nDreapta determinata de p1 si p2 formeaza cu Ox un unghi de " << unghi(p1, p2) << "
grade\n";
return 0;
}
5. Se citește un număr natural nr și nr medii (numere reale cu două zecimale cu valori
cuprinse între 1 și 10). Notele se stochează într-un container de tip
std::vector<float>note. Să se afișeze o statistică a mediilor astfel: numărul de medii
cuprinse în intervalul [1,5), numărul de medii din intervalul [5,5.50), numărul de medii
cuprinse în intervalul [5.50,6.50), ..., numărul de medii cuprinse în intervalul [9.50,10].
(1.5p)
#include <iostream>
#include <vector>
#include <iomanip>

void citire_note(std::vector<float>& note)


{
int nr;
std::cin >> nr;
float nota;
for (int i = 0; i < nr; ++i)
{
std::cin >> nota;
note.push_back(nota);
}
}
//O(1)
int interval(float nota)
{
//[1,5)
if (nota >= 1 and nota < 5)
return 0;
//[5,5.50)
if (nota >= 5 and nota < 5.5)
return 1;
//[5.50,6.50)
if (nota >= 5.5 and nota < 6.5)
return 2;
//[6.50,7.50)
if (nota >= 6.5 and nota < 7.5)
return 3;
//[7.50,8.50)
if (nota >= 7.5 and nota < 8.5)
return 4;
//[8.50,9.50)
if (nota >= 8.5 and nota < 9.5)
return 5;
//[9.50,10]
if (nota >= 9.5 and nota <= 10)
return 6;
}
//O(n)
void statistica(int intervale[7], std::vector<float> note)
{
for (int i = 0; i < 7; ++i)
intervale[i] = 0;
for (auto nota : note)
++intervale[interval(nota)];
}
int nr_cif(int a)
{
int ct = 0;
do
{
a /= 10;
++ct;
} while (a);
return ct;
}
void afis_statistica(int intervale[7])
{
std::cout << std::setw(36) << std::setfill('-') << "\n";
std::cout << "| Nr. | INTERVAL NOTE | NR. NOTE |\n";
std::cout << "| crt. |" << std::setw(16) << std::setfill(' ') << '|';
std::cout << std::setw(12) << std::setfill(' ') << "|\n";
std::cout << std::setw(36) << std::setfill('-') << "\n";
float st, dr;
for (int i = 0; i < 7; ++i)
{
char inchis_deschis;
if (i < 6)
inchis_deschis = ')';
else
inchis_deschis = ']';

std::cout << std::setiosflags(std::ios::right) << std::setprecision(2);


std::cout << '|' << std::setw(5) << std::setfill(' ') << i + 1 << " | ";
std::cout << std::resetiosflags(std::ios::right);
switch (i)
{
case 0:
{
st = 1;
dr = 5;
break;
}
case 1:
{
st = dr;
dr = 5.5;
break;
}
case 2:
{
st = 5.5;
dr += 1;
break;
}
case 6:
{
st = 9.5;
dr = 10;
break;
}
default:
{
st += 1;
dr += 1;
break;
}
}
int spatiu = 0;
if (st == 1)
std::cout << '[' << st << ',' << dr;
if (st == 5)
{
std::cout << '[' << st << std::setiosflags(std::ios::fixed) << ',' << dr;
spatiu = 3;
}
if (st > 5 and st < 9)
{
std::cout << std::setiosflags(std::ios::fixed) << '[' << st << ',' << dr;
spatiu = 6;
}
if (st > 9)
{
std::cout << std::setiosflags(std::ios::fixed) << '[' << st;
std::cout << std::resetiosflags(std::ios::fixed) << ',' << dr;
spatiu = 4;
}
std::cout << inchis_deschis << std::setw(11-spatiu) << std::setfill(' ') << "| ";
spatiu = nr_cif(intervale[i]);
std::cout << intervale[i] << std::setw(11-spatiu) << std::setfill(' ') << "|\n";
std::cout << std::setw(36) << std::setfill('-') << "\n";
std::cout << std::resetiosflags(std::ios::fixed);
}
}
int main()
{
std::vector<float>note;
citire_note(note);
int intervale[7];
statistica(intervale, note);
afis_statistica(intervale);
return 0;}

6. Cristina și George vor pleca într-o excursie și trebuie să cumpere alimente. Fiecare a
alcătuit o lista de cumpărături pe care sunt numele de produse și cantitatea din fiecare
produs, pe care o doresc. George folosește o funcție, care preia cele două liste și
returnează o a treia, ce conține toate produsele din ambele liste, împreună cu cantitățile
corespunzătoare. Produsele care apar pe ambele liste vor apărea o singură dat în lista
finală , cu cea mai mare cantitate dintre cele de pe cele două liste. Scrieți această funcție
și afișați frumos lista finală. Observație: folosiți vectori pentru memorarea listelor de
cumpărături. Produsele vor avea nume de tip std::string.(2p)
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <iomanip>

class lista
{
public:
float cantitate{};
std::string produs;
bool operator>(lista list)
{
return lista::produs > list.produs;
}
//supraîncărcare operator "==" pentru a compara componenta produs a obiectului\
cu componenta produs a variabilei rhs
bool operator==(const lista& rhs) const { return this->produs == rhs.produs; }
};

void citire_lista(std::vector<lista>& list, std::string fisier)


{
std::ifstream fin(fisier);
lista date;
while (fin>>date.produs>>date.cantitate)
list.push_back(date);
}
//find: O(n), cele 2 for-uri: O(2n) => O(2n^2)
std::vector<lista>creeare_lista(std::vector<lista>list1, std::vector<lista>list2)
{
std::vector<lista>final_list;
std::vector<lista>::iterator it;
for (auto l1 : list1)
{
it = std::find(list2.begin(), list2.end(), l1);
if (it != list2.end())
{
int index = it - list2.begin();
if (l1.cantitate > list2[index].cantitate)
final_list.push_back(l1);
else
final_list.push_back(list2[index]);
}
else
final_list.push_back(l1);

}
for (auto l2 : list2)
{
it = std::find(list1.begin(), list1.end(), l2);
if (it == list1.end())
final_list.push_back(l2);
}
return final_list;
}
void afisare_lista(std::vector<lista>list)
{
std::cout << " PRODUSE" << std::setfill(' ')<<std::setw(6)<<std::setfill(' ')<<' ' << "| CANTITATE\n";
std::cout << std::setw(27) << std::setfill('-') << '\n';
for (auto l : list)
{
std::cout << ' ' << l.produs << std::setw(15 - l.produs.size()) << std::setfill(' ');
std::cout << " | " << std::setprecision(3) << l.cantitate << std::endl;
std::cout << std::setw(27) << std::setfill('-') << '\n';
}
}

int main()
{
std::vector<lista>lista_Cristina;
std::vector<lista>lista_George;
std::vector<lista>lista_finala;
citire_lista(lista_Cristina, "lista_Cristina.in");
citire_lista(lista_George, "lista_George.in");
lista_finala = creeare_lista(lista_Cristina, lista_George);
afisare_lista(lista_finala);
return 0;
}

7. Alex are un joc cu blocuri din lemn de forma unor paralelipipede dreptunghice cu baza
pătrată de dimensiune fixă. Blocurile au înălțimi diferite. Alex aranjează aceste blocuri în
pătrate concentrice.
a) Să se verifice dacă un astfel de aranjament, reprezentat printr-o matrice, are formă
piramidală, adică: toate blocurile dintr-un pătrat sunt mai mici decât cele aflate în
regiunea din interiorul acestui pătrat. (1p)
b) Dacă pe baza fiecărui pătrat este gravat un număr pozitiv (ce reprezintă înălțimea
blocului în cm), să se scrie o funcție care calculează pentru un pătrat k înălțimea
medie a cuburilor de pe acel pătrat. (1p)

#include <iostream>
#include <fstream>

void Quader_Lesen(float**& mat, int& n,std::string Datei)


{
std::ifstream fin(Datei);
fin >> n;
mat = new float* [n];
mat[0] = new float[n * n];
for (int i = 1; i < n; ++i)
mat[i] = mat[i - 1] + n;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
fin >> mat[i][j];
}
void Matrix_Druck(float** mat, int n)
{
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
std::cout << mat[i][j]<<' ';
std::cout << std::endl;
}
}
//O(n^2)
bool Pyramide(float** mat, int n)
{
float max_ext = INT_MIN, min_int = INT_MAX, max_int = INT_MIN;
int Grenze;
if (n % 2 == 0)
Grenze = n / 2;
else
Grenze = n / 2 + 1;

for (int i = 0; i < n; ++i)


if (max_ext < mat[0][i])
max_ext = mat[0][i];
for (int i = 1; i < n; ++i)
if (max_ext < mat[i][n - 1])
max_ext = mat[i][n - 1];
for (int i = n - 2; i >= 0; --i)
if (max_ext < mat[n - 1][i])
max_ext = mat[n - 1][i];
for (int i = n - 2; i > 0; --i)
if (max_ext < mat[i][0])
max_ext = mat[i][0];
for (int k = 1; k < Grenze; ++k)
{
for (int i = k; i < n - k; ++i)
{
if (min_int > mat[k][i])
min_int = mat[k][i];
if (max_int < mat[k][i])
max_int = mat[k][i];
}
for (int i = k + 1; i < n - k; ++i)
{
if (min_int > mat[i][n - 1 - k])
min_int = mat[i][n - 1 - k];
if (max_int < mat[i][n - 1 - k])
max_int = mat[i][n - 1 - k];
}
for (int i = n - 2 - k; i > k - 1; --i)
{
if (min_int > mat[n - 1 - k][i])
min_int = mat[n - 1 - k][i];
if (max_int < mat[n - 1 - k][i])
max_int = mat[n - 1 - k][i];
}
for (int i = n - 2 - k; i > k; --i)
{
if (min_int > mat[i][k])
min_int = mat[i][k];
if (max_int < mat[i][k])
max_int = mat[i][k];
}
if (min_int <= max_ext)
return false;
max_ext = max_int;
max_int = INT_MIN;
min_int = INT_MAX;
}
return true;
}
//O(4(n-4)) – schlimmster Fall \
O(1) – bster Fall
float mittlere_Hohe(float** mat, int n, int Quadrat_Nr)
{
int k = Quadrat_Nr - 1, Blocke_Nr = 0;;
float Summe = 0;
for (int i = k; i < n - k; ++i)
{
Summe += mat[k][i];
++Blocke_Nr;
}
for (int i = k + 1; i < n - k; ++i)
{
Summe += mat[i][n - 1 - k];
++Blocke_Nr;
}
for (int i = n - 2 - k; i > k - 1; --i)
{
Summe += mat[n - 1 - k][i];
++Blocke_Nr;
}
for (int i = n - 2 - k; i > k; --i)
{
Summe += mat[i][k];
++Blocke_Nr;
}
return Summe / Blocke_Nr;
}
int main()
{
float** Blocke;
int n;
Quader_Lesen(Blocke, n, "blocuri.in");
Matrix_Druck(Blocke, n);
if (Pyramide(Blocke, n))
std::cout << "Pyramidalische Konstruktion";
else
std::cout << "Die Konstruktion ist nicht pyramidalisch";
int Quadrat_Nr;
std::cout << "\nQuadratnummer: ";
std::cin >> Quadrat_Nr;
std::cout << "\nDie mittlere Hohe der Blocke aus dem " << Quadrat_Nr
<< " Quadrat ist: " << mittlere_Hohe(Blocke, n, Quadrat_Nr);
delete[]Blocke[0];
delete[]Blocke;
return 0;
}

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