Documente Academic
Documente Profesional
Documente Cultură
Implementare C++
#include <iostream>
using namespace std;
int cifraMinima_V1(int n) {
if(n<=9) //caz in care n este format dintr-o singura cifra
return n;
int cifraMinima_restul_numarului = cifraMinima_V1(n / 10);
return (n % 10 < cifraMinima_restul_numarului ? n % 10 : cifraMinima_restul_numarului);
}
1 / 22
PB2 Determinarea cifrei pare maxime a lui n
Să se realizeze o funcție recursivă cu un singur parametru (numărul n) pentru determinarea
cifrei pare maxime a lui n, se va returna cifra pară maximă sau -1, dacă n nu are cifre pare.
Analiză – se scrie formula recursivă
{
1 , dacă n este format dintr−o singură cifră impară
n
cifraParaMaxima (n)= cifraParaMaxima ([ ])
10
, daca n mod 10 este impara
{
max n mod 10 , cifraParaMaxima ([ ])}
n
10
, daca n mod 10 este para
Implementare C++
#include <iostream>
using namespace std;
int cifraParaMaxima(int n) {
if(n<=9) {//caz in care n este format dintr-o singura cifra
if(n%2==0) return n;
else return -1;
}
int ultima_cifra = n % 10;
if (ultima_cifra % 2 != 0) return cifraParaMaxima(n / 10);
int cifraParaMaxima_restul_numarului = cifraParaMaxima(n / 10);
return (ultima_cifra > cifraParaMaxima_restul_numarului ? ultima_cifra : cifraParaMaxima_restul_numarului);
}
{
0 , daca n<10 sin ≠ c
n
aparitii (n , c)= 1+aparitii ( )
10
, c , daca n>c si n mod 10=c
n
aparitii ( )
10
, c , daca n> c si n mod 10 ≠ c
Implementare C++
#include <iostream>
using namespace std;
int aparitii(int n, int c) {
// daca n are o singura cifra returnez 1 daca cifra = c, 0 altfel
if (n < 10) return n == c;
//daca ultima cifra e c o adauga la numaratoare
else if (n % 10 == c) return 1 + aparitii(n / 10, c);
2 / 22
else return aparitii(n / 10, c);
}
elimCifrePare ( n )=
Implementare C++
{ elimCifrePare
elimCifrePare
n
([ ])
10
n
([ ])
10
, daca n numar par
#include <iostream>
using namespace std;
int elimCifrePare(int n) {
if (n == 0) return 0;
else
if (n % 2 == 0) return elimCifrePare(n / 10);
else return elimifrePare(n / 10) * 10 + n % 10;
}
Pentru varianta recursivă, formula recursivă se deduce din formula anterioară astfel:
1, daca j=0
rest (i, j , k )=
{
( ( i mod k )∗rest ( i, j−1, k ) ) mod k
Implementare C++
//ITERATIV //RECURSIV
#include <iostream> #include <iostream>
using namespace std; using namespace std;
int Rest(int i, int j, int k) { int Rest(int i, int j, int k) {
int r = i % k; if (j == 0) return 1;
int rest = 1; return ((i % k) * Rest(i, j - 1, k)) % k;
while (j > 0) {
}
rest = (rest * r) % k; j--;
}
3 / 22
return rest;
}
Implementare C++
#include <iostream>
using namespace std;
PB7
Un domeniu pătrat (cu albastru), ca cel din figură trebuie
apărat. Domeniul e împărțit în pătrățele. Latura domeniului
este de n pătrățele, n≥7. Pe culoarele colorate patrulează 3
soldați, care încep patrularea din colțul stânga sus în același
moment (poziția inițială). În exemplul de mai jos avem n=9.
Cei 3 soldați (garda) se vor schimba cu alți 3 soldați în
momentul în care ajung în poziția inițială, simultan.
Soldații patrulează în sensul acelor de ceasornic fiecare cu
aceeași viteză constantă, și fiecare pe culoarul său.
Să se implementeze un program care determină numărul de
circuite complete pentru fiecare soldat (un circuit complet
este făcut de un soldat oarecare, pe același culoar până
ajunge în poziția inițială), pentru schimbarea gărzii.
4 / 22
S1 patrulează pe culoarul galben, S2 pe gri, S3 pe roșu. Albastrul este cetatea care trebuie apărată.
Analiză
-Considerăm doi soldați care patrulează circuite de lungimi diferite, măsurate în unități (o unitate este
un pătrățel). Un circuit are lungime L1, iar al doilea lungime L2 unități.
-Cei doi vor ajunge concomitent în punctul inițial după ce parcurg X = cmmmc(L1, L2) unități. Astfel,
primul va parcurge X/L1 circuite, iar al doilea X/L2.
-Aceeași idee se aplică pentru trei soldați.
1 2 3 4 5 6 2 22 23 24
1 2 3 4 7 1
2 13 14 15 16
12 5 8
0
11 6 9
1 24 17
10 9 8 7 10
9
12 11
1 23 18
8
41
25 26 22 43
21 44
20 45
19 46
42
25 26 27 28 27 7
1
1 15 14 13
36 29 28 4 37 38 39 40 47
35 30 29 06
34 33 32 31 30 3 48 41 48
3 35 34 33 32 31 9
6 3 47 42
8
6 3 46 45 44 43
1 7
6 49/61 50 51 5
0 2
5 60 5
9 3
5 59 5 49
8 4
5 58 57 56 5 50 Implementare C++
7 5 #include <iostream>
5 55 54 53 5 51
using namespace std;
6 2
int cmmmc(int a, int b){
if (a < b){
int aux = a;a = b;b = aux;
}
// cel mai mare numar se aduna repetat cu el insusi si se verifica divizibilitatea cu celalalt
int rez = a;
while (rez % b != 0) rez += a;
return rez;
}
//Descriere: Calculeaza numarul de circuite complete pentru fiecare soldat, pana la intalnire.
//Date: n – latura domeniului.
//Rezultate: c1, c2, c3 – numarul de circuite parcurse de catre cei trei soldati.
5 / 22
void circuite(int n, int& c1, int& c2, int& c3){
int l1 = 4 * (n - 1); // lungimea culoarului exterior
int l2 = 4 * (n - 3); // lungimea culoarului din mijloc
int l3 = 4 * (n - 5); // lungimea culoarului interior
int intalnire = cmmmc(cmmmc(l1, l2), l3); // cmmmc al lui l1, l2, l3
c1 = intalnire / l1;
c2 = intalnire / l2;
c3 = intalnire / l3;
}
int main(){
int n = 0;
cout << "Introduceti latura domeniului: ";
cin >> n;
int c1 = 0, c2 = 0, c3 = 0;
circuite(n, c1, c2, c3);
cout << "Soldatul S1 va face " << c1 << " circuite pana la intalnire." << endl;
cout << "Soldatul S2 va face " << c2 << " circuite pana la intalnire." << endl;
cout << "Soldatul S3 va face " << c3 << " circuite pana la intalnire." << endl;
return 0;
}
Observatie: Alternativ, se poate lua in considerare calculul cmmmc folosind cmmdc, astfel:
𝒄𝒎(𝒂,𝒃)=(𝒂∗𝒃)/𝒄𝒎𝒎𝒅𝒄(𝒂,𝒃)
Implementare C++
#include <iostream>
using namespace std;
bool esteTriangular(int x) {
int n = 1, s = 0;
while (s <x) {
s = s + n;
n++;
}
if (s == x) return true;
return false;
6 / 22
}
//afiseaza maximul dintre numerele triangulare din fiecare sir citit, iar apoi afiseaza maximul global
void nrTriangulareMaximaleDinSir() {
int n, max, maxTriangular = -1;
cin >> n;
while (n > -1) {
max = -1;
while (n > -1) {
if (esteTriangular(n) && n > max) max = n;
cin >> n;
}
if (max > maxTriangular) maxTriangular = max;
cout <<"Maximul dintre numerele triunghiulare din sirul citit este "<< max;
cin >> n;
}
cout <<"Maximul dintre toate numerele triunghiulare din toate sirurile este "<<
maxTriangular;
}
Pb9-Numere piramidale
Sa se scrie o functie care
afiseaza primele k numere piramidale,
unde k este un nr natural specificat ca
parametru functiei.
Un număr x se numește piramidal
daca exista un numar natural n astfel
incat x poate fi scris ca suma
primelor n numere triangulare.
1+2+3+4+5=15 1+3+6+10=20
Pentru k=8 se va afisa: 1, 4, 10, 20, 35, 56, 84, 120, 165
Implementare C++
#include <iostream>
using namespace std;
void sirPiramidal(int k{
int s = 1, n = 2, nrPiramidal = 1;
for (int i = 0; i <k; i++) {
cout << nrPiramidal <<", ";
s = s + n;
n = n + 1;
nrPiramidal = nrPiramidal + s;
}
}
Pb10 - Secvențe 101(binar)
Fie un număr n, se definește gradul numărului n ca fiind numărul de secvențe "101" din
reprezentarea binară a acestuia. De exemplu, numărul 21 are gradul 2 (reprezentarea binară a lui 21
este 10101). Pentru un șir s citit de la tastatură să se determine grupul de numere de grad k.
7 / 22
Analiză: - o posibilă rezolvare poate utiliza un vector de 32 de elemente (daca elementele șirului sunt
numere naturale de tipul intreg reprezentarea binară a unui intreg are 32 de biți, dimensiunea unui
intreg este 4 octeți).
Exemple:
Date de intrare Date de ieșire
1 (k) numere de grad 1:
7 5, 13, 29
5 5(2)= 101
13 13(2)= 1101
21 29(2)= 11101
29
25
0
2 (k)
13 numere de grad 2:
5 21, 45, 360
21
56 21(2)= 10101
45 45(2)= 10101
360 360(2)= 101101000
37
0
Implementare C++
#include <iostream>
using namespace std;
const int NRBITI = 32;
int BINAR[NRBITI] = {0}; //toate elementele vectorului BINAR se initializeaza cu 0
void resetBinar(){
for (int i = 0; i < NRBITI; ++i)
BINAR[i] = 0;
}
// reprezint un numar in baza doi, n - numarul natural de reprezentat in baza doi,
// returnez: numarul de cifre din reprezentarea binara
int calculReprezBinar(int n){
resetBinar();
for (int i = 0; n > 0; i++) {
BINAR[i] = n % 2;
n = n / 2;
}
return i+1;
}
// reprezint un numar in baza doi, versiunea II folosind operatii pe biti
// n - numarul natural de reprezentat in baza doi
// returnez: numarul de cifre din reprezentarea binara
int calculReprezBinar2(int n){
resetBinar();
int i = 0;
while (n) {
BINAR[i] = n & 1;
n >>= 1;
i++;
}
return i;
}
8 / 22
// calcul determina gradul unui numar (numarul de secvente 101 din reprezentarea binara)
// n - numarul natural pentru care trebuie determinat gradul
// returnez: gradul numarului
int determinaGrad(int n){
int grad = 0;
int nrCifre = 0;
nrCifre = calculReprezBinar2(n);
for (int i = nrCifre; i >= 2; i--) {
if(BINAR[i]==1 && BINAR[i-1]==0 && BINAR[i-2]==1)
grad++;
}
return grad;
}
int main() {
int k, numar = 1;
// se citeste gradul cautat
cin >> k;
// sirul s va stoca numerele de grad k
int s[100] = {0};
int i = 0;
// citirea numerelor se termina cu citirea lui 0
while (numar) {
cin >> numar;
if (k == determinaGrad(numar)) {
s[i] = numar;
i++;
}
}
cout << "numere de grad " << k << " :" << endl;
for (int y = 0; y < i; ++y) {
cout << s[y] << " ";
}
return 0;
}
O abordare MAI EFICIENTĂ poate fi imaginată prin izolarea celor mai puțin semnificativ trei
biți din reprezentarea binară și verificarea dacă sunt o secvență 101, după care se deplasează la stânga
cu una sau două poziții (în funcție de rezultatul comparației cu (101)2 = (5)10 ).
Implementare C++
#include <iostream>
using namespace std;
int determinaGrad2(int n){
int grad = 0;
while (n) {//se izoleaza cei mai putin semnificativ 3 biti si se verifica daca sunt o secventa 101
if ((n&7) == 5) { //7 (in baza 2) = 111, 5(in baza 2) = 101
grad++;
n >>= 2;
} else
n >>= 1;
}
return grad;
}
int main() {
9 / 22
int k, numar = 1;
// se citeste gradul cautat
cin >> k;
// citirea numerelor se termina cu citirea lui 0
while(numar) {
cin >> numar;
if (k == determinaGrad2(numar)) {
cout << "numarul " << numar << " are gradul " << k << endl;
}
}
return 0;
}
Implementare C++
#include <iostream>
using namespace std;
int sumPatrate(int n){
int suma = 0;
while (n) {
suma += (n % 10) * (n % 10);
n /= 10;
}
return suma;
}
bool eNumarZambaret(int n){
int nr1, nr2;
nr1 = nr2 = n; // initializare numere cu n
//un numar NU este zambaret daca pe parcursul iteratiilor atinge aceeasi valoare succesiv
do {
nr1 = sumPatrate(nr1);
nr2 = sumPatrate(sumPatrate(nr2));
} while (nr1 != nr2);
return (nr1 == 1); // daca ambele numere sunt 1, return true
}
int main() {
int contor = 0;
int numar = 1;
while (numar) {
cin >> numar;
if (eNumarZambaret(numar)) {
cout << "numarul " << numar << " este zambaret" << endl;
contor++;
}
cout << "Am citit " << contor << " numere zambarete" << endl;
10 / 22
return 0;
}
Exemple:
Date de intrare si rezultat
23
numarul 23 este zambaret
45
56
46
49
numarul 49 este zambaret
19
numarul 19 este zambaret
100
numarul 100 este zambaret
11
0
Am citit 4 numere zambarete
Implementare C++
long sumDiv(long n) {
long S = n + 1; //initializarea sumei S cu n+1 (divizorii improprii)
long d = 2;
for (d = 2; d*d<n; d++) //se verifica pentru d=2,3,...,radical(n)-1
11 / 22
if (n%d == 0) S += d + n / d; //se aduna factorii complementari
if (d*d == n) S += d; //daca n este patrat perfect se mai aduna d
return S; //d, atentie la iesire din for d>=radical(n)
}
Implementare C++
void citesteNumarSiPrecizie(double& x, double& eps){
cout << "Introduceti numarul real si apoi precizia: ";
cin >> x >> eps;
}
double determinaRadacinaPatrataIterativ(double x, double eps){
double dreapta = x;
double stanga = 0;
double mij = (dreapta + stanga) / 2;
while (abs(dreapta - stanga) > eps) {
if (mij * mij > x) dreapta = mij;
else stanga = mij;
mij = (dreapta + stanga) / 2;
12 / 22
}
return mij;
}
double determinaRadacinaPatrataRec(double x, double eps, double stanga, double dreapta){
double mij = (dreapta + stanga) / 2;
if (abs(dreapta - stanga) < eps) return mij;
if (mij * mij > x)
return determinaRadacinaPatrataRec(x, eps, stanga, mij);
return determinaRadacinaPatrataRec(x, eps, mij, dreapta);
}
double determinaRadacinaPatrataRecursiv(double x, double eps){
return determinaRadacinaPatrataRec(x, eps, 0, x);
}
int main(){
double x = 0, eps = 0;
citesteNumarSiPrecizie(x, eps);
cout << "Iterativ: ";
cout << "Radacina patrata a numarului " << x << ", cu precizia " << eps << " este: " <<
determinaRadacinaPatrataIterativ(x, eps) << endl;
cout << endl;
cout << "Recursiv: ";
cout << "Radacina patrata a numarului " << x << ", cu precizia " << eps << " este: " <<
determinaRadacinaPatrataRecursiv(x, eps) << endl;
return 0;
}
Implementare C++
#include <iostream>
using namespace std;
int citesteNumar() {
int n = 0;
cout << "Introduceti un numar natural: "; cin >> n;
return n;
}
bool prim(int n) {
if (n < 2) return false; // numerele mai mici ca 2 nu sunt prime
if (n == 2) return true; // 2 este prim
if (n % 2 == 0) return false; // numerele pare nu sunt prime
for(int div = 3; div * div <= n; d+=2) // verificare pentru n impar
13 / 22
if (n % div == 0) return false; // iesire n nu e prim
return true; // la finalul lui for n e prim
}
// gaseste, pentru numarul n, primul divizorul prim dupa div. Daca un astfel de divizor nu exista,
// se returneaza -1
int divizorPrimUrmator(int n, int div) {
if (prim(n)) return -1;
int i = div + 1;
while ((!prim(i) || (n % i != 0)) && i != n)
i++;
if (i == n) return -1;
return i;
}
//determina numarul din sirul X (format dupa cum se specifica in enunţul problemei), de la pozitia poz
int determinaNumarDeLaPozitie(int poz) {
if (poz < 3) return poz + 1;
int rezultat = 0;
int numarCurentInSecventa = 3;
int pozitieCurenta = 2;
while (poz > pozitieCurenta) {
numarCurentInSecventa++;
if (prim(numarCurentInSecventa)){ // daca numarul este prim, pozitia va creste cu 1
pozitieCurenta += 1;
rezultat = numarCurentInSecventa;
} else { // se iau pe rand divizorii primi ai numarului
int divUrm = divizorPrimUrmator(numarCurentInSecventa, 1);
while (poz > pozitieCurenta && divUrm != -1) {
pozitieCurenta += divUrm; // valoarea divUrm va aparea de divUrm
//ori in sir, deci se pot sari divUrm pozitii
rezultat = divUrm; // toate aceste pozitii vor contine valoarea divUrm
divUrm = divizorPrimUrmator(numarCurentInSecventa, divUrm);
}
}
}
return rezultat;
}
int main() {
/*for (int i = 0; i < 100; i++)
cout << i << " " << determinaNumarDeLaPozitie(i) << endl;*/
int poz = citesteNumar();
cout << "Numarul din sirul X de pe pozitia " << poz << " este: " <<
determinaNumarDeLaPozitie(poz) << ".";
system("pause");
return 0;
}
14 / 22
Probleme tip grilă
16 / 22
}
if (c) cout << i << ” ” << c << endl;
}
}
a) Afişează perechi de numere prime (n≥2).
b) Afişează numerele prime până la n (n≥2).
c) Afişează factorii primi ai lui n (n≥2).
d) Afişează factorii primi ai lui n şi puterile lor (n≥2).
e) Subprogramul nu afişează nimic, dacă n<2.
7. Care este efectul execuției următoarei secvențe de instrucțiuni?
citeşte a,b {numere întregi}
x 1
cât_timp (a>0)şi(b>0) execută
dacă (a mod 10)<(b mod 10) atunci x0
sfDaca
a [a/10]
b [b/10]
sfCat_timp
dacă (x=1) şi (b=0) atunci scrie ”DA”
altfel scrie ”NU”
sfDaca
a) Afişează „DA” pentru perechi de numere strict pozitive.
b) Afişează „NU” pentru perechi de numere strict negative.
c) Afişează „DA” dacă a<b.
d) Afisează „DA” dacă fiecare cifră a lui a este mai mare sau egala cu cifra corespondentă a lui b
(unităţi, zeci, etc.) şi numarul cifrelor lui b este mai mic sau egal cu numarul cifrelor lui a daca a,b>0.
e) Afişează „DA” pentru a=34, b=12
8. Care este efectul executiei urmatoarei secvente de instrucţiuni pentru şirul: 5, 24, 5, 25, 5, 26,
0?
citeşte x {x natural}
nr0
s0
cât_timp x≠0 executã
nrnr+1
dacã nr mod 2=0 atunci
ss+x mod 10
sfDaca
citeşte x
sfCat_timp
scrie s, nr
a) Afişează 0 0.
b) Afişează 15 6.
c) Afişează 10 9.
d) Afişează 10 6.
e) Afişează suma ultimelor cifre ale numerelor de rang (indice) par din şir si numarul de numere
nenule citite.
17 / 22
9. Se consideră următoarea secvență de instrucțiuni.
citeşte n,c {n, natural>0, c cifra}
z0
cât_timp n mod 10=c execută
n [n/10]
zz+1
sfCat_timp
scrie z
a) Afişează 3 pentru n=123 şi c=3;
b) Afişează 2 pentru n=12003 şi c=0;
c) Afişează 1, pentru n=c=1;
d) Afişează 4, pentru n=1277771 şi c=7
e) Afişează 3, pentru n=12555 şi c=5.
13. Se considera subalgoritmul prim(n,d), n si d - numere naturale nenule, care verifica daca
numarul n este prim.
Subalgoritmul prim(n, d):
18 / 22
dacǎ (n<2) atunci returneazǎ 0;
sfDacǎ
dacǎ d=1 atunci returneazǎ 1;
sfDacǎ
Dacǎ (n mod d=0) atunci returneazǎ 0;
sfDacǎ
returneazǎ prim
Cum ar trebui efectuat apelul pentru ca subalgoritmul sǎ returneze rǎspunsul corect:
a) Prim(n,n)
b) Prim(n,1)
c) Prim(n,n/2)
d) Prim(n/2,2)
16. Ce va afișa următoarea secvență de program, dacă se citesc în această ordine numerele: 194,
121, 782?
citeşte x (număr natural)
n=0
┌cât timp x≠0 execută
│ y=x; c=0
19 / 22
│ ┌cât timp y>0 execută
│ │ ┌dacă y%10>c atunci
│ │ │ c=y%10
│ │ └■
│ │ y=y/10
│ └■
│ n=n*10+c
│ citeşte x
└■
scrie n
17. Care este valoarea afişată pentru x=-2 şi m=9?
citeşte x ,m
{x întreg, m natural}
y1
┌ cât timp m>0 exec
│┌ dacă m%2 =0
││ atunci
││ m [m/2]; xx*x
││ altfel
││ mm-1;yy*x
│└■
└■
scrie y
21. Se consideră funcția de mai jos, care primește ca parametru un număr natural.
int f(int a){
20 / 22
int x = a % 10;
if (x == a)
if (x % 2 == 0) return a;
else return 0;
if (x % 2 == 0) return 10 * f((int)(a/10)) + x;
return f((int)(a/10));
}
22. Știind că variabilele a și i sunt întregi, stabiliți ce reprezintă valorile afișate de algoritmul de
mai jos.
a 10
pentru i 1,6 execută
scrie [a/7]
a a % 7 * 10
sfârşit pentru
21 / 22
Răspunsuri
1 b
2 a, b, d
3 b
4 b
5 e
6 d, e
7 b, d, e
8 b, e
9 c, e
10 b
FALS
(se tine cont de
11 prioritatea
operatorilor)
12 b, c, d
13 c
14 d
15 c
16 928
-512
17
calculeaza lungimea
18
unui șir de caractere
transformă un numar
19
în baza doi
20 b
21-I b
21-II c
22 c
22 / 22