Probleme cu elementele de bază ale limbajului C++

Probleme cu elementele de bază ale limbajului C++

În acest articol voi prezenta câteva probleme elementare ce țin de elementele de bază ale limbajului C++ (operatori și expresii, structura alternativă, structura repetitivă). Puteți găsi câteva dintre aceste probleme și pe PbInfo. Sper că este suficient să scriu doar secvențele de cod esențiale și nu tot programul pentru fiecare exercițiu :smile:

Probleme cu operatori și expresii C++

Problema 1.

Să se scrie o expresie care testează dacă a este divizibil cu b, a și b fiind naturale, iar b nenul.

Dacă a este divizibil cu b înseamnă că restul împărțirii lui a la b este 0. Expresia va fi a % b == 0.

Problema 2.

Să se scrie o expresie care testează dacă numărul natural a este nenul, și respectiv una care testează dacă este 0.

Soluția imediată, care folosește operatorul diferit de este a != 0. Există și o soluție mai scurtă, ce testează exact același lucru, și anume a. Într-o structură de genul if (a), numărul a se convertește la tipul bool. Astfel, dacă a este diferit de 0, expresia devine true, iar altfel false. Similar, expresia !a testează dacă a nu este nenul, adică dacă este 0.

Problema 3.

Să se testeze dacă a și b dau același rest la împărțirea la k. Considerăm că a > b și k > 0.

Se observă că dacă a și b dau același rest la împărțirea la k, atunci diferența lor este divizibilă cu k, deci soluția va fi (a - b) % k == 0.

Problema 4.

Să se afișeze rădăcina pătrată a numărului natural n, pătrat perfect.

