Explorați Cărți electronice
Categorii
Explorați Cărți audio
Categorii
Explorați Reviste
Categorii
Explorați Documente
Categorii
=
=
= =
rest n b), mod a cmmdc(b,
0 b dac a,
0 a dac b,
0 b si 0 a dac exist, nu
var a,b,c: integer;
function cmmdc(x,y:integer):integer;
begin
if (x=0) and (y=0) then cmmdc:=0
else if y=0 then cmmdc:=x
else if x=0 then cmmdc:=y
else cmmdc:=cmmdc(y,x mod y)
end ;
begin
write(`a= );
readln(a);
write(`b= );
readln(b);
c:=cmmdc(a,b);
if c=0 then writeln (`cmmdc(0,0) nu este definit)
else writeln(cmmdc(`, a,,,b,)= ,c);
readkey
end.
6. Se citete de la tastatur un numr natural n>0. S se
afieze, utiliznd recursivitatea, descompunerea lui n n factori
primi.
Vom scrie un subprogram recursiv, care primind ca
argument un numr natural K, determin cel mai mic divizor al
su precum i puterea la care acest divizor apare n cadrul
descompunerii n factori primi. Apoi, subprogramul se va apela
recursiv pentru numrul obinut prin mprirea lui k la
numrul obinut prin ridicarea la putere a divizorului la factorul
lui.
var n,s: integer;
procedure descompunere(k:integer);
var divizor, putere: integer;
begin
if k>1 then
begin
divizor:=s+1;
while k mod divizor <>0 do
divizor:=divizor+1;
putere:=0;
while k mod divizor=0 do begin
putere:=putere+1;
k:=k div
divizor;
end;
writeln(divizor, ^ `,putere);
s:=divizor;
descompunere(k);
end;
end;
begin
write(`n= );
readln(n);
s:=1;
if n<>1 then descompunere(n)
else write(n);
readkey
end.
7. S se scrie un subprogram recursiv care calculeaz C
k
n
,
utiliznd formula de recuren:
C
k
n
=
rest in , C + C
1 = k dac n,
0 = k dac 1,
1 - k
1 - n
k
1 - n
var n,k: longint;
function comb(n,k:longint):longint;
begin
if k=0 then comb:=1
else if k>n then comb:=0
else comb:=comb(n-1,k)+comb(n-1,k-1)
end;
begin
write(`n= );
readln(n);
write(`k= `);
readln(k);
writeln(`comb(`,n,,,k,)= , comb(n,k));
readkey
end.
5.2. Recursivitatea n prelucrarea tablourilor
unidimensionale
1. S se scrie un subprogram recursiv care determin
minimul dintre componentele unui vector citit de la tastatur.
type vect=array[1..10] of integer;
var v:vect;
n,i: integer;
function min(a,b:integer):integer;
begin
if a>=b then min:=b
else min:=a
end;
function minvect(n:integer):integer;
begin
if n=1 then minvect:=v[1]
else if n=2 then minvect:=min(v[1],v[2])
else minvect:=min(v[n],minvect(n-1))
end;
begin
write(`Introduceti dimensiunea vectorului: `);
readln(n);
for i:=1 to n do begin
write(`v[`,i,]= );
readln(v[i]);
end;
write(`minimul este: , minvect(n));
readkey
end.
2. S se scrie un program care determin recursiv media
aritmetic a componentelor unui vector citit de la tastatur.
type vect=array[1..10] of real;
var v:vect;
n,i:integer;
function suma(k:integer):real;
begin
if k=1 then suma:=v[1];
else suma:=v[k]+suma(k-1);
end;
begin
write(`Intoduceti dimensiunea vectorului: );
readln(n);
for i:=1 to n do begin
write(`v[`,i,]= );
readln(v[i]);
end;
writeln(`Media aritmetica a elementelor vectorului este: ,
(suma(n)/n):6:2);
readkey
end.
3.S se scrie un program care determin recursiv
produsul scalar a doi vectori de numere intregi citii de la
tastatur.
type vect=array[1..10] of longint;
var a,b:vect;
n,i:integer;
function prods(k:integer):longint;
begin
if k=n then prods:=a[n]*b[n]
else prods:=a[k]*b[k]+prod(k+1);
end;
begin
write(`Introduceti dimensiunea vectorilor: )
readln(n);
for i:=1 to n do begin
write(`a[`,i,]= );
readln(a[i]);
end;
writeln;
for i:=1 to n do begin
write(`b[`,i,]= );
readln(b[i]);
end;
writeln(`Produsul scalar al vectorilor a si b este: , prods(1));
readkey
end.
4. S se scrie un program care caut existena unui
element x citit de la tastatur ntr-un sir ordonat cresctor,
folosind metoda cutrii binare.
Ideea implementrii metodei cutrii binare este
urmtoarea:
- se compar elementul x cu elementul din mijloc al
irului;
- dac ele sunt egale, s-a gsit elementul cutat i
algoritmul se ntrerupe;
- dac elementul x este mai minc dect cel din mijloc,
vom relua cutarea pentru prima parte a irului;
- dac este mai mare, cutarea se va face numai n
partea dreapt a irului fa de elemntul din mijloc.
Type vect=array[1..20] of integer;
Var v:vect;
poz,x,n,i:integer;
function cautbin(inc,sf:integer):integer;
var mij:integer;
begin
if inc<=sf then begin
mij:=(inc+sf) div2;
if x=v[mij] then cautbin:=mij;
else if x<v[mij] then
cautbin:=cautbin(inc,mij-1)
else
cautbin:=cautbin(mij+1,sf)
end;
else cautbin:=0;
end;
begin
writeln(`Introduceti elementul cautat: `);
readln(x);
write(`Introduceti dimensiunea vectorului: );
readln(n);
for i:=1 to n do begin
write(`v[`,i,]= );
readln(v[i]);
end;
poz:=cautbin(1,n);
if poz=0 then
writeln(`Elementul `,x, nu se afla in sir)
else writeln (`Elementul `,x, se gaseste in sir pe pozitia:
,poz);
readkey
end.
5. S se rezolve recursiv problema punctului fix: fiind
dat un vector ordonat de numere ntregi distincte, s se
determine un indice m (1<=m<=n), cu v[m]=m, dac este
posibil.
Vom folosi ideea problemei anterioare: determinm m
mijlocul vectorului i verificm dac v[m]>m, cum vectorul
este ordonat cresctor, vom efectua cutarea n stnga, altfel
n dreapta.
type vect=array[1..20] of integer;
Var v:vect;
poz,n,i:integer;
function cautbin(inc,sf:integer):integer;
var mij:integer;
begin
if inc<=sf then begin
mij:=(inc+sf) div2;
if x=v[mij] then cautbin:=mij;
else if x<v[mij] then
cautbin:=cautbin(inc,mij-1)
else
cautbin:=cautbin(mij+1,sf)
end;
else cautbin:=0;
end;
begin
write(`Introduceti dimensiunea vectorului: );
readln(n);
for i:=1 to n do begin
write(`v[`,i,]= );
readln(v[i]);
end;
poz:=cautbin(1,n);
if poz=0 then writeln(`Sirul nu admite punct fix)
else writeln(`Punctul fix se gaseste in sir pe pozitia ,poz);
readkey
end.
5.3. Alte probleme ce utilizeaz recursivitatea
1. Se citesc n,A1,r (numere naturale). S se calculeze
suma A1!+A2!+A3!+...+An!, unde A1,A2,.,An reprezint
termeni ai progresiei aritmetice cu prim termen A1 i raie r,
iar K!=1*2*3*.*k.
Se folosesc urmtoarele funcii recursive:
- function A(n#inte"er)#inte"er- calculeaz termenul n al
progresiei aritmetice.
- function fact(n#inte"er)#lon"int) calculeaz n!.
- function suma(n#inte"er)#inte"er) calculeaz suma
primilor n termeni din irul cerut.
Toate sunt funcii pentru care nainte de implementare se
caut o relaie de recuren pentru funcia A.
var n,a1,r :integer;
function A(n:integer):integer;
begin
if n=1 then A:=A1
else A:=A(n-1)+r;
end;
function fact(n:integer):longint;
begin
if n=1 then fact:=1
else fact:=n*fact(n-1);
end;
function suma(n:integer):longint;
begin
if n=0 then suma:=0
else suma:=fact(A(n))+suma(n-1);
end;
begin
readln(n,A1,r);
writeln(suma(n));
end.
2. Se d un numr natural n. S se scrie n ca sum de
numere prime. Obs! 1 se va considera numr prim.
var a,x:array[0..100] of integer ;
n,I,s,m: integer;ok:boolean;
function prim(n:integer):boolean;
var i:integer;
begin
prim:=true;
for i:=2 to trunc(sqrt(n)) do
if n mod i=0 then
begin
prim:=false;break;
end;
end;
procedure tipar (k:integer);
var i:integer;
begin
for i:=1 to k do
write(a[x[i]]);
writeln;
end;
procedure back(k:integer);
var i:integer;
begin
for i:=x[k-1]+1 to n do
begin
x[k]:=I; s:=s+a[x[k]];
if s<=n then
if s=n then
tipar(k)
else
back(k+1);
s:=s-a[x[k]];
end;
end;
begin{main}
write(`n= );readln(n);
m:=0;
for i:=1 to n do
if prim(i) then
begin
inc(m);
a[m]:=i;
end;
x[0]:=0;s:=0;
back(1);
readln;
end.
3. Se d un alfabet care conine v vocale i c consoane. S
se genereze toate cuvintele de lungime n care nu conin trei
vocale sau trei consoane alturate.
Vocalele i consoanele alfabetului vor fi memorate n
vectorul a. Primelev elemente reprezint vocalele, urmtoarele
c elemente consoanele. Vectorul soluie x=(x1,x2,.,xn) va
avea ca valori indicii elementelor din a iar elementele sale vor
lua valori din multimea {1,.,v+c}. Vocalele vor fi elemente din
a din pozitiile {1,.,v} , iar consoanele elementele din a din
pozitiile {v+1,.,v+c}.
Var x:array[1..20] of integer;
n,i,v,c,m:integer;
a:array[1..20] of char;
car:char;f:text;
function cont (k:integer):boolean;
var i:integer;
begin
cont:=true;
if k>2 then
if (x[k]<=v) then
begin
if (x[k-1]<=v) and (x[k-2]<=v) then
cont:=false;
end
else
if (x[k-1]>v) and (x[k-2]>v) then
cont:=false;
end;
procedure tipar;
var i:integer;
begin
for i:=1 to n do
write(a[x[i]]);
writeln;
end;
procedure back(k:integer);
var i:integer;
begin
for i:= 1 to v+c do
begin
x[k]:=1;
if cont(k) then
if k=n then
tipar
else
back(k+1);
end;
end;
begin
assign(f,date.in);
reset(f);
readln(f,n);
readln(f,v);
m:=0;
for i:=1 to v do
begin
read(f,car);inc(m);a[m]:=car;
end;
readln(f,c);
for i:=1 to c do
begin
read(f,car);inc(m);a[m]:=car;
end;
close(f);
back(1);
readln;
end.
4. Se consider n soldai numerotai de la 1 la n. Se citesc
de la intrare k perechi de numere (i,j) cu i<>j, 1<=i<=n,
1<=j<=n, cu semnificatia ca i este superiorul lui j. se cere sa
se aseze soldatii intr-un rand, in mod ierarhic, astfel incat
fiecare soldat sa aiba subalternii sai situati dupa el.
Exemplu : pentru n=6, k=4 si perechile (1,5), (4,5),
(2,3), (1,4), iesirile posibile sunt : 1 2 4 6 3 5, 2 1 4 5 3, .
Pentru a reprezenta relatiile existente intre soldati se va
folosi un tablou bidimensional n x n, ale carui elemente a[i,j]
vor avea valorile 1 daca i este superiorul lui j, 0 in caz contrar.
Vectorul solutie va fi x=(x1,x2,.,xn), x[k] reprezinta
codificarea unui soldat, iar lementele sale or lua valori din
multimea {1,.,n}. Un element x[k] este valid daca sunt
indeplinite urmatoarele conditii de continuare :
- este diferit de toate valorile determinate anterior
x[k]<>x[i], i={1,.,k-1}
- nici un element anterior x[i] nu trebuie sa fie subaltern
lui x[k]: a[x[k],x[i]]<>1, i={1,.,k-1}
var a:array[1..20,1..20] of integer;
x,viz:array[1..20] of integer;
i,n,k,p,j:integer;f:text;
Function cont(k:integer):boolean;
Var i:integer;
Begin
Cont:=true;
for i:=1 to k-1 do
if a[x[k],x[i]]=1 then begin cont:=false;exit:end;
end;
procedure tipar;
var i:integer;
begin
for i:=1 to n do
write(f,x[i]);
writeln(f);
end;
5. La un concurs sunt prezentate 5 melodii notate
A,B,C,D,E. Sa se afiseze toate posibilitatile de a prezenta cele 5
melodii in ipoteza ca melodia B va fi prezentata inaintea lui A.
Melodiile vor fi codificate prin numere de la 1 la 5.
Elementele vectorului solutie x=(x1,x2,x3,.,x5) vor lua valori
din multimea {1,2,.,5}. Vectorul solutie trebuie sa aiba toate
elementele distincte, valoarea 2 trebuie sa fie in vector
inaintea valorii 1. Astfel, conditiile de continuare sunt
indeplinite daca :
- x[k]<>x[i], i={1,.,k-1}
- daca x[k]=2 atunci x[i]<>1, i={1,.,k-1}
Elementele vectorului solutie vor lua valori din multimea
{`A,B,C,D,E}. Vectorul viz tine evidenta valorilor utilizate.
Viz[i]=0 indica faptul ca valoarea I nu a fost utilizata.
var x:array[1..5] of char;
viz:array[`A..E]
of integer;
procedure tipar;
var i:integer;
begin
for i:= 1 to 5 do
write (x[i]);
writeln;
end;
function cont(k:integer):boolean;
var i:integer;
begin
cont:=true;
if x[k]=B then
for i:=1 yo k-1 do
if x[i]=A then begin cont:=false;brek;end;
end;
procedure back(k:integer);
var i:char;
bagin
for i:= `A to `E do
begin
x[k]:=i;
if viz[i]=0 then
if cont(k) then
begin
viz[i]:=1;
if k=5 then tipar
else
back(k+1);
viz[i]:=0;
end;
end;
end;
begin
back(1);
readln;end.
6. Sa se scrie un program care, citind in cuvant si un
numar natural cuprins intre 1 si lungimea cuvantului sa se
afiseze toate anagramarile obtinute din acest cuvant, dupa
eliminarea literei de pe pozitia citita.
var x,viz:array[1..10] of integer;
cuv:string;p:integer;
procedure tipar;
var i:integer;
bagin
for i:=1 to length(cuv) do
writw(cuv[x[i]]);
writeln;
end;
procedure back(k:integer);
var i:integer;
begin
for i:=1 to length(cuv) do
if viz[i]:=0 then
begin
x[k]:=i;
viz[i]:=1;
if k=length(cuv) then
tipar
else
back(k+1);
viz[i]:=0;
end;
end;
begin
write(`dati cuvantul); readln(cuv);
reapeat
write(`pozitia:);readln(p);
until p in [1..length(cuv)];
delete(cuv,p,1);
back(1);
readln;
end.
7. Figuri recursive
Dup cum am mai spus, recursivitatea are o mare arie de
ntrebuinare i de aplicabilitate. n continuare, voi prezenta o
folosire a recursivitii n grafica de sub Borland Pascal prin
ncercarea de realizare a unor ,figuri recursive.
O astfel de figur recursiv este cea pe care o prezint mai
jos.
Aceast figur o voi numi ,diamant. Observm forma
recursiv a acestui diamant. El este perfect caracterizat de
coordonatele centrului su, precum i de latura ptratului
iniial. Ptratele imediat urmtoare, au laturile de c ori mai
mici, unde c este o constant real oarecare, cl1. De fapt,
acest diamant se constituie dintr-un ptrat de centru (x,y) i
de latur l i dintr-un cerc cu acelai centru ca ptratul iar raza
egal cu diferena dintre latura ptratului i jumtate din
diagonala sa. Ptratul are patru diamante n colurile sale.
Aceasta este o definiie recursiv a diamantului.
Astfel, vom putea scrie cu uurin o procedur care s-l
deseneze. Aceast procedur va desena un ptrat i un cerc,
care au acelai centru, apoi se va autoapela de patru ori,
pentru cele patru diamante din colurile ptratului. Trebuie s
existe, ns, i o condiie de oprire deoarece programul ar afia
diamante din ce n ce mai mici de un numr infinit de ori, i
astfel s-ar depi stiva de memorie cu care lucreaz Borland
Pascal. De aceea vom introduce o condiia ca diamantele s fie
desenate atta timp ct latura ptratului este mai mare strict
dect 0.
n program am folosit directivele de compilare {$S-} -
pentru a face compilatorul s nu in seama de depirea
stivei, i {$S+} - pentru a reveni la controlul normal al
umplerii stivei.
Voi prezenta mai jos programul cu ajutorul cruia am
realizat desenul anterior, cu precizarea c singurele proceduri
grafice pe care le-am folosit sunt: Line i Circle. Nu voi insista
asupra utilizrii graficii n Borland Pascal. Iat programul:
program FiguraRecursiva;
var mg,er,d:integer;
procedure patratcerc(x,y,l:integer);
var l2:integer;
begin
l2:=round(l/sqrt(2));
line(x-l2,y,x,y-l2);
line(x,y-l2,x+l2,y);
line(x+l2,y,x,y+l2);
line(x,y+l2,x-l2,y);
circle(x,y,l-l2);
end;
{$S-}
procedure diamant(x,y,l:integer);
const c=2.7;
var l2,l3:integer;
begin
if l>0 then begin
patratcerc(x,y,l);
l2:=round(l/sqrt(2));
l3:=round(l/c);
diamant(x-l2,y,l3);
diamant(x,y+l2,l3);
diamant(x+l2,y,l3);
diamant(x,y-l2,l3);
end;
end;
{$S+}
begin
d:=detect;
initgraph(d,mg,'c:\bp\bgi');
er:=graphresult;
if er<>grok then
begin
writeln('Eroare grafica :',grapherrormsg(er));
halt;
end;
setcolor(blue);
setbkcolor(white);
diamant(GetMaxX div 2, GetMaxY div 2, GetMaxY div 3);
readln;
closegraph;
end.
Dac am prezentat o aplicaie grafic a recursivitii
directe, trebuie s prezentm i o aplicaie a recursivitii
indirecte, realizat cu ajutorul cuvntului cheie forward, despre
care am vorbit n capitolele anterioare.
i aceast aplicaie se nscrie n seria ,figurilor recursive,
i ilustreaz totodat lucrul cu mouse-ul n modul grafic, dar nu
voi insista asupra acestui lucru. Precizez doar faptul c n
program se folosete un unit pentru lucrul cu mouse-ul, unit ce
cuprinde unele proceduri realizate n limbaj de asamblare
(procedurile init, show, clear, done, getx, gety, etc.).
Astfel aciunea mouse-ului este urmtoarea: la apsarea
butonului drept se va afia o figur recursiv, iar la apsarea
celuilalt buton, alt figur recursiv.
Un posibil rezultat al programului pe care-l voi prezenta
este urmtorul:
n acest exemplu am folosit de trei ori butonul drept al
mouse-ului i de patru ori pe cel stng. Se observ c acest
diamant este o figur geometric (un cerc ori un ptrat) care
are la capetele unui diametru, respectiv unei diagonale, cte
un alt diamant care este de acelai tip cu el, iar la capetele
diametrului perpendicular pe el, respectiv a celeilalte
diagonale, cte un diamant care nu este de acelai tip cu el
(diamantul realizat la apsarea celuilalt buton al mouse-ului).
Programul este urmtorul:
program DesenareCuMouse;
const n1=0;ns=1;nd=2;nt=3;
var am:tmouse;
x,y:integer;
d,mg,er:integer;
procedure romb(x,y,l:integer);
var l2:integer;
begin
l2:=round(l/sqrt(2));
line(x-l2,y,x,y-l2);
line(x,y-l2,x+l2,y);
line(x+l2,y,x,y+l2);
line(x,y+l2,x-l2,y);
end;
procedure diamantcercuri(x,y,l:integer); forward;
procedure diamantromburi(x,y,l:integer);
const c=2.3;
var l2,l3:integer;
begin
if l>0 then begin
romb(x,y,l);
l2:=round(l/sqrt(2));
l3:=round(l/c);
diamantcercuri(x-l2,y,l3);
diamantromburi(x,y-l2,l3);
diamantcercuri(x+l2,y,l3);
diamantromburi(x,y+l2,l3);
end;
end;
procedure diamantcercuri(x,y,l:integer);
const c=3;
var l2,l3:integer;
begin
if l>0 then begin
circle(x,y,l);
l2:=round(l/sqrt(2));
l3:=round(l/c);
diamantromburi(x-l2,y,l3);
diamantcercuri(x,y-l2,l3);
diamantromburi(x+l2,y,l3);
diamantcercuri(x,y+l2,l3);
end;
end;
{$S+}
begin
d:=detect;
initgraph(d,mg,'c:\bp\bgi');
er:=graphresult;
if er<>grok then
begin
writeln('Eroare grafica :',grapherrormsg(er));
halt;
end;
setcolor(blue);
setbkcolor(white);
am.init;
am.show;
repeat
x:=am.getx;
y:=am.gety;
if am.leftbutton then begin
am.clear;
diamantcercuri(x,y,50);
am.show;
end;
if am.rightbutton then begin
am.clear;
diamantromburi(x,y,50);
am.show;
end;
until (am.leftbutton and am.rightbutton) or keypressed;
end.
Cristea Valentin, Atanasiu Irina, Iorga Valeriu,
Kalis !ugenia " ,,Tehnici de programare, !ditura
#eora, $ucure%ti & '(()*
+iculescu ,te-an, Cerc.e !manuela"
Bacalaureat i atestat n informatic, !ditura /01
In-ormat, $ucure%ti & '(((*
Cre2u Vladimir Ioan, 3odica 4intea " Culegere
de probleme Pascal !ditura 4etrion, #imi%oara &
'((5 *
6oina 3ancea" imba!ul Pascal, 7ol I %i II
!ditura /ibris, Clu8 9 '(()*
Carmen 4o:escu" Culegere de probleme de
informatic, !ditura 6onaris, 1ibiu 9 5005
#udor 1orin" ;Tehnici de programare< !ditura
#eora, $ucure%ti 9 '(()*