Sunteți pe pagina 1din 5

Algoritmi si structuri de date (5-6.11.

2014) Informatica&Matematic , anul 1

ASD13AlgIterLab

ALGORITMI ITERATIVI (continuare)

R1.
Enunul problemei: S se descrie un algoritm pentru determinarea tuturor ptratelor perfecte
mai mici sau egale cu nN* dat.
Metoda de rezolvare: O metod ar fi s parcurgem toate numerele de la 0 la n i s testm
?

dac acestea sunt ptrate perfecte sau nu ( i N [ i ] = i ).


O alt metod: i=? astfel nct i2n este echivalent cu i=? astfel nct 1 i [ n ], astfel c
este suficient s parcurgem toate numerele naturale i ntre 1 i [ n ] i s afim i2.
Descrierea algoritmului n pseudocod:
citeste n

*presupunem n1

pentru i = 0, [ n ], 1 repeta
scrie i2

Descrierea algoritmului n C++ (CodeBlocks):


#include <iostream>
//#include <cmath> //pt sqrt
using namespace std;
int main()
{
int n,i;
cout<<"n="; cin>>n;
cout<<"Patratele perfecte pana la n: ";
//for (i=0;i<=sqrt(n);i++)
for (i=1;i*i<=n;i++) //i*i<=n <=> i<=sqrt(n) si evitam cmath
cout<<i*i<<" ";
return 0;
}

Rulare:
n = 10 <Enter>
Patratele perfecte pana la n: 0 1 4 9

sau
n = 16 <Enter>
Patratele perfecte pana la n: 0 1 4 9 16

R2.
n

Enunul problemei: Descriei un algoritm pentru calculul sumei S =

k!,

pentru n1.

k =1

De exemplu, pentru n = 4: S = 1! + 2! + 3! + 4! = 1 + 2 + 6 + 24 = 33.


Metoda de rezolvare: Avem de calculat o sum de factoriale, deci o sum de produse.
Folosind algoritmii clasici de determinarea unei sume i a unui produs, un prim algoritm
const n: iniializarea sumei cu 0, apoi pentru i de la 1 la n se adun la suma anterioar i!,
care se poate calcula clasic ca un produs: orice produs se iniializeaz cu 1, apoi pentru k = 2
la n nmulim produsul anterior cu k (k ncepe de la 2 i nu de la 1 pentru a nu mai nmuli cu
1).
1

Algoritmi si structuri de date (5-6.11.2014) Informatica&Matematic , anul 1

ASD13AlgIterLab

Descrierea algoritmului 1 n pseudocod:


*presupunem n1

citeste n
S 0
pentru k = 1, n repeta
kfact 1
pentru i = 2, k repeta
kfact kfact * i
S S + kfact
scrie S

*i=1 a fost omis


*pentru a nu mai inmulti cu 1

Algoritmul anterior calculeaz fiecare factorial de la capt (12k). Dar innd cont c la un
moment dat, adugm un factorial, la urmtorul nu ar trebui dect s nmulim cu k curent
(k! = (k-1)! k). Acest lucru se aplic la orice algoritm n care termenul curent al sumei se
poate scrie (n ntregime sau parial) n funcie de termenul anterior (n ntregime sau parial):
n

S = 1! + 2! + 3! + ...+ n! = k!, iar k! = (k-1)! k, pentru k1 (reamintim 0! = 1).


k =1

Descrierea algoritmului 2 n pseudocod:


citeste n
*presupunem n1
S 0
*initializarea sumei cu 0
kfact 1 *initializarea termenului curent al sumei cu 1
pentru k = 1, n repeta
kfact kfact * k
S S + kfact

scrie S

Se mai poate optimiza algoritmul anterior, prin iniializarea sumei cu primul termen, apoi k
ncepe de la valoarea 2.
Descrierea algoritmului n C++ (CodeBlocks):
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int n,k;
float S=1,kfact=1; //declarare si initializare
//am inclus in suma deja 1!
//factorilele este bine sa fie memorate in tip de date float
cout<<"n="; cin>>n; //presupunem ca
for (k=2;k<=n;k++) //pornim cu k de la 2
{
kfact *= k; //factorialul anterior se inmulteste cu k
S += kfact; //se adauga la suma
}
cout<<"S = 1!+2!+...+n! = "<<fixed<<setprecision(0)<<S<<endl;
return 0;
}

R3.
n

Enunul problemei: Descriei un algoritm pentru calculul sumei S = k a k , pentru nN* i


k =1

aR date. De exemplu, pentru n=3 i a=2 avem S = 121 + 222 + 323 = 34.
Metoda de rezolvare: Avem de calculat o sum de puteri (ak) nmulite cu k. Avnd n vedere
observaiile din algoritmul anterior, aici putem calcula parte din termenul general n funcie de
parte din termenul general anterior: ak = ak-1 a, pentru k1).
2