Pentru a nu implementa un algoritm care să extragă radicalul unui număr, vom folosi funcția sqrt din biblioteca cmath. Pentru a funcționa, trebuie inclusă la început biblioteca unde este definită funcția (#include <cmath>). Expresia va fi cout << sqrt(n).

Problema 5.

Să se afișeze partea întreagă a numărului real n.

Vom folosi operatorul de conversie a tipului (din double în int). Acesta returnează partea întreagă a lui n, deci soluția este (int) n.

Problema 6.

Să se testeze dacă numărul n este pătrat perfect folosind funcția sqrt.

Funcția sqrt returnează mereu un double (un număr real). Cum un pătrat perfect are mereu rădăcina pătrată număr întreg, soluția constă în a testa dacă radicalul lui n este este egal cu partea sa întreagă folosind operatorul de conversie a tipului: sqrt(n) == (int) sqrt(n). Desigur, putem folosi o variabilă auxiliară care să rețină radicalul, pentru a nu se calcula de două ori:

double aux = sqrt(n);
if (aux == (int) aux)
cout << "DA\n";
else
cout << "NU\n";

Problema 7.

Să se scrie o expresie care testează dacă numărul întreg x aparține intervalului închis la ambele capete determinat de numerele a și b.

De multe ori în problemele de informatică cu intervale nu se specifică care dintre capete este mai mare, așa că vom avea două cazuri: când a <= b și când a > b.

Expresia va fi: a <= x && x <= b || b <= x && x <= a.

Problema 8.

Să se afișeze codul ASCII al caracterului chr.

O variabilă de tip char reține codul ASCII al caracterului pe care-l reprezintă, diferențele dintre un char și un int cu aceeași valoare sunt doar la citire și afișare. Când afișăm o variabilă de tip char, afișăm caracterul corespunzător ei, însă când afișăm un int, afișăm un număr. Deci, cea mai simplă soluție constă în conversia caracterului la int, pentru a putea fi afișat drept număr: cout << (int) chr.

Problema 9.

Să se scrie o expresie care testează dacă un caracter dat (chr) este o literă a alfabetului englez.

Vom testa dacă chr este o literă mică sau mare. Ne vom folosi de faptul că dacă două litere sunt consecutive în alfabet, atunci și codurile lor ASCII sunt consecutive. Cu alte cuvinte, literele apar în ordine alfabetică în tabelul ASCII.

Deci, expresia va fi 'a' <= chr && chr <= 'z' || 'A' <= chr && chr <= 'Z'.

Problema 10.

Se dă un caracter chr. Să se testeze dacă acesta este un caracter alb.

Vom testa dacă chr este spațiu, tab sau enter: chr == ' ' || chr == '\t' || chr == '\n'.

Problema 11.

Să se afișeze modulul diferenței a două numere a și b.

Avem două cazuri, a > b și a <= b. Putem folosi instrucțiunea if, dar o soluție simplă ce folosește operatorul condițional ternar este a > b ? a - b : b - a.

Problema 12.

Să se afișeze valoarea sumei 1+2++n1 + 2 + \cdots + n

Desigur, putem aduna efectiv fiecare număr de la 1 la n într-o variabilă sum, dar putem răspunde practic instant folosind formula lui Gauss: 1+2++n=n(n+1)/21 + 2 + \cdots + n = n(n+1)/2 S-ar putea ca produsul n * (n + 1) să depășească tipul int, așa că ar fi bine să punem un 1LL în față, pentru a forța ca tipul expresiei să fie long long int. Deci, expresia este 1LL * n * (n + 1) / 2.

Probleme cu instrucțiunea alternativă if

Problema 1.

Să se afișeze suma, diferența, produsul, câtul și restul împărțirii a două numere întregi date. Cazul în care b este 0 se va trata separat.

int a, b; cin >> a >> b;
cout << "Suma: " << a + b << '\n';
cout << "Diferenta: " << a - b << '\n';
cout << "Produsul: " << a * b << '\n';
if (!b)
cout << "Impartirea la 0 nu are sens.";
else {
cout << "Catul impartirii: " << a / b << '\n';
cout << "Restul impartirii: " << a % b << '\n';
}

Problema 2.

Să se afișeze maximul a două numere a și b.

if (a > b)
cout << a << '\n';
else
cout << b << '\n';

Problema 3.

Fiind dată nota unui elev, să se afișeze dacă acesta rămâne corigent sau promovează.

if (nota < 5)
cout << "corigent\n";
else
cout << "promovat\n";

Problema 4.

Să se afișeze minimul a trei numere date (a, b, c).

Ne putem încurca în 100 de if-uri, dar cea mai simplă soluție este să calculăm minimul dintre a și b, iar apoi minimul dintre acest rezultat și c. Ideea se aplică și pentru determinarea minimului maximului a n numere.

int min;
if (a < b)
min = a;
else
min = b;
if (min < c)
cout << min << '\n';
else
cout << c << '\n';

Problema 5.

Stabiliți dacă numărul nenul n este negativ sau pozitiv.

if (n < 0)
cout << "negativ\n";
else
cout << "pozitiv\n";

Problema 6.

Să se stabilească dacă un an calendaristic dat este bisect sau nu. Un an este bisect dacă se divide cu 4 și nu se divide cu 100, sau dacă se divide cu 400.

if (n % 4)
cout << "NU\n";
else if (n % 400 == 0)
cout << "DA\n";
else if (n % 100 == 0)
cout << "NU\n";
else
cout << "DA\n";

Și o soluție mai concisă:

if (n % 4 == 0 && n % 100 || n % 400 == 0)
cout << "DA\n";
else
cout << "NU\n";

Problema 7.

Să se verifice dacă trei numere întregi date pot fi laturile unui triunghi.

Ne folosim de inegalitatea triunghiului. Ca trei numere să fie laturile unui triunghi, suma oricăror două laturi trebuie să fie mai mare decât a treia latură. În plus, vom mai testa dacă numerele date sunt strict pozitive.

if (a <= 0 || b <= 0 || c <= 0 ||
a + b <= c || a + c <= b || b + c <= a)
cout << "NU\n";
else
cout << "DA\n";

Problema 8.

Fiind date laturile unui triunghi, să se determine dacă acesta este isoscel și nu este echilateral.

if (!(a == b && b == c) && (a == b || b == c || c == a))
cout << "DA\n";
else
cout << "NU\n";

Problema 9.

Fiind date laturile unui triunghi (abc\htmlClass{katexified}{(} a \ge b \ge c să se determine dacă acesta este dreptunghic, ascuțitunghic sau obtuzunghic.

Din teorema cosinusului putem deduce că:

  • b2+c2>a2b^2 + c^2 \gt a^2 \Leftrightarrow triunghi ascuțitunghic
  • b2+c2=a2b^2 + c^2 = a^2 \Leftrightarrow triunghi dreptunghic
  • b2+c2<a2b^2 + c^2 \lt a^2 \Leftrightarrow triunghi obtuzunghic
if (b * b + c * c == a * a)
cout << "triunghi dreptunghic\n";
else if (b * b + c * c < a * a)
cout << "triunghi obtuzunghic\n";
else
cout << "triunghi ascutitunghic\n";

Problema 10.

Se dau coordonatele a două puncte în plan (x1, y1, x2, y2). Să se stabilească dacă dreapta este verticală, orizontală sau oblică.

Dacă x1 == x2, atunci dreapta este paralelă cu axa OYOY deci verticală. Dacă y1 == y2, atunci dreapta este paralelă cu axa OXOX deci orizontală. Altfel, dreapta este oblică.

if (x1 == x2)
cout << "verticala\n";
else if (y1 == y2)
cout << "orizontala\n";
else
cout << "oblica\n";

Problema 11.

Se dă un număr n de maxim trei cifre. Să se determine câte cifre are.

if (n < 10)
cout << "1\n";
else if (n < 100)
cout << "2\n";
else
cout << "3\n";

Problema 12.

Se dau coeficienții din ecuația de gradul al II-lea ax2+bx+c=0ax^2 + bx + c = 0 cu a>0a \gt 0 Să se determine rădăcinile sale.

double delta = b * b - 4 * a * c;
if (delta < 0)
cout << "Nu exista solutii reale.\n";
else if (!delta)
cout << -b / (2 * a) << '\n';
else {
cout << (-b - sqrt(delta)) / (2 * a) << ' ';
cout << (-b + sqrt(delta)) / (2 * a) << '\n';
}

Problema 13.

Se dă o dată calendaristică (ziua: z, luna: l, anul: a), cele trei numere fiind nenule. Să se determine dacă este o dată corectă.

if (l == 1 || l == 3 || l == 5 || l == 7 || l == 8 || l == 10 || l == 12) {
if (z <= 31)
cout << "DA\n";
else
cout << "NU\n";
}
else if (l == 4 || l == 6 || l == 9 || l == 11) {
if (z <= 30)
cout << "DA\n";
else
cout << "NU\n";
}
else if (l == 2) {
if (n % 4 == 0 && n % 100 || n % 400 == 0) {
if (z <= 29)
cout << "DA\n";
else
cout << "NU\n";
}
else if (z <= 28)
cout << "DA\n";
else
cout << "NU\n";
}
else
cout << "NU\n";

Probleme cu instrucțiunile repetitive (for, while, do while)

Problema 1.

Să se afișeze primele n numere naturale pare nenule în ordine crescătoare.

Vom folosi o variabilă i cu care vom itera de la 1 la n, iar la fiecare pas afișăm dublul ei.

for (int i = 1; i <= n; i++)
cout << 2 * i << ' ';

Putem optimiza un pic soluția, și doar să creștem i-ul din 2 în 2, ca să nu se calculeze un produs la fiecare pas.

for (int i = 2; i <= 2 * n; i += 2)
cout << i << ' ';

Totuși n-am făcut mare brânză, pentru că la fiecare pas se calculează 2 * n când se evaluează condiția. Ar fi o idee bună să calculăm acest număr înaintea for-ului, din moment ce nu se va schimba.

int m = 2 * n;
for (int i = 2; i <= m; i += 2)
cout << i << ' ';

Acum se face doar o adunare la fiecare pas. Uneori optimizările de genul ăsta chiar contează pentru numere mari, dar pentru cerința asta prefer prima variantă. O înmulțire cu 2 și o incrementare la fiecare pas nu înseamnă mai nimic.

Problema 2.

Să se calculeze aba^b pentru aa nenul.

Vom lua o variabilă p inițializată cu 1, în care calculăm rezultatul, și o vom înmulți cu a de b ori. Astfel nici nu va mai trebui să tratăm separat cazul în care b este 0. Problema se poate rezolva mai eficient, în timp logaritmic; despre asta am scris aici.

int p = 1;
for (int i = 0; i < b; i++)
p *= a;

Problema 3.

Să se afișeze 10n10^n

Atenție, scrie să se afișeze, deci nu trebuie neapărat să calculăm într-o variabilă răspunsul :wink: Vom afișa cifra 1 urmată de n de 0. Astfel, programul va funcționa și pentru valori foarte mari ale lui n.

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

Problema 4.

Să se afișeze un dreptunghi format din cifre 0, de lățime m (linii) și lungime n (coloane).

Pentru fiecare linie afișăm n caractere de 0, urmate de enter.

for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++)
cout << 0;
cout << '\n';
}

Problema 5.

Să se afișeze o piramidă de ordinul n ca mai jos.

1
1 2
1 2 3
.........
1 2 3 ... n

Pentru linia i vom afișa primele i numere naturale nenule.

for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++)
cout << j << ' ';
cout << '\n';
}

