Documente Academic
Documente Profesional
Documente Cultură
SPORTULULUI
COLEGIUL TEHNIC MTSARI
ATEST
AT
PROF
ESION
AL
PROF. COORDONATOR:
SCEANU ION
ELEV:
Voica Cornelia
Alexandra
Clasa a XII-a B
Profil: Matematic-informatic
Colegiul Tehnic Mtsari
2015-
RECU
RSIVI
TATE
PROF. COORDONATOR:
SCEANU ION
ELEV:
Voica Cornelia
Alexandra
CLASA a XII-a B
Profil: Matematic-informatic
Colegiul Tehnic Mtsari
2015-
CUPRINS:
1. Aspecte
teoretice1
2. Proceduri
recursive7
3. Funcii recursive
.14
4. Backtracking recursiv.
..20
5. Funcii Forward. Referine
forward..22
6. Probleme
recursive...25
7. Figuri
recursive...44
8. Bibliografie
50
Recursivitate
1.Aspecte teoretice
1.1 Ce este recursivitatea?
Recursivitatea, folosit cu mult eficien n matematic, s-a impus n
programare, odata cu apariia unor limbaje de nivel inalt, ce permit scrierea de
module ce se autoapeleaz (PASCAL,LISP,ADA,ALGOL,C sunt limbaje
recursive, spre deosebire de FORTRAN,BASIC,COBOL, nerecursive).
Recursivitatea e strns legat de iteratie, dar dac iteratia e execuia
repetat a unei poriuni de program, pn la ndeplinirea unei conditii (while,
repeat, for din PASCAL), recursivitatea presupune executia repetata a unui
modul, insa n cursul executiei lui (i nu la sfrsit, ca n cazul iteratiei), se
verifica o conditie a crei nesatisfacere, implica reluarea executiei modulului de
la inceputul sau. Atunci un program recursiv poate fi exprimat: P=M(i,P) ,
unde M este multimea ce contine instructiunile i i pe P insusi.
Structurile de program necesare i suficiente n exprimarea recursivitii
sunt procedurile i subrutinele ce pot fi apelate prin nume.
Recursivitatea poate fi:
begin
if n=1 then fact:=1
else fact:=n*fact(n-1)
end;
Demonstrarea corectitudinii cuprinde doi pai:
-pentru n=1 valoarea 1 ce se atribuie factorialului este corect
-pentru n>1, presupunnd corect valoarea calculat pentru predecesorul lui n
de fact(n-1), prin nmulirea acesteia cu n se obine valoarea corect a
factorialului lui n.
prel_car
end.
program var_nerecursiv;
begin
*iniializeaz stiv
while not eoln do
begin
read(car);
push(car)
end;
while not stiva_goal do
begin
pop(car);
write(car)
end
end.
1.5 Exemple de algoritmi recursivi
begin
if element <> ultimul_din_structura then
traversare(element_urmtor);
prelucrare(element)
end;
De observat important ca parametrul formal al celor dou proceduri s fie de
tip valoare, pentru a nu fi alterat de apelul recursiv.
2. Proceduri recursive
Procedurile de asemenea pot fi recursive. Ca un exemplu considerm
algoritmul pentru transformarea ntregilor zecimali n numere binare. Astfel, lui
(13)10 i corespunde (1101)2
PROCEDURE flipcar;
{Inverseaza recursiv caracterele pn la eoln}
VAR ch:char;
BEGIN
read(ch);
IF eoln THEN write(ch) ELSE
BEGIN {pasul inductiv}
flipcar;
write(ch)
END
END {flipcar};
BEGIN {principal}
WHILE NOT eof DO
BEGIN
writeln('Introduceti o propozitie pe o singura linie de input');
flipcar;
writeln
END
END {tipar}.
Rezultatele execuiei programului:
Input
AFARA PLOUA LINISTIT
UNIVERSITATEA DE VEST ESTE N TIMISOARA
AM FOST N BUCURESTI
Output
TITSINIL AUOLP ARAFA
ARAOSIMIT NI ETSE TSEV ED AETATISREVINU
ITSERUCUB NI TSOF MA
MOVE(4,1,3,2);
{Mut 4 discuri de la acul 1 la 3 prin intermediul acului 2}
Writeln('Muta un disc de la acul 1 la acul 3');
MOVE(4,3,2,1);
{Mut 4 discuri de la acul 3 la acul 2 prin intermediul acului 1 pentru a
completa soluia problemei cu 5 discuri}
Cum procedm s realizm primul i al treilea pas? Recursivitatea
direct: problema cu cinci discuri poate fi rezolvat dac soluionam problema
cu patru discuri i aa mai departe, pn la problema care nu implic nici un
Remarc!
n descrierea originala a problemei turnurilor din Hanoi se
spune ca un grup de calugari au fost... provocati s mute 64 de
discuri de aur utiliznd o platforma de alama cu trei ace de
diamant. Legendele sustin ca preotii joaca acest joc n mod
curent i ca sfrsitul jocului va nsemna sfrsitul lumii!
3. Funcii recursive
Una din cele mai simple funcii matematice este, fr ndoiala funcia
factorial.
Din moment ce (Borland) PASCAL-ul nu are o funcie (de bibliotec)
standard pentru calculul factorialului, va trebui s scriem noi una. Definirea
lui n! (se citete "n factorial") este produsul:
n x (n-1) x (n-2) x...x 3 x 2 x 1 (pentru un ntreg mai mare ca 0; 0!=1).
Aceasta definiie poate fi implementata n (Borland) PASCAL prin funcia
descris n continuare:
Exemplu:
FUNCTION fact(n:integer):integer;
VAR i,t:integer;
BEGIN
t:=1;
FOR i:=n downto 2 DO t:=t*i;
fact:=t
END {fact};
Cnd vrem s subliniem c o funcie nu este recursiv (dar ar fi putut
fi !) noi o numim funcie iterativ. Remarcai c enunul iterativ folosit (o bucl
FOR) nu este executat niciodat pentru n mai mic ca 2 - funcia returneaz
valoarea 1 att pentru 1! ct i pentru 0!. Variabil de control al buclei (i) ia
valori pn la 2, nu pn la 1 pentru a evita o nmulire inutil cu 1 n final.
Variabil (de stare) t este necesar pentru a evita folosirea lui fact (numele
funciei) n partea dreapt a enunului de atribuire t:=t*i. Compilatorul
(Borland) PASCAL se ateapt ca un nume de funcie s apar numai n partea
dreapt a enunului de atribuire, acela care leag numele funciei de o valoare
particular. Iat n exemplul urmtor o alternativ de definire a lui n! care este
mai degrab recursiva dect iterativa.
ce face ca fact s fie o funcie recursiv este prezena lui fact (n-1) n membrul
drept al enunului fact:=n*fact (n-1). Asocierea lui fact cu argumentul n-1,
presupune c atunci cnd implicm funcia fact, ea se va apela pe ea nsi.
Aa cum a trebuit s nvm cum s scriem bucle care se termin
dup un numr finit de iteraii, trebuie s nvm s construim funcii
recursive care se termin cu succes dup o serie finit de referiri la sine.
nvarea modului de folosire a recursivitii este mai important dect
nelegerea modului cum lucreaz. Prezentm dou reguli simple, dar eseniale.
Reguli:
1) Orice funcie sau procedura recursiv trebuie s aib cel puin o
bootstrap condition, care specific rspunsul corect sau aciunea pentru cea
mai simpl situaie imaginabil, n general una corespunztoare celei mai mici
valori parametru (cea de final);
2) Orice funcie sau procedura recursiv trebuie s aib un pas inductiv
(inductive step) care leag problem ce trebuie rezolvat de cea mai simpl
versiune.
Pentru funcia factorial (fact recursiv), bootstrap condition este 0!=1,
iar inductive step (pasul inductiv) leag pe n! de (n-1)! care rmne nchis la
bootstrap.
La prima vedere, funcia factorial - fact recursiva pare s aib nevoie de
mai puin memorie dect omoloaga s nerecursiva deoarece este folosit
variabil nontemporara (stare) t, dar aceasta este o iluzie. n spatele ... scenei,
o rutin recursiv trebuie s salveze una sau mai multe valori intermediare ori
de cte ori ea se apeleaz pe ea nsi. Ea salveaz aceste valori n form de
stack, o structur de date n care ultimul item salvat este primul ce poate fi
rechemat.
Remarc!
Alte nume pentru stack sunt pushdown stack i lifo list (lifo este
prescurtarea de la "last n, first ou").
Alt posibil operaie recursiv este an - a ridicat la puterea n (unde n
>= 0).
Ceea ce urmeaz este o soluie nerecursiva, bazat pe multiplicarea lui a cu el
nsui de n ori.
FUNCTION putere (a:real; n:integer):real;
{O funcie iterativ pentru calculul lui a la puterea n}
VAR t:real;
i:integer;
BEGIN
t:=1;
FOR i:=1 TO n DO t:=t*a;
putere:=t
END {putere};
Pentru n=0, bucla FOR nu se va executa, genernd a0=1, valoare evident
corect. Pentru n>=1, t devine n ordine a, a2, a3 i tot aa pn la an.
Definirea recursiv a lui an este:
IF n=0 THEN an:=1; unde an =a*an-1
Condiia bootstrap este a0=1. Pasul inductiv (inductive step) an=a*an-1,
leag problem general an de problema an-1, care rmne pe loc la bootstrap.
Traducerea (Borland) PASCAL a acestei definiii este ilustrata n
secvena urmtoare:
FUNCTION putere (a:real; n:integer):real;
BEGIN
IF n=0 THEN putere:=1
ELSE putere:=a*putere(a,n-1)
END {putere};
Exist ceva dezorganizat n ambele versiuni ale lui putere. Ai calculat
a , fcnd 15 nmuliri ? Probabil c nu; ai observat c a16 =(a8)2 i c a8
=(a4)2 i tot aa mai departe. Astfel, n realitate avem nevoie de 4 nmuliri
pentru a calcula a16. Evident, aceasta njumtire maxim nu va lucra la fel,
dac n este impar. n consecin, un algoritm recursiv mbuntit trebuie s fie
structurat astfel:
16
Pentru valori mari ale lui n, aceast versiune a lui putere folosete mai
degrab un numr de nmuliri egal cu log2n dect cu n-1, ca n versiunea
precedenta. Pentru n=64, unde log264=6, aceasta reprezint o economie
nzecita.
Observaie!
Remarcai c ntruct exista o mic diferen ntre numrul de enunuri
(Borland) PASCAL folosite pentru versiunile recursiva, respectiv iterativa ale
lui fact sau pentru primele dou versiuni (ineficiente) ale lui putere, este pe
undeva prea dificil s recodificam versiunea eficient a lui putere fr a folosi
recursivitatea.
Implementarea recursiv a unui algoritm este adesea mult mai natural
i mult mai lizibila dect implementarea iterativ echivalent.
Unul dintre cei mai cunoscui algoritmi este algoritmul lui Euclid, care
calculeaz cel mai mare divizor comun (gcd) a doi ntregi pozitivi, nenuli m i
n. De exemplu, dac m este 45 i n este 30, c.m.m.d.c. al lor este 15; dac m
este 8 i n este 12, atunci c.m.m.d.c. este 4.
Pentru a calcula c.m.m.d.c. reamintim algoritmul lui Euclid. Dac m=n,
atunci c.m.m.d.c. este m (sau n); n caz contrar, se nlocuiete numrul mai
mare cu diferena celor dou numere i procesul se repet.
Funcia iterativ (Borland) PASCAL care corespunde acestei definiii
este ilustrat de:
FUNCTION gcd1(m,n:integer):integer;
BEGIN
WHILE m<>n DO
IF m>n THEN m:=m-n
ELSE n:=n-m;
gcd1:=m
END {gcd1};
Versiunea recursiv, cu aceeai logic, este prezentat n continuare:
FUNCTION gcd2(m,n:integer):integer;
BEGIN
IF m=n THEN gcd2:=m ELSE
IF m>n THEN gcd2:=gcd2(m-n,n)
ELSE gcd2:=gcd2(m,n-m)
END {gcd2};
Remarc!
Cele dou versiuni sunt foarte ineficiente cnd diferena dintre m i n
este mare , deoarece determina un numr considerabil de scderi succesive pn
4. Backtracking recursiv
n acest capitol prezentm rutin de backtracking recursiv. Procedurile i
funciile folosite sunt n general aceleai ca la backtracking, cu dou mici
excepii:
-SUCCESOR nu mai este procedura ci funcie booleana ;
-rutina backtracking se transform n procedura,care se
apeleaz prin BACK(1)
Principiul de funcionare al procedurii BACK,corespunztor unui nivel k
este urmtorul:
-in situaia n care avem o soluie,o tiprim i revenim pe nivelul anterior
-in caz contrar se iniializeaz nivelul i se cauta un succesor
-cand am gsit unul verificm dac este valid;procedura se autoapeleaza
pentru (k+1) , n caz contrar urmnd a se continua cutarea succesorului;
-daca nu avem succesor,se trece pe nivel inferior (k-1) prin ieirea din
procedur BACK
Vom explica n continuare utilizarea backtrackingului recursiv prin
generarea permutrilor:
type stiv=array[1..9] of integer;
var st:stiv;
ev:boolean;n,k:integer;
procedure init(k:integer;var st:stiv);
begin
st[k]:=0;
end;
Pentru valori mici ale lui x este aproape adevrat c sin x i cos x au
valorile definite de primii doi termeni: (x-x3/6), respectiv 1-x2/2 dintr-o serie
infinit.
sinx @ x-x3/6
cosx @ 1-x2/2
Ne ntrebam: ct de mic trebuie s fie x pentru a ne permite nou s ne
bazm pe aceste aproximaii. Aceasta depinde de ct de multe zecimale ne vom
atepta la rspunsurile date. Un matematician ne-ar rspunde c pentru x < 0.02
aproximarea lui cos x poate fi fcut cu 8 zecimale, iar pentru sinx este chiar
mai bun.
n rutinele pe care le vom prezenta, valorile mai mici dect 0.02 i 0.01
servesc ca bootstrap-uri i sunt numite epsilon. n fiecare rutin epsilon este
declarat c o constant astfel nct valoarea s poate fi uor modificat, n
funcie de experiment .
Impedimentul final l constituie situaia "chicken-and-egg" (gaina-i-oul)
referitoare la ordinea relativ a lui sine i cosine din interiorul codului sursa.
Din fericire, un pas de compilare n (Borland) PASCAL cere ca numai o
procedur sau o funcie s poat fi alimentate cu elementele pentru header-ul
rutinii apelate.
Cnd este definit un asemenea header, includerea cuvntului rezervat
forward va anuna compilatorul (Borland) PASCAL ca ntreg corpul logic al
rutinei mpreuna cu toate declaraiile sale vor aprea mai trziu n program. n
cazul nostru, vom scrie urmtorul header:
FUNCTION cosine(x:real): real; forward;
dup care vom proceda la fel pentru funcia sine.
FUNCTION cosine(x:real):real;forward;
FUNCTION sine(x:real):real;
Prezentm n cele ce urmeaz funciile mutuale complet recursive cosine
i sine:
FUNCTION cosine(x:real):real;forward;
FUNCTION sine(x:real):real;
CONST epsilon=0.01;
BEGIN
IF abs(x)<epsilon THEN sine:=x*(1-x*x/6)
ELSE sine:=2*sine(x/2)*cosine(x/2)
END {sine};
FUNCTION cosine(x:real):real;
CONST
epsilon=0.02;
BEGIN
IF abs(x)<epsilon THEN cosine:=1-x*x/2
ELSE cosine:=sqr(cosine(x/2))-sqr(sine(x/2))
END {cosine};
5. Probleme recursive
5.1. Recursivitatea n prelucrarea datelor elementare
1. S se scrie un subprogram recursiv care apelat ntr-un program
principal s conduc la afiarea urmtorului triunghi de stelue, pentru citirea de
la tastatur a valorii n=4.
*
**
***
****
var n:integer;
procedure rec(k:integer);
var i: integer;
begin
if k=n then for i:=1 to k do write(* )
else begin
for i:=1 to k do write(* );
writeln;
rec(k+1)
end;
end;
begin {pp}
write(n= );
readln(n);
rec(1);
readkey
end.
2.S se scrie un program care s utilizeze recursivitatea i care pentru
citirea de la tastatur a valorii n=5, s afieze urmtorul triunghi de numere:
5
45
345
2345
12345
var n: integer;
procedure tiplinie(l:integer);
begin
if l=1 then write(n-l+1, )
else begin
write(n-l+1, );
tiplinie(l-1);
end
end ;
procedure rec(k:integer);
begin
if k=n then tiplinie(n)
else begin
tiplinie(k)
writeln;
rec(k+1)
end
end;
begin{pp}
write(n= );
rec(1);
readkey
end.
3. Se citesc de la tastatur coeficienii reali a,b,c,d, a0 ai ecuaiei: ax?
+bx?+cx+d=0. Notm cu x1,x2,x3 rdcinile acestei ecuaii. Pentru un n natural
i strict pozitiv citit de la tastatur, s se scrie un program ce utilizeaz
recursivitatea pentru calculul sumei: Sn= x1n+x2n+x3n
S0=x10+x20+x30=3
S1=x1+x2+x3= -b/a
S2=x12+x22+x32= (x1+x2+x3)2-2(x1x2+x1x3+x2x3)=S12-2c/a
function s(k:integer):real;
begin
if k=0 then s:=3
else if k=1 then s:=-b/a
else if k=2 then s:= sqr(b)/sqr(a)-2*c/a
else s: =-b/a*s(k-1) - c/a*s(k-2) - d/a*s(k-3);
end;
begin {pp}
write(a= );readln(a);
write(b= );readln(b);
write(c= );readln(c);
write(d= );readln(d);
write(n= );readln(n);
writeln(Suma este: , s(n):6:3);
readkey
end.
4. Se citete de la tastatur un numr natural ce va fi memorat ntr-o
variabil de tipul longint. Se cere s se scrie un subprogram recursiv care s
afieze numrul format cu cifrele sale inversate.
var n:longint ;
procedure invers(k:longint);
begin
if k<>0 then begin
write (k mod 10);
invers(k div 10);
end;
end;
begin
write(n= );
readln(n);
invers(n);
readkey
end.
cmmdc(a,b)=
nu exist, dac a 0 si b 0
b, dac a 0
a, dac b 0
cmmdc(b, a mod b), n rest
k
Cn ,
utiliznd
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.
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 i b este: , prods(1));
readkey
end.
4. S se scrie un program care caut existena unui element x citit de la
tastatur ntr-un ir 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 mnc 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 cutat: );
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 n sir)
else writeln (Elementul ,x, se gsete n ir pe poziia:
,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 gsete n ir pe poziia ,poz);
readkey
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.
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.
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. S se afieze toate posibilitile de a prezenta cele 5 melodii n
ipoteza c melodia B va fi prezentat naintea lui A.
Melodiile vor fi codificate prin numere de la 1 la 5. Elementele
vectorului soluie x=(x1,x2,x3,,x5) vor lua valori din mulimea {1,2,,5}.
Vectorul soluie trebuie s aib toate elementele distincte, valoarea 2 trebuie s
fie n vector naintea valorii 1. Astfel, condiiile de continuare sunt ndeplinite
dac :
- x[k]<>x[i], i={1,,k-1}
- dac x[k]=2 atunci x[i]<>1, i={1,,k-1}
Elementele vectorului soluie vor lua valori din mulimea
{A,B,C,D,E}. Vectorul viz ine evidena valorilor utilizate. Viz[i]=0
indic faptul c valoarea I nu a fost utilizat.
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. S se scrie un program care, citind n cuvnt i un numr natural
cuprins ntre 1 i lungimea cuvntului s se afieze toate anagramrile obinute
din acest cuvnt, dup eliminarea literei de pe poziia citit.
var x,viz:array[1..10] of integer;
cuv:strng;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 n [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.
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
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.