Algoritmi si structuri de date (5-6.11.2014) Informatica&Matematic , anul 1

ASD13AlgIterLab

Descrierea algoritmului n pseudocod:


*presupunem n1
*initializarea sumei cu 0
*initializarea puterii cu 1

citeste n,a
S 0
ak 1
pentru k = 1, n repeta
ak ak * a
S S + k*ak

scrie S

Descrierea algoritmului n C++ (CodeBlocks):


#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int n,k;
float S=0,ak=1,a;
//functie putere care creste repede => memorare in "float"
//factorilele este bine sa fie memorate in tip de date float
cout<<"n="; cin>>n; //pp. n>=1
cout<<"a="; cin>>a;
for (k=1;k<=n;k++)
{
ak *= a;
//puterea anteioara se inmulteste cu a
S += k*ak;
}
cout<<"S = "<<fixed<<setprecision(0)<<S<<endl;
return 0;
}

Rulare:
n=3
a=2
S = 34
R4.
Enunul problemei: Determinai un algoritm pentru determinarea tuturor variantelor de scriere
a unui numr ntreg dat ca sum de dou numere prime; n cazul n care nu exist nicio
descompunere se va afia un mesaj.
Metoda de rezolvare: De exemplu, n = 12 = 5+7, iar n = 10 = 3+7 = 5+5, iar pentru n = 23 se
va afia mesajul nu se descompune.
Vom cuta s descompunem n n suma dintre dou numere prime: i i n-i. Cea mai
mic valoare a lui i este 2 pentru c acesta este cel mai mic divizor propriu, iar valoarea cea
mai mare este aceea pentru care cele dou componente sunt ordonate: i n-i i n / 2.
Pentru cazurile cnd nu exist nicio descompunere, putem lua o variabil n care s
memorm valoarea 1 n care am gsit cel puin o decompunere i valoarea 0 n cazul n care n
exist nicio descompunere. Putem iniializa aceast variabil cu 0, iar n cazul gsirii unei
descompuneri s schimbm valoarea variabilei la valoarea 1. La final, dac variabila a rmas
cu valoarea iniializat 0, atunci se afieaz un mesaj.
O descriere a algoritmului n C++:
#include <iostream>
#include <iomanip>
using namespace std;
int Prim (int n)
{

Algoritmi si structuri de date (5-6.11.2014) Informatica&Matematic , anul 1

ASD13AlgIterLab

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


if (n%i==0) return 0;
return 1;
}
int main() {
int n, OK = 0; //initializam variabila OK cu 0
//ca si cum am presupune ca nu exista nicio descompunere
cout<<"n="; cin>>n;
for (int i=2;i<=n/2; i++)
if (Prim(i)==1 && Prim(n-i)==1) {
cout<<n<<" = "<<setw(2)<<i<<" + "<<n-i<<endl;
OK = 1; //am gasit o descompunere
}
if (OK == 0) //daca nu am gasit nicio descompunere => mesaj
cout<<"Nu se poate descompune"<<endl;
return 0;
}

R6 (studiu individual).
Enunul problemei: S se determine toate numerele prime mai mici sau egale dect un numr
natural n2 dat.
Metoda de rezolvare: De exemplu, pentru n=10 numerele prime mai mici sau egale dect n
sunt 2, 3, 5, 7. Vom parcurge toate numerele de la 2 (cel mai mic numr prim) pn la n i
testm primalitatea numrului curent. n C++, primalitatea se poate testa prin apelarea unei
funcii.
O descriere a algoritmului n C++:
#include <iostream>
using namespace std;
int Prim (int n)
{
//if (n==0 || n==1) return 0;
for (int i=2; i*i<=n; (i==2)?i=3:(i+=2))
if (n%i==0) return 0;
return 1;
}
int main()
{
int n;
cout<<"n="; cin>>n;
cout<<"Numerele prime pana la n sunt: ";
for (int i=2; i<=n; i++) //pornind de la 2, din 1 in 1
if (Prim(i)) //sau if (Prim(i)==1)
cout<<i<<" ";
return 0;
}

Algoritmi si structuri de date (5-6.11.2014) Informatica&Matematic , anul 1

ASD13AlgIterLab

Tem suplimentar:
1. S se descrie un algoritm pentru a afia divizorii primi ai unui numr natural dat.
2. S se descrie un algoritm pentru afiarea tuturor numerelor prime de 3 cifre, care citite
invers sunt tot numere prime.
3. S se descrie un algoritm pentru a stabili dac dou numere sunt gemene (p i q sunt 2
numere gemene dac ambele sunt numere prime i q p = 2). De exemplu, 3 i 5,
5 i 7, 11 i 13, 17 i 19, 29 i 31 sunt numere gemene.
4. S se descrie un algoritm pentru a exprima o sum de lei dat n numr minim de
bancnote n valoarea de 1 leu, 5 lei, 10 lei, 50 lei, 100 lei i 500 lei.

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