Problema 6.

Să se afișeze un romb de ordinul n ca mai jos. Exemplul este pentru n == 5:

1
222
33333
4444444
555555555
4444444
33333
222
1

Nimic special, doar facem câteva observații pentru numărul de spații și de cifre de pe fiecare rând.

for (int i = 1; i <= n; i++) {
for (int j = 0; j < n - i; j++)
cout << ' ';
for (int j = 1; j < 2 * i; j++)
cout << i;
cout << '\n';
}
for (int i = n - 1; i >= 1; i--) {
for (int j = 0; j < n - i; j++)
cout << ' ';
for (int j = 1; j < 2 * i; j++)
cout << i;
cout << '\n';
}

Problema 7.

Se citește câte un număr natural până la introducerea lui 0. Calculați suma lor.

Este un exemplu bun pentru folosirea instrucțiunii do while. O putem utiliza ca mai jos deoarece adunarea lui 0 la sumă nu afectează rezultatul.

int sum = 0;
do {
cin >> x;
sum += x;
} while (x);

Problema 8.

Se citește câte un număr natural nenul până la introducerea a două numere egale. Să se calculeze suma tuturor numerelor introduse.

Folosim o variabilă xPrec unde reținem x-ul citit la pasul anterior. Dacă acesta este egal cu x-ul curent, ne putem opri. Vom inițializa xPrec cu 0 pentru a fi siguri că va fi diferit de primul x. Cel mai sugestiv este să folosim while și break.

int xPrec = 0, sum = 0;
while (true) {
cin >> x;
sum += x;
if (x == xPrec)
break;
xPrec = x; // Nu mai este nevoie de else
// pentru că oricum ieșim din while prin break.
}

Problema 9.

Se citesc n numere naturale, n > 0. Să se calculeze media aritmetică a celor impare.

Citim numerele cu un for. La fiecare pas testăm dacă numărul curent este impar. Dacă da, actualizăm suma și numărul de numere impare. La final împărțim cele două variabile.

int sum = 0, nr = 0;
for (int i = 0; i < n; i++) {
cin >> x;
if (x % 2) {
sum += x;
nr++;
}
}
cout << sum / nr << '\n';

Problema 10.

Se dau două numere naturale nenule n și b. Să se afișeze numărul obținut prin conversia lui n din baza 10 în baza b.

Trebuia să bag într-un articol și algoritmul de conversie dintr-o bază în alta, iar ăsta mi s-a părut cel mai potrivit loc :smile: Deci, pentru a scrie numărul n în baza b se procedează astfel: Îl împărțim pe n la b până devine zero, iar apoi parcurgem resturile obținute la fiecare pas în ordine inversă. Pentru a putea face asta, am reținut resturile în vectorul cif, a cărui lungime len o incrementez la fiecare pas adăugând restul curent.

int n, b; cin >> n >> b;
while (n) {
cif[len++] = n % b;
n /= b;
}
for (int i = len - 1; i >= 0; i--)
cout << cif[i];
cout << '\n';

Problema 11.

Se dă un număr format din n cifre în baza b. Să se afișeze numărul respectiv în baza 10.

Procedăm ca atunci când ni se dă un număr în baza 10 cifră cu cifră, pe care trebuie să-l construim în timp ce citim cifrele. Diferența este că în loc de 10 trebuie să folosim numărul b.

int n, b; cin >> n >> b;
int sol = 0;
for (int i = 0; i < n; i++) {
int x; cin >> x;
sol = sol * b + x;
}
cout << sol << '\n';

Acestea sunt cele mai importante exerciții ce pun în evidență elementele de bază ale limbajului C++. Dacă aveți vreo astfel de problemă care nu vă iese, lăsați un comentariu și vă voi ajuta :smile:

Mulțumesc că ai citit acest articol.
Dacă vrei să susții blogul, poți cumpăra un abonament de 2$.

patreon

Lasă un comentariu!

0 comentarii