fileshare.ro sc

115

Click here to load reader

Upload: gabi

Post on 11-Dec-2015

48 views

Category:

Documents


2 download

DESCRIPTION

a

TRANSCRIPT

Page 1: Fileshare.ro SC

Topic Algoritmi si structuri de date

Algoritmi clasici

Backtracking, Divide et Impera, Greedy, Metoda programarii dinamice

Tipuri de date Lista simplu inlantuita, lista dublu inlantuita, stiva, coada,

Sortari SelectionSort, BubbleSort, InsertionSort, ShellSort, Mergesort, Quicksort

Grafuri BFS, DFS

Arbori Arbori binari

Cautari Hash table

Operatie Frecventa Notatie

Declarare variabila N+2 ~N

Asignare N+2 ~N

<, > ½(N+1)(N+2) ~ ½ N^2

== ½ N(N-1) ~ ½ N^2

Accesare elemente array

N(N-1) ~ N^2

Incrementare ½ N(N-1) pana la N(N-1)

~ ½ N^2 pana la ~ N^2

Adancime-Stiva

https://www.youtube.com/watch?v=zLZhSSXAwxI

https://www.youtube.com/watch?v=6VF2Q0pgUFI

https://www.youtube.com/watch?v=gm8DUJJhmY4

Latime-Coada

1

Page 2: Fileshare.ro SC

Preordine Radacina Stanga Dreapta , Inordine Stanga Radacina Dreapta , Postordine Stanga Dreapta Radacina

2.Recursivitate. Divide-et-impera Recursivitate

Modalitatea de gasi solutia unei probleme de dimensiune mare impartind-o in probleme dedimensiuni mai mici, dar de aceeasi forma ca problema initiala Subproblemele dintr-o solutie recursiva au aceeasi structura ca problema initiala Recursivitatea permite rezolvarea unor probleme complexe, scriind programe simple si elegante

Un exemplu simplu de recursivitatevoid CollectContributions(int n) {if (n <= 100)colecteaza banii de la unsingur donatorelse{gaseste 10 voluntarifiecare voluntar strangen/10 dolari //CollectContributions(n/10) combina banii stransi de voluntari}}

Structura unei functii recursive. Paradigma recursivitatii._ if (testeaza cazul simplu) {_ Calculeaza o solutie simpla fara recursivitate_ } else {_ Imparte problema in subprobleme de aceeasi forma_ Rezolva fiecare problema apeland recursiv functiaaceasta_ Combina solutiile subproblemelor astfel incat sa obtiisolutia problemei initiale }

2

Page 3: Fileshare.ro SC

3

Page 4: Fileshare.ro SC

4

Page 5: Fileshare.ro SC

Leap of faith_ Strategia psihologica: presupunerea ca orice apel recursiv simplu va merge corect._ Intelegerea acestei strategii este esentiala pentru aplicatiile practice_ fact(4) = 4 * fact(3)_ fact(3) este mai simplu decat fact(4), deci, presupunem ca merge corect – leap of faith

Fibonacci_ Problema reproducerii iepurilor (1202 – Leonardo Fibonacci)_ Fiecare pereche de iepuri produce o noua pereche in fiecare luna10_ Iepurii devin mai fertili in a doua luna a vietii lor_ Iepurii batrani nu mor niciodata_ Daca o pereche de iepuri nou nascuti apare in Ianuarie, cate perechi de iepuri vor fi pana

la finele anului? Calcularea numerelor Fibonacci

5

Page 6: Fileshare.ro SC

6

Page 7: Fileshare.ro SC

7

Page 8: Fileshare.ro SC

8

Page 9: Fileshare.ro SC

Cautarea binara_ Cautarea intr-un array sau vector a unui elementparticular_ De exemplu, daca lucram cu un array de string-uri near fi foarte folositoare o functie de urmatoarea forma:1ar _ int FindStringInArray(string key, string array[], int n);_ Returneaza indexul elementului egal cu key (daca sunt mai multe elemente, orice index este ok)_ Returneaza -1 daca nu a gasit niciun element egal cu key_ Algoritmul de cautare liniara – nu avem informatii cu privire la ordinea elementelor in array, astfel verificam element cu element. Strategia consuma foarte mult timp, in cazul array-urilor foarte mari._ Daca string-urile sunt asezate in ordine19 alfabetica, folosim strategia cautarii binare.Impartim array-ul in doua, comparam key cu elementul din mijloc, dupa care verificam sirul din stanga sau dreapta, in functie de caz.

Recursivitate mutuala_ Daca o functie f apeleaza o functie g, care la randul ei apeleaza functia f, apelurile functiilor sunt considerate recursive.21_ Deoarece functiile f si g se apeleaza una pe alta, acest tip de recursivitate se numesterecursivitate mutuala._ Sa testam daca un numar este par sau impar.

9

Page 10: Fileshare.ro SC

_ Daca limitam cautarea la multimea numerelor naturale, atunci numerele pare si impare pot fi caracterizate astfel:_ Predecesorul unui numar par este un numar impar._ Un numar este par, daca nu este impar.22_ Numarul 0 este par prin definitie.

Sa gandim recursiv!_ Reductionism - un obiect poate fi inteles prin intelegerea partilor sale componente_ Holism – un obiect intreg este mai mare decat suma partilor sale componente (recursivitate)24_ Cand scrii un program recursiv trebuie sa ignore detaliile apelurilor recursive._ Cand programul recursiv nu merge, cauta in eroarea in implementare recursiva, nu in mecanismul recursiv!Checklist pentru gasirea erorii_ Incepe programul recursiv cu cazul simplu? (programul trebuie sa inceapa cu if)_ Ai rezolvat cazul simplu corect? (daca ai scris fact(0) = 0 si nu fact(0) = 1, tot programul va merge prost)_ Descompunerea recursiva simplifica problema? (ai grija sa nu scrii o bucla infinita)_ Apelurile recursive sunt subprobleme de aceeasi forma cu cea initiala?_ Cand unim solutiile subproblemelor formam raspunsul intreg al problemei initiale ?

10

Page 11: Fileshare.ro SC

3.BacktrackingObiective_ Intelegerea modalitatii de folosire a backtrackingului ca strategie de rezolvare a problemelor_ Recunoasterea problemelor ce pot fi rezolvate cu backtracking_ Intelegerea modului in care se aplica recursivitatea in backtracking_ Abilitatea de a implementa recursivitatea in probleme de backtracking

Problema labirintului:Regula mainii drepte_ Pune mana dreapta pe perete_ Atat timp cat nu ai iesit din labirint {_ Mergi tinand mana dreapta pe zid _ }

Abordare recursiva :

11

Page 12: Fileshare.ro SC

Codarea problemei labirintului_ Reprezentarea labirintului trebuie sa fie o structura de date ce ne permite:_ sa codam peretii_ sa retinem pozitia curenta_ sa ne indice daca un anumit loc este marcat_ sa putem determina daca am iesit din labirint sau nu

12

Page 13: Fileshare.ro SC

13

Page 14: Fileshare.ro SC

Problema colorarii hartilor_ Vrem coloram harta din imagine folosind backtracking_ Scopul este de a folosi doar 4 culori, astfel incat oricare doua tari vecine sa nu aiba aceeasi culoare_ Vom considera statele in ordine alfabetica si vom folosi cele patru culori in ordinea urmatoare: rosu, galben, verde si albastru

14

Page 15: Fileshare.ro SC

_ Incepem prin apelarea metodei de colorare pentru a colora Colorado_ Aceasta metoda incepe cu o bucla for in care iteram lista cu culori posibile (rosu, galben, verde, albastru)._ Intai se verifica daca se poate colora cu rosu Colorado_ Se poate deoarece niciun dintre vecini nu e colorat, deci Colorado primeste rosu_ Metoda se aplica apoi pentru Idaho (in ordine alfabetica)_ Ce culoare va primi?

_ Idaho va primi culoare rosie, deoarece niciunul dintre vecinii sai e colorat cu rosu_ Apoi metoda va apela Kansas_ Ce culoare va primi?

_ Kansas e colorat cu galben_ Metoda incearca mai intai rosu, dar nu poate deoarece este culoarea lui Colorado, apoiincearca urmatoarea culoare din lista, galben_ Montana este colorata cu galben

_ Rosu nu merge deoarece Idaho e colorat cu rosu_ Se continua apelul cu Nebraska_ Ce culoare va primi?_ Nebraska se coloreaza cu verde_ Rosu nu merge, deoarece Colorado e colorat cu rosu. Galben nu merge, deoarece Kansas e deja colorat cu galben. Verde merge, deoarece niciun vecin nu este colorat cu verde

15

Page 16: Fileshare.ro SC

_ Se continua apelul cu North Dakota_ Ce culoare va primi?

_ North Dakota este colorata cu rosu, deoareceniciun vecin nu este colorat cu rosu_ Se apeleaza South Dakota

_ Ce culoare va primi?

_ South Dakota este colorata cu albastru_ Se apeleaza Utah

_ Ce culoare va primi?_ Utah va fi colorat cu galben_ Urmatorul apel va fi Wyoming

_ Ce culoare va primi?

_ Nicio culoare nu merge!!!!_ Ce va face metoda in continuare??!?!?!_ Va face un pas inapoi intorcandu-se la pasul dinaintea acestui apel recursiv_ Nu mai coloreaza cu galben Utah, alegand alta culoare

_ Ce culoare va alege?

16

Page 17: Fileshare.ro SC

_ Utah va fi colorat cu verde_ Metoda incearca un nou apel pentru colorarea lui Wyoming_ Ce culoare va primi?

_ Nicio culoare nu merge!!_ Metoda face din nou backtracking.._ Ce culoare va primi Utah?_ Utah va fi colorat cu albastru

_ Urmeaza apelul recursiv pentru Wyoming_ Ce culoare va primi?

_ Nicio culoare nu merge!!!!_ Backtracking.. Utah a epuizat culorile.._ Backtracking..

17

Page 18: Fileshare.ro SC

_ Metoda apeleaza South Dakota_ Nu mai avem culori de incercat pentru South Dakota

_ Backtracking.._ Metoda apeleaza North Dakota_ Ce culoare va primi?

_ North Dakota este colorata cu verde_ Apelam South Dakota

_ South Dakota este colorata cu rosu_ Apelam Utah

_ Ce culoare va primi?

_ Utah este din nou colorat cu galben_ Apelam Wyoming din nou..

18

Page 19: Fileshare.ro SC

_ Va merge oare de data aceasta?

_ Da!! Wyoming este colorat cu albastru!

Codarea problemei colorarii hartii_ O matrice map[V][V] – unde V este numarul de tari_ map[V][V] - matricea de adiacenta (1 daca tarile sunt vecine, 0 altfel)_ Un integer m care reprezinta numarul de culori cu care se poate colora harta_ color[V] – vector cu culori asignate fiecarei tari

19

Page 20: Fileshare.ro SC

20

Page 21: Fileshare.ro SC

4.Greedy:Algoritmi Greedy _ Plata in monezi _ Programarea intervalelor de timp_ Problema rucsaculuiPlata in monezi_ Scop. Date fiind urmatoarele monezi 1, 5, 10, 25, 100, sa se gaseasca o metoda pentru a plati unui client o anumita suma, folosind un numar minim de monezi._ Ex. 34 $_ Algoritmul casierului. La fiecare iteratie se adauga moneda cu cea mai mare valoare, astfel incat sa nu se depaseasca valoarea totala. _ Ex. 2.89 $

21

Page 22: Fileshare.ro SC

Algoritmul casierului_ La fiecare iteratie, adauga cea moneda cu cea mai mare valoare, astfel incat sa nu se depaseasca suma totala

_ Este algoritmul casierului optim? Proprietatile solutiei optime_ Proprietate. Numarul de monezi cu valoare 1 <= 4_ Inlocuim 5 monezi de 1 cu una de 5_ Proprietate. Numarul de monezi de 5 <= 1_ Proprietate. Numarul de monezi de 25 <= 3_ Proprietate. Numarul de monezi de 5 + numarul de monezi de 10 <= 2_ Inlocuim 3 monezi de 10 si 0 monezi de 5 cu una de 25 si una de de 5_ Inlocuim 2 monezi de 10 si una de 5 cu una de 25

Analiza algoritmului casierului_ Consideram modalitatea optima de a schimba ck<=x<ck+1: greedy ia moneda k_ Presupunem ca orice varianta optima va lua tot moneda k_ Daca nu, are nevoie de monezi de tipul c1, c2,..., ck pentru a aduna suma x_ Tabelul urmator indica faptul ca nicio solutie optima poate sa realizeze acest lucru_ Problema se reduce la x-ck centime, care prin inductie se rezolva optim cualgoritmul casierului

Programarea intervalelor de timp

22

Page 23: Fileshare.ro SC

_ Task-ul j incepe la timpul sj si se termina la timpul fj_ Doua task-uri sunt compatibile daca nu se suprapun_ Scop: sa se gaseasca cea mai mare submultime de task-uri compatibile

Algoritm greedy_ Consideram task-urile intr-o ordine naturala_ Alegem fiecare task, astfel incat sa fie compatibil cutask-urile deja alese_ Consideram task-urile in ordine crescatoare in functie sjConsideram task-urile in ordine crescatoare _ in functie fj_ Consideram task-urile in ordine crescatoare in functie fjsj_ Pentru fiecare task j, numaram conflictele cj. Programam

in ordine crescatoare in functie de cjAlgoritmul Finish-time-first

Analiza algoritmului_ Sa presupunem ca algoritmul finish-time-first nu esteoptim_ Demonstratie (prin contradictie)_ Sa presupunem ca greedy nu este optim si sa vedem cese intampla_ Fie i1,i2,...,ik task-urile alease de greedy_ Fie j1,j2,...,jm task-urile dintr-o solutie optima cu i1=j1, i2=j2,..., ir=jr, pentru cea mai mare valoare posibila a lui

r

23

Page 24: Fileshare.ro SC

Partitionarea intervalelor_ Cursul j incepe la ora sj si se termina la ora fj._ Scop: sa se gaseasca numarul minim de sali pentru a programa toate cursurile, astfel incat sa nu se tina doua cursuri in aceeasi sala, la aceeasi ora._ Ex. Acest orar foloseste 4 sali pentru 10 cursuri

Ex. Acest orar foloseste 3 sali pentru 10 cursuri

Algoritm greedy_ Consideram cursurile intr-o ordine naturala

24

Page 25: Fileshare.ro SC

_ Punem fiecare curs intr-o sala libera (care?) sau alocam o noua sala, daca toate sunt ocupate_ Consideram cursurile in ordine crescatoare in functie sj Consideram cursurile in ordine crescatoare _ in functie fj_ Consideram cursurile in ordine crescatoare in functie fjsj_ Pentru fiecare curs j, numaram conflictele cj. Programam in ordine crescatoare in functie de cj

Algoritm start-time-first

15Algoritm start-time-first_ Algoritmul start-time-first poate fi implementat in O(nlogn)._ Stocam clasele intr-o coada de prioritati (cheia-timpul de terminare a ultimului curs)_ Pentru a determina daca un curs j este compatibil cu o sala, comparam sj cu cheia minima a salilor k din coada de prioritati_ Pentru a adauga cursul j in sala k, crestem valoarea cheii lui k cu fj_ Numarul total de operatii din coada de prioritati este de O(n)_ Sortarea in functie de timpul de start este de O(nlogn)_ Implementarea aceasta alege sala k al carei curs se termina cel mai devreme

Analiza algoritmului start-time-first_ Algoritmul start-time-first nu va pune doua cursuri in aceeasi sala, in acelasi timp_ Algoritmul start-time-first este optim_ Fie d numarul de sali pe care le aloca algoritmul_ Sala d este libera pentru vroiam sa o alocam cursului j, care este incompatibil cu restul salilor d-1_ Toate aceste d sali se elibereaza dupa timpul sj_ Deoarece am sortat cursurile in functie de timpul de start, toate aceste cursuri incep mai devreme de sj_ Deci, avem d cursuri care se suprapun la timpul sj+Ɛ_ Observatie -> toate orarele folosesc mai mult de d Sali

Problema rucsacului_ Un hot intra intr-un magazin si vede urmatoarele obiecte

25

Page 26: Fileshare.ro SC

_ Rucsacul sau are capacitatea de 4 kg. Ce trebuie sa ia astfel incat sa-si maximizeze profitul?Problema rucsacului fractional_ Hotul poate sa ia o parte dintr-un obiect

Problema rucsacului 0-1_ Hotul poate sa ia obiectul doar intreg.

Solutia Greedy pentru problema rucsacului fractional_ Sortam obiectele descrescator in functie de cost/kg

26

Page 27: Fileshare.ro SC

_ Daca rucsacul are capacitate 5 kg atunci Solutia este:

_ O(nlogn)

_ Data fiind o multime de obiecte I

_ Fie P problema selectarii obiectelor din I, cu greutatea maxima K, astfel incat valoarea lor sa fie22

Maxima

_ Fie k limita curenta a greutatii. Initial k=K.

5.Metoda programarii DINAMICE:Programare dinamica_ O meta-tehnica (seamana cu divide-et-impera)_ Se foloseste atunci cand problema initiala se poatesparge in probleme asemanatoare, mai mici.2_ Se foloseste cand solutia se poate calcula recursivfolosind solutiile subproblemelor._ Algoritmul gaseste solutii la subprobleme si le

stocheaza in memorie pentru a le folosi mai tarziu.Conceptul de programare dinamica

27

Page 28: Fileshare.ro SC

_ Ideea de baza:_ Solutia optima a problemei consta in gasireasolutiilor optime ale subproblemelorSe rezolva de jos in sus, prin construirea unui tabel3_ al subproblemelor rezolvate, folosit pentru

rezolvarea problemei initiale.Problema rucsacului (recapitulare)_ Data fiind o multime de obiecte, sa se aleaga aceleacare maximizeaza valoarea totala si incap intr-unrucsac. Fiecare obiect are o greutate si o valoare. Nuputem cara mai mult de o anumita greutate W.4_ Obiect # Greutate Valoare 1 1 8 2 3 6 3 5 5

Problema rucsacului_ Exista doua versiuni ale acesteu probleme:_ 0-1_ Fractionala5_ 0-1: obiectele nu se pot fractiona; se rezolva cu metoda programarii dinamice_ Fractionala: obiectele se pot fractiona; se rezolva cu algoritmul greedy.Problema rucsacului 0-1_ Fie un rucsac cu o capacitate W si o multime S ce consta in n obiecte._ Fiecare obiect i are o greutate wi si o valoare bi (wi, bi si W sunt intregi)_ Problema: ce obiecte trebuie alese, astfel incat samaximizam costul?

28

Page 29: Fileshare.ro SC

Abordare brute-force_ Sa rezolvam mai intai problema folosind un algoritm direct_ Deoarece sunt n obiecte, inseamna ca sunt

_ Exista o metoda mai buna?_ Da, folosind un algoritm bazat pe programarea dinamica_ Putem identifica foarte simplu subproblemele Daca problema initiala are obiectele 1...n, atunci10_ o subproblema ar fi gasirea unei solutii optime pentru Sk = {obiecte etichetate 1...k}

Definirea unei subprobleme

29

Page 30: Fileshare.ro SC

_ Daca problema initiala are obiectele 1...n, atunci o subproblema ar fi gasirea unei solutii optime pentru Sk = {obiecte etichetate 1...k}11_ Este o definitie rezonabila pentru o subproblema_ Intrebarea este: putem descrie solutia finala Sn folosind subprobleme Sk?_ Din pacate, nu.Definirea unei subprobleme_ Deci, definitia unei subprobleme este gresita._ Sa adaugam un nou parametru: w, care va reprezenta greutatea exacta pentru fiecare submultime de obiecte_ Problema va trebui sa calculeze B[k,w]

Formula recursiva pentru subprobleme_ Formula recursiva pentru subprobleme

_ Inseamna ca cea mai buna submultime Sk care are greutatea totala w este_ Cea mai buna submultime Sk-1 care are greutatea w_ Cea mai buna submultime Sk-1 care are greutatea w-wk

plus obiectul k

_ Cea mai buna submultime Sk care are greutatea totala w, fie contine obiectul k, fie nu_ Primul caz: wk > w, obiectul k nu poate fi in parte a solutiei deoarece am depasi greutatea w_ Al doilea caz: wk <= k, obiectul k poate fi parte a solutiei, si vom alege solutia care are o valoarea mai mare

Algoritm Rucsac 0-1

30

Page 31: Fileshare.ro SC

Exemplu_ Sa rulam algoritmul pe urmatoarele date:_ n = 4 # obiecte_ W = 5 (greutate maxima)17_ Obiecte (greutate, castig)

_ (2,3), (3,4), (4,5), (5,6)

31

Page 32: Fileshare.ro SC

32

Page 33: Fileshare.ro SC

Cum gasim efectiv obiectele corecte?_ Toate informatiile de care avem nevoie se gasesc in tabel._ B[n,W] sunt valorile maxime ce pot fi introduse in rucsac_ Fie i = n si k=W_ If B[i,k]!=B[i-1,k]_ Marcam obiectul i ca fiind in rucsac_ i = i-1, k = k-wi_ Else_ i= i-1

33

Page 34: Fileshare.ro SC

6.Liste inlantuite

Liste simplu inlatuite_ O lista inlantuita este reprezentata printr-o serie de noduri conectate intre ele, unde fiecare nod este reprezentat de o structura de date.2_ O lista inlantuita poate sa-si modifice dimensiunea in timpul rularii programului._ Inserarea si stergerea de noduri se face mai rapid cu liste inlantuite decat cu vectori.Liste simplu inlatuite_ Fiecare nod dintr-o lista inlantuita contine informatii despre date._ Fiecare nod dintr-o lista inlantuita contine si un pointer care face legatura cu un alt nod.

Liste simplu inlatuite_ O lista simplu inlantuita se numeste “inlantuita” deoarece fiecare nod din ea are un pointer prin care se face legatura cu urmatorul nod din lista.

Cum se declara?_ In primul rand, trebuie sa declaram o structura de date pentru noduri. De exemplu, urmatoarea structura poate fi folosita pentru a crea o lista in care nodurile stocheaza date de tip float.5struct ListNode{float value;struct ListNode *next;

};_ Urmatorul pas este sa declaram un pointer care sa fie capul listei.• Odata declarata structura nod si creat capulListNode *head;

34

Page 35: Fileshare.ro SC

6listei ca pointer NULL, avem o lista simplu inlantuita vida.• Urmatorul pas il reprezinta implementarea operatiilor listei.Operatii cu liste_ Vom folosi declararea clasei din slide-ul urmator, care este stocata in FloatList.h.

Adaugarea unui nod la o lista_ A adauga un nod la o lista inlatuita inseamna a-l adauga la finalul listei._ Pseudocodul pentru aceasta operatie este prezentat mai jos. Codul C++ urmeaza.Creeaza un nou nod9Stocheaza date in noul nodDaca nu exista niciun nod in listaNodul este capul listeiAltfelParcurge lista pentru a gasi ultimul nodAdauga nodul la finalul listei

35

Page 36: Fileshare.ro SC

Program:

Programul pas cu pas_ Pointerul head este declarat ca variabila globala. head este automat initializat cu 0 (NULL), ceea ce indica faptul ca lista este vida._ Primul apel al appendNode trimite 2.5 ca argument.12In urmtoarele instructiuni, un nou nod este alocat inmemorie, 2.5 este copiat in membrul value iar NULL este atribuit pointerului next.newNode = new ListNode;newNode->value = num;

newNode->next = nULL;

36

Page 37: Fileshare.ro SC

_ Urmatoarea instructiune este if.if (!head)

head = newNode;

_ Nu mai exista instructiuni de executat, asa ca functia main preia controlul._ In cel de-al doilea apel al appendNode, 7.9 este argumentul. Inca o data, se creeaza un nou nod, se atribuie valoarea lui value si se asigneaza

NULL pointerului next.

_ Deoarece head nu mai pointeaza NULL, intram pe ramura de else.

_ nodePtr este deja la finalul listei, deci buclawhile se termina imediat. Ultima instructiunenodePtr->next = newNode; face canodePtr->next sa pointeze catre noul nod.

37

Page 38: Fileshare.ro SC

17Acest fapt insereaza newNode la finalul listei.

_ A treia oara cand metoda appendNode este apelata, 12.6 este argumentul. Inca o fata, primele 3 instructiuni creeaza un nou cu argumentul stocat ca valoare a lui value.

_ Apoi, else se executa. nodePtr pointeazacatre head.

_ Atat timp cat nodePtr->next nu este NULL, se executa while. Dupa prima iteratie, nodePtr va pointa catre al doilea nod din lista.

_ Testul din conditia lui while pica dupa prima iteratie deoarece nodePtr->next pointeaza acum catre NULL. Ultima instructiune, nodePtr ->next = newNode; face ca nodePtr->next sa pointeze catre noul nod. Asa se insereaza newNode la capatul listei.

38

Page 39: Fileshare.ro SC

Parcurgerea unei liste_ Functia displayList parcurge lista, afisand value a fiecarui nod. Urmatorul pseudocod reprezinta algoritmul. Codul C++ este pe22slide-ul urmator.Atribuie capul listei unui pointer nodAtat timp cat pointerul nod nu este NULLAfiseaza value a nodului la care pointeaza pointerul nod

Atribuie pointerul nod urmtorului nod al listei

Inserarea unui nod_ Folosind structura listNode, pseudocodul urmator prezinta un algoritm pentru gasireapozitiei corecte de inserare a unui nod nou.2_ Algoritmul presupune ca nodurile din lista sunt deja ordonate.Creeaza un nou nodStocheaza datele in noul nod

39

Page 40: Fileshare.ro SC

Daca nu sunt noduri in listaNoul nod va fi capul listeiAltfel26Gaseste primul nod a carei valoare este mai mare sau egala cu nouavaloare sau finalul listei. Insereaza noul nod inaintea celui gasit sau pe

ultima pozitie.

40

Page 41: Fileshare.ro SC

_ In insertNode, un nou nod este creat si argumentul functiei este copiat in value. Atat timp cat lista are deka noduri stocate in ea, ramura de else se va executa. Incepe prin a30asigna nodePtr lui head.

_ Atat timp cat nodePtr nu este NULL si nodePtr->value este mai mica decat num, bucla while va itera. Pe parcursul acestei iteratii previousNode va pointa catre acelasi nod ca si nodePtr. nodePtr va pointa mai apoi catre nodul urmator.

_ Inca o data, bucla testeaza conditia. DeoarecenodePtr nu este NULL si nodePtr->valueeste mai mica ca num, bucla itereaza a douaoara. In timpul celei de-a doua iteratii, atat

41

Page 42: Fileshare.ro SC

32previousNode cat si nodePtr avanseaza cu

un nod in lista.

Stergerea unui nod_ Un nod se sterge dintr-o lista inaltuita in doi pasi:_ Se scoate nodul din lista_ Se sterge nodul din memorie33

_ Functia deleteNode incepe in slide-ul urmator.

42

Page 43: Fileshare.ro SC

43

Page 44: Fileshare.ro SC

Variatii ale listelor inlantuite_ Lista dublu inlantuita

_ Lista circulara inlantuita

7. Stive si cozi

Stive si cozi (Stack vs. Queue)_ Colectii de obiecte_ Operatii: inserare, stergere, iterare, verificare daca sunt vide_ Inserarea e la fel la ambele_ Dar stergerea?

44

Page 45: Fileshare.ro SC

_ Stiva: Last in first out – LIFO_ Coada: First in first out – FIFO

Stive_ O stiva permite accesul la un singur element:ultimul introdus in stiva._ Daca scoatem din stiva ultimul element, vom avea acces la penultimul element s.a.m.d._ Majoritatea microprocesoarelor folosesc o arhitectura bazata pe stive_ Adaugarea unui nou element intr-o stiva se numeste push._ Scoaterea unui element dintr-o stiva se numeste pop.

45

Page 46: Fileshare.ro SC

46

Page 47: Fileshare.ro SC

47

Page 48: Fileshare.ro SC

48

Page 49: Fileshare.ro SC

Exemple: Verificare paranteze_ c[d] // corect_ a{b[c]d}e // corect_ a{b(c]d}e // incorect ] != (_ a[b{c}d]e} // incorrect_ a{b(c) // incorrect

49

Page 50: Fileshare.ro SC

50

Page 51: Fileshare.ro SC

51

Page 52: Fileshare.ro SC

Coada. Coada de prioritati_ Enqueue - a introduce elemente in coada

_ Dequeue - a scoate elemente din coada

52

Page 53: Fileshare.ro SC

53

Page 54: Fileshare.ro SC

54

Page 55: Fileshare.ro SC

Coada de prioritati_ La fel ca o coada obisnuita, coada de prioritatiare doua capete_ Inserarea in coada de prioritati se face dupa26

valoarea unei chei ce determina prioritatea.

55

Page 56: Fileshare.ro SC

56

Page 57: Fileshare.ro SC

57

Page 58: Fileshare.ro SC

8.Sortari elementare

Ordonare_ Sortare a oricarui tip de data (atat timp cat ele se pot ordona)_ Ordonarea este o relatie binara care satisface urmatoarele

proprietati:

_ Exemple:_ Multimea numerelor naturale sau reale_ Ordinea cronologica a datelor

_ Ordinea alfabeticaSelection sort_ La iteratia i, gaseste indexul min a celui mai micelement ramas in lista

_ Interschimba pe a[i] cu a[min].

58

Page 59: Fileshare.ro SC

59

Page 60: Fileshare.ro SC

60

Page 61: Fileshare.ro SC

61

Page 62: Fileshare.ro SC

62

Page 63: Fileshare.ro SC

Insertion sort_ La iteratia i, interschimba a[i] cu valorile mai

mari decat ea din stanga sa.

63

Page 64: Fileshare.ro SC

Shell sort_ Spre deosebire de BubbleSort in care secompara doua elemente adiacente, in ShellSortse compara doua elemente ce se afla la odistanta d unul de celelalalt.17_ d este initial egal cu jumatatea lungimii array-ului,

dupa care se injumatateste continuu.

64

Page 65: Fileshare.ro SC

9.Merge Sort

MergeSort_ Pasi._ Impartim array-ul in doua jumatati_ Sortam recursiv fiecare jumatate2

_ Combinam jumatatile

Demo_ Scop. Fiind date doua subarray-uri sortate a[lo]pana la a[mid] si a[mid+1] pana la a[hi], sa se

inlocuiasca cu array-ul sortat a[lo] a[hi].

65

Page 66: Fileshare.ro SC

66

Page 67: Fileshare.ro SC

67

Page 68: Fileshare.ro SC

68

Page 69: Fileshare.ro SC

69

Page 70: Fileshare.ro SC

70

Page 71: Fileshare.ro SC

10. Quick SortQuickSort_ Ocupa un loc in Top 10 cei mai buni algoritmi ai

secolului 20QuickSort_ Pasi._ Se amesteca elementele din array_ Se imparte array-ul astfel incat pentru un anumit j_ Pentru un element a[j]_ Nu exista niciun element mai mare ca el la stanga_ Nu exista niciun element mai mic ca el la dreapta4

_ Se sorteaza recursiv fiecare subarray

71

Page 72: Fileshare.ro SC

Demo_ Repeta pana cand indicii i si j se intersecteaza_ Parcurge cu i de la stanga la dreapta atata timp cat a[i] < a[lo]._ Parcurge cu j de la dreapta la stanga atata timp cat a[j] > a[lo].

_ Interschimba a[i] cu a[j].

QuickSort – detalii de implementare_ Folosirea inca unui array simplifica modalitatea deimplementare, dar creste costurile._ Testarea incrucisarii pointerilor i si j este mai complicatadecat pare.

72

Page 73: Fileshare.ro SC

10_ Cand exista duplicate, mai bine se opreste scanarea._ Amestecarea elementelor este necesara pentru garantiaperformantei._ Trebuie sa se aleaga aleator elementul de partitionare in

fiecare subarray.

73

Page 74: Fileshare.ro SC

74

Page 75: Fileshare.ro SC

Algoritmul QuickSort

75

Page 76: Fileshare.ro SC

76

Page 77: Fileshare.ro SC

77

Page 78: Fileshare.ro SC

78

Page 79: Fileshare.ro SC

11. Grafuri_ Intrebare: Cum reuseste Google sa gaseasca

lucruri?Cautare pe Web_ Toate navigarile pe Internet sunt de fapt cereripentru anumite pagini

79

Page 80: Fileshare.ro SC

_ Dar ce se intampla cand nu stim ce sa cautam?4_ Un “motor de cautare” este un server Web care

raspunde la cererile particulare de paginilor Web.Grafuri_ In Informatica si matematica aceasta structura senumeste graf._ Nodurile: paginile Web5

_ Muchiile: link-urile dintre paginiGrafuri_ Un graf este o structura formala de a reprezenta relatiiledintre obiecte._ Un graf G este reprezentat ca G = (V, E)._ V – multimea varfurilor6_ E – multimea muchiilor_ Operatiile pe grafuri includ:_ Parcurgere_ Cautarea

_ Verificarea daca exista muchie intre doua varfuri etc.

Exemple de grafuri_ Grafuri web_ Varfurile sunt paginile web_ Muchia de la u la v este link-ul catre v care apare in pagina u_ Program7_ Varfurile sunt functiile_ Muchiile sunt apelurile de functii_ Facebook

_ TwitterReprezentarea grafurilor1. Matricea de adiacenta_ O matrice |V| x |V|, unde elementul (u,v) = 1,

daca si numai daca exista muchie intre u si v.

80

Page 81: Fileshare.ro SC

Reprezentarea grafurilor2. Liste de adiacenta_ O lista cu |V| elemente, in care fiecare elementstocheaza cate o lista inlantuita a tuturor varfurilor

adiacente

Terminologie_ In grafurile orientate muchiile au o anumita directie si se numesc arce._ In grafurile neorientate muchiile au dublu sens.10_ Varfurile u si v sunt adiacente daca exista muchia (u,v)._ Un graf complet are oricare doua varfuri sunt unite printr-o muchie.

Graf de cost_ Fiecare muchie are asociat un cost.

Drum si ciclu

81

Page 82: Fileshare.ro SC

Arbori ca si grafuri_ Fiecare arbore este un graf cu anumite restrictii._ Arborele este orientat_ Nu exista cicluri13_ Exista un drum direct de la radacina pana la fiecare

nod.

82

Page 83: Fileshare.ro SC

Algoritm general de cautare

83

Page 84: Fileshare.ro SC

Cautarea in latime_ Nodul radacina este expandat intai, apoi toate celelalte noduri suntexpandate, apoi toti succesorii lor s.a.m.d._ Sunt considerate toate drumurile de lungime 1, apoi toate

drumurile de lungime 2 etc.

_ Daca exista o solutie, algoritmul garanteaza ca o va gasi, iar dacaexista mai multe solutii, algoritmul va gasi intai starea tinta aflata la

cel mai mic numar de noduri.

Algoritm cautare in latime

84

Page 85: Fileshare.ro SC

Cautarea in adancime_ Se expandeaza nodul radacina, apoi se merge pe un drum pana seajunge la cel mai adanc nivel al arborelui._ Numai cand se ajunge la final (la nodurile frunza), cautarea se intoarce

si expandeaza noduri de la nivele mai putin adanci.

Parcurgerea in adancime: A, B, D, H, I, E, J, K, C, F, L, M, G, N, O.Algoritm cautarea in adancime

85

Page 86: Fileshare.ro SC

Deci, cum reuseste Google?_ Web Crawl: se downloadeaza pagini cunoscute, secolecteaza link-uri catre alte pagini, se repetaprocesul_ Indexare: se construieste un index gigant care53asociaza fiecare cuvant cu o lista de pagini in careapare acel cuvant_ Cautare distribuita: se folosesc foarte multe

calculatoare pentru a cauta mai rapidUn tip special de graf: Arborele

86

Page 87: Fileshare.ro SC

12. Arbori

_ Scopul: rezolvarea cautarii intr-o baza de date._ Arbore.2_ Folositor_ Versatil

_ Recursiv in mod natural.Cautarea intr-o baza de date_ Inregistrari:_ Nume si Social Security Number (SSN)_ Operatii:_ Inserare student3_ Stergere student_ Cautare student dupa nume sau SSN_ Scop:

_ Cautare rapida intr-o baza de date mare

Alte aplicatii_ Agenda telefonica online_ Spell checker care cauta cuvintele in dictionar_ Server care cauta adrese IP4_ Compilator care cauta dupa nume de variabile

pentru a le vedea tipul si adresa de memorie

Reprezentarea datelor_ Definim Item.h pentru o inregistrare din baza de

Date

87

Page 88: Fileshare.ro SC

_ Cream ST.h pentru a defini operatiile.

Array nesortat pentru reprezentareabazei de date

_ Cautare secventiala

Array sortat pentru reprezentareabazei de date

_ Cautarea binara dupa cheie

88

Page 89: Fileshare.ro SC

89

Page 90: Fileshare.ro SC

Arbore binar de cautare (BTS)

_ Se mentine ordonarea si in subarbori!

13

90

Page 91: Fileshare.ro SC

Cautarea in arborele binar decautare_ Incepem de la nodul radacina_ Daca cheia nodului curent este k, returnam nod_ Mergem la stanga daca <k15

_ Mergem la dreapta daca >kCautarea in BTS

Inserarea in BTS_ Cautam dupa cheie in arbore_ Cautarea se termina la pointerul NULL_ Alocam memorie pt noul element si facem legatura cu arborele

91

Page 92: Fileshare.ro SC

92

Page 93: Fileshare.ro SC

Traversarea arborilor

13. Hash Table

Inregistrari si chei_ Sa presupunem ca avem o clasa Record care contineinformatii despre studentii de la academia Jedi.2_ Vrem sa stocam aceste date dupa o cheie predefinita_ Cheia poate fi numele, ID, GPA, sau oricare alta data._ Restul datelor sunt date satelit

_ Sa luam un prim exemplu unde cheia este Class Rank.

93

Page 94: Fileshare.ro SC

Inregistrari si chei_ Deci, atunci cand scriem o lista de intregi de fapt ne referim la o lista de inregistrari ale

unor studenti. _ Vrem sa stocam datele astfel incat sa le putem gasi rapid intr-o cautare.Indexarea prin cheie_ Sa presupunem ca stim dinainte ca sunt mai putin de 500de studenti la Academia Jedi._ Sa cream un vector de marime 500._ Sa punem studentul cu cheia i in locul v[i]. Deci indexul =4

Cheie

_ Mai multe inregistrari sunt libere, deci folosim prea multamemorie.

_ Dar cautarea unei chei este rapida. O(1)Hash Table_ Un hash table (o harta) este o lista de inregistrari in carecheia unei inregistrari este mapata catre un index din lista._ Legatura dintre index si cheie se numeste functie hash._ Cheile nu trebuie sa fie numere intregi.5_ Fiecare bloc din hash table se numeste bucket._ Hash table-ul mananca multa memorie._ Cautarea/stergerea/inserarea se face in O(1)._ Regula de aur in Informatica: daca vrei sa faci ceva care

sa mearga repede, iti trebuie multa memorie.

Coliziuni_ In exemplul nostru s-a presupus ca nu avem duplicate._ Adica, fiecare inregistrare din baza de date are cheie unica._ Totusi, aceasta presupunere nu este in general valabila._ In cazul nostru, doi studenti cu aceeasi GPA ar avea acelasiClass rank. Deci, ar fi mapati in acelasi loc in hash table.6_ O coliziune apare cand doua inregistrari sunt mapate cu acelasi

94

Page 95: Fileshare.ro SC

index._ Cea mai grea partea a programarii hash table-urilor este evitarea

coliziunilor.

Open Addressing_ Open addressing: mapeaza fiecare cheie cu un index, iar dacaacesta este deja luat, il mapeaza in locul urmator liber._ Atunci cand facem cautarea si nu gasim inregistrarea cautam sila indexul urmator._ Ne oprim din cautare cand gasim inregistrarea sau cand dam de7un index gol._ Evident, aceasta rezolvare devine problematica atunci cand

datele se clusterizeaza intr-o anumita parte a hash tablelului.

Chaining_ O alta solutie ar fi sa lasam fiecare bucket sastocheze mai multe inregistrari._ Acest proces se numeste chaining.8_ Fiecare index ar fi o lista de inregistrari (vector,lista inlantuita, arbore etc.)_ Deci, am putea sa facem hash table-ul nostru un

vector de vector de inregistrari.

Chei mai complicate_ In exemplul nostru am organizat inregistrariledupa class rank._ Dar daca am vrea organizam inregistrarile dupa9ID? 399-423-821 cum l-am stoca?_ Sau daca am vrea sa le organizam dupa nume?

Cum mapam un string?Functii hash_ Functia hash H(x) mapeaza pe x intr-un index din tabel._ In primul exemplu H(x)=x: H(357)=357_ Functia hash trebuie sa poata mapa si H(“luke

95

Page 96: Fileshare.ro SC

skywalker”)=357 si chiar intregi mai mari precum ID,10H(002-345-285) = 357._ O functie hash trebuie sa minimizeze numarul de coliziuni_ Crearea unei functii hash bune este esentiala pentru

crearea unui hash table bun.Hashing strings_ Prezentam un exemplu de functie hash pentru stringuri. Nota bene: nueste o functie buna._ Fiecarui caracter din string-ul s ii va fi luat codul ASCII si insumat.e.g.(int)(‘L’) = 76._ Daca vrem ca rezultatul sa incapa intr-un hash table de marimea11HASH_SIZE, facem mod pe acea marime.int index = 0for (int i = 0; i < s.length(); i++)index += (int)s[i];index = index%HASH_SIZE;

_ Cu HASH_SIZE = 500, “Luke Skywalker” este mapat cu indexul 390.Hashing Strings12_ Cum este mai mare marimea hash tablelului, cu atataveam mai putine coliziuni._ Cu cat folosim mai multa memorie, cu atat hash tablelul

devine mai eficient.

Hashing Strings_ Inainte de a mapa un index, trebuie convertita cheia intr-uninteger._ Este de preferat un integer mai mare, pentru a nu mapa doar oparte a hash tablelului.

_ Pentru stringuri putem aduna codurile ASCII ale caracterelor.

_ Dar cu aceasta metoda, ordinea caracterelor nu conteaza, deci,H(“Yoda”) = H(“adoY”)_ O solutie ar fi sa ponderam caracterele. De exemplu, fixam oconstanta 1 < B < 2 si calculam:

Metoda diviziunii

96

Page 97: Fileshare.ro SC

_ Functia de hashing prezentata anterior este un exemplu al

metodei diviziunii: unde cheia x este convertita in integer iar M este o14constanta._ In general M este marimea hash tablelului_ Programatorii aleg de obicei o marimea hash tablelului un

numar mare prim, pentru a evita coliziunile.Metoda multiplicarii_ O metoda populara de hashing este metoda multiplicarii

unde 0 < A < 1 si M = HASH_SIZE sunt constante._ Cu alte cuvinte, multiplicam M cu A*x si apoi rotunjum.15_ Aceasta metoda de hashing a fost inventata de Donald Knuth._ Alegerea lui A depinde de date. Knuth recomanda_ Daca respectivele chei sunt uniform repartizate, alegerea lui A

minimizeaza coliziunile.

1. Cautarea binara. 

2. Se citeste un numar real x. Sa se calculeze radical de ordinul 3 din x folosind un algoritm de tip Divide et impera.

3. Se citeste un vector cu n elemente numere naturale. Sa se determine elementul minim din vector folosind divide et impera.

4. Se citeste un vector cu n elemente numere naturale. Sa se calculeze suma elementelor vectorului folosind divide et impera.

5. Turnurile din Hanoi.

6. Se citeste un vector cu n elemente numere naturale. Sa se calculeze CMMDC al elementelor vectorului folosind divide et impera.

7. Sa se rezolve ecuatia x^3+x-1=0 pe intervalul [0,1] folosind metoda divide et impera.

8. Se citesc doua numere, n si x, n natural si x real pozitiv. Fara a folosi functia pow, extrageti cu 3 zecimale exacte radicalul de ordinul n din x. 

9. Scrieti o functie minmax care sa determine elementul minim si elementul maxim dintr-un tablou cu elemente intregi folosind metoda divide et impera. 

10.Folosind metoda divide et impera, scrieti o functie care sa determine daca un tablou cu elemente intregi este ordonat crescator. 

11.Maximul din vector

12.QuickSort

13.Sortarea prin interscalare (MergeSort)

14.Se citesc 3 numere naturale S, n si e cu urmatoarele semnificatii: S este o suma de bani care trebuie platita folosind bancnote care au valori puterile lui e de la 1 la e la n. Se se afiseze modalitatea de plata folosind un numar minim de bancnote de tipurile precizate.

15.Problema comis-voiajorului

16.Fiind data o tabla de sah de dimensiunea nxn si un cal în coltul stânga sus al acesteia, se cere sa se deplaseze calul pe tabla astfel încât sa treaca o singura data prin fiecare patrat al tablei. 

17.Problema rucsacului

18.Problema programarii spectacolelor 

19.Se citeste un numar natural n>=4. Sa se afiseze toate permutarile multimii {1, 2, ... n} care au proprietatea ca diferenta absoluta a oricaror 2 elemente alaturate este cel putin egala cu 2.  

97

Divide et impera

Greedyy

Page 98: Fileshare.ro SC

98

Page 99: Fileshare.ro SC

20.Sa se afiseze toate permutarile multimii {1,2,...,n} care au proprietatea ca pentru orice element x din permutare (exceptandu-l pe primul) exista un element generat anterior care sa aiba valoare cu unu mai mica sau mai mare ca x.

21.Se citeste un numar natural n si o permutare a multimii {1,2,...,n}. Sa se afiseze permutarile multimii {1,2,...,n} in care oricare doua elemente alaturate nu au fost alaturate in parmutarea citita. Ex. Pt n= 4 si permutarea 1 2 3 4 , o permutare care respecta regula este 2 4 1 3

22.Se citeste un numar natural n. Afisati permutarile multimii 1,2,3...n in care pana la jumatate elementele sunt in ordine descrescatoare, iar de la jumatate pana la final in ordine crescatoare. 

23.Se citeste un numar natural n. Afisati permutarile multimii 1,2,3...n in care elementele pare sunt puncte fixe (se afla pe pozitie egale cu valoarea lor). 

24.Sa se scrie un program care reconstituie urmatoarea adunare: CINCI+ DOI=SAPTE

25. Casierul Se citeste un numar natural n si apoi n numere naturale ordonate strict crescator reprezentand valorile a n bancnote. Se citeste apoi o suma de bani s si se cere sa se plateasca in toate modurile posibile suma s cu bancnote de valorile precizate folosind cel putin o bancnota de fiecare valoare data. Se presupune ca avem la dispozitie oricate bancnote de fiecare valoare. 

26.Se citeste un numar natural n. Sa se afiseze toate modurile in care poate fi descompus ca produs de numere naturale diferite de 1 si n. 

27.Sa se aranjeze in toate modurile n pisici si m caini astfel incat nicio pisica sa nu fie asezata intre 2 caini. 

28.Se citeste un numar natural n<30. Sa se afiseze toate modalitatile de a-l calcula prin adunari sau scaderi ale numerelor 1,2, ...n. Fiecare numar de la 1 la n va aparea o singura data în descompunerea lui n. Daca acest lucru nu este posibil, se va afisa mesajul „Imposibil”. 

29.Se citeste un numar natural n. Sa se afiseze toate modalitatile de a-l descompune ca suma de numere naturale consecutive. Daca acest lucru nu este posibil, se va afisa mesajul „Imposibil”. 

30.Fie n>0, natural. Sa se scrie un program care sa afiseze toate partitiile unui numar natural n. Numim partitie a unui numar natural nenul n o multime de numere naturale nenule {p1, p2, …, pk} care îndeplinesc conditia p1+p2+ …+pk = n. 

31.Se citeste de la tastatura un numar natural n par, n<30. Sa se genereze si sa se afiseze pe ecran toate combinatiile de n paranteze rotunde care se închid corect. De exemplu, pentru n=4 se obtin urmatoarele combinatii: ( ( ) ) si ( ) ( ) .

32.Sa se scrie un program care genereaza si scrie într-un fisier toate cuvintele formate din n vocale mici (n numar natural citit de la tastatura, n<10), ordonate alfabetic. De exemplu, pentru n=3 se vor scrie în fisier: 

33.Scrieti un program care citeste de la tastatura un numar natural nenul n (n<=20) si construieste toate numerele formate din n cifre impare cu proprietatea ca oricare doua cifre alaturare dintr-un numar generat sunt consecutive în multimea cifrelor impare. Exemplu: Pentru n=4 se obtin numere de forma: 1313, 1353, 1357, .... 7979... 

99

Page 100: Fileshare.ro SC

100

Casierul prob 25

#include <fstream>using namespace std;ifstream fin("date.in");ofstream fout("date.out");

int x[100], a[100], n,s;

void citire(){ fin>>n; for(int i=1;i<=n;i++) fin>>a[i]; fin>>s;}

void afis(){ for(int i=1;i<=n;i++) if(x[i]!=0) fout<<x[i]<<"*"<<a[i]<<" "; fout<<endl;}

void back(int k,int sp){ int i; for(i=0;i<=(s-sp)/a[k];i++) { x[k]=i; sp=sp+x[k]*a[k]; if(sp<=s && k<=n) if(k==n && sp==s) afis(); else if(k<n) back(k+1,sp); sp=sp-x[k]*a[k]; }}

int main(){ citire(); back(1,0); fin.close(); fout.close(); return 0;} 25

Problema 26

#include<iostream>using namespace std;int n, a[100],m,x[100];

void afis(int k){

for(int i=1;i<=k;i++) cout<<x[i]<<" "; cout<<endl;}

void back(int k, int p){

if(p==n) afis(k-1);else

for(int i=1;i<=m;i++)

{

x[k]=a[i];

if(p*x[k]<=n && x[k]>=x[k-1]) back(k+1,p*x[k]);

}}

int main(){

cin>>n;m=0;for(int i=2;i<=n/2;i+

+) if(n%i==0)

a[++m]=i;back(1,1);return 0;

} 26

26

Problema 27

#include<iostream>

using namespace std;

int x[100],pus[100],n,m,nr=0;

void Write(){ for(int i=1;i<=n+m;i++) if(x[i]==1) cout<<"P ";

else cout<<"C "; cout<<endl; nr++;}

int cond(int k){ int c=0,p=0,i; for(i=1;i<=k;i++) if(x[i]==0) c++; else p++; if(p>n || c>m) return 0; if(k>=3) if(x[k-2]==0 && x[k-1]==1 && x[k]==0) return 0; return 1;}

void Sub(int k){ for(int i=1;i>=0;i--) { x[k]=i; if(cond(k)) if(k==n+m) Write(); else Sub(k+1); } }int main(){ cin>>n>>m; Sub(1); cout<<nr; system("pause"); return 0;}

Problema 27

#include<iostream.h>

int x[10],n,ns;

void scriesol (){ int j; int s=0; ns++; for(j=1;j<=n;j++) if(x[j]==1) s=s+j; else s=s-j; if(s==n) { cout<<endl; for(j=1;j<=n;j++) if(x[j]==1) cout<<"+"<<j; else cout<<"-"<<j;}}void back(int k){int i; for(i=0;i<=1;i++) { x[k]=i; if (k==n) scriesol(); else back(k+1);}}void main(){ cin>>n; back(1); if (ns==0) cout<<"Imposibil";}

Problema 28

#include<iostream.h>int n, ns,sol[20];void afis(int l){ int i; ns++; for(i=1;i<=l;i++) cout<<sol[i]<<" "; cout<<endl;}void back(int i, int sp){ int j; if (sp==n && i>2) afis(i-1); else for(j=sol[i-1]+1;j<=n-sp;j++)

if (j==sol[i-1]+1 || i==1){ sol[i]=j;

back(i+1, sp+j);}}void main(){cin>>n; ns=0; back(1,0); if (ns==0) cout<<"Imposibil";}

Page 101: Fileshare.ro SC

101

#include<iostream.h>int n, ns,sol[20];

void afis(int l){ int i; ns++; cout<<"Solutia nr. "<< ns<<" : "; for(i=1;i<=l;i++) cout<<sol[i]<<" "; cout<<endl;}

void back(int i, int sp){ int j; if (sp==n) afis(i-1); else for(j=1;j<=n-sp;j++)

if (j>=sol[i-1]){

sol[i]=j;

back(i+1, sp+j);

}}

void main(){ cin>>n; ns=0; back(1,0); cout<<ns<<" solutii";} Nr30 problema

#include<iostream.h>

int x[10],n;

void scriesol(){ int j; cout<<endl; for(j=1;j<=n;j++) if(x[j]==1) cout<<")"; else cout<<"(";}int cond(int k){ int i,pi=0,pd=0; for(i=1;i<=k;i++) if(x[i]==0) pd++; else pi++; return pd<=n/2 && pi<=pd;}void back(int k){ int i; for(i=0;i<=1;i++) { x[k]=i; if (cond(k))

if (k==n) scriesol();

else back(k+1); }}

void main(){ cin>>n; back(1);}

Problema nr 31

#include<iostream.h>

int x[10],n;char v[]="aeiou";

void scriesol(){ int j; cout<<endl; for(j=1;j<=n;j++) cout<<v[x[j]];}

void back(int k){ int i; for(i=0;i<=4;i++) { x[k]=i; if (k==n) scriesol(); else back(k+1); }}

void main(){ cin>>n; back(1);}Problema nr 32

#include<iostream.h>

int x[10],n;

void scriesol(){ int j; cout<<endl; for(j=1;j<=n;j++) cout<<x[j];}int cond(int k){ if(k>1) if(x[k]-x[k-1]==2 || x[k-1]-x[k]==2) return 1;

else return 0; else return 1;

}void back(int k){ int i; for(i=1;i<=9;i=i+2) { x[k]=i; if (cond(k))

if (k==n) scriesol();

else back(k+1); }}

void main(){ cin>>n; back(1);}

Problema nr 33

Page 102: Fileshare.ro SC

102

Se citeste un numar natural n si o permutare a multimii {1,2,...,n}. Sa se afiseze permutarile multimii {1,2,...,n} in care oricare doua elemente alaturate nu au fost alaturate in parmutarea citita. 

#include<iostream.h> int x[100],a[20][20],p[100],n; void citire() { cin>>n; for(int i=1;i<=n;i++) cin>>p[i]; for(i=2;i<=n;i++) {

a[p[i-1]][p[i]]=1;a[p[i]][p[i-1]]=1;

} }

void afis() { for(int i=1;i<=n;i++) cout<<x[i]<<" "; cout<<endl; }

int cond(int k) { for(int i=1;i<=k-1;i++) if(x[k]==x[i]) return 0;

if(k>1 && a[x[k-1]][x[k]]==1) return 0;

return 1; }

void back(int k) { for(int i=1;i<=n;i++) { x[k]=i;

if(cond(k)) if(k==n) afis();

else back(k+1); } }

void main() { citire(); back(1); }

Se citeste un numar natural n. Afisati permutarile multimii 1,2,3...n in care pana la jumatate elementele sunt in ordine descrescatoare, iar de la jumatate pana la final in ordine crescatoare. 

#include <fstream>using namespace std;ifstream fin("date.in");ofstream fout("date.out");

int n, sol[20], p[20];

void afis(){ for(int i=1;i<=n;i++) fout<<sol[i]<<" "; fout<<endl;}

int valid(int k){ if(k>1) if(k<=(n+1)/2) { if(sol[k]>sol[k-1]) return 0; } else if(sol[k]<sol[k-1]) return 0; return 1;}

void back(int k){ for(int i=1;i<=n;i++) if(p[i]==0) { sol[k]=i; p[i]=1; if(valid(k)) if(k==n) afis(); else back(k+1); p[i]=0; }}

int main(){ fin>>n; back(1); fin.close(); fout.close();}

Se citeste un numar natural n. Afisati permutarile multimii 1,2,3...n in care elementele pare sunt puncte fixe (se afla pe pozitie egale cu valoarea lor). 

#include <fstream>using namespace std;ifstream fin("date.in");ofstream fout("date.out");

int n, sol[40], p[40];

void afis(){ for(int i=1;i<=n;i++) if(i%2==0) fout<<i<<" "; else fout<<sol[i]<<" "; fout<<endl;}

void back(int k){ for(int i=1;i<=n;i=i+2) if(p[i]==0) { sol[k]=i; p[i]=1; if(n%2==0 && k==n-1 || n%2==1 && k==n) afis(); else back(k+2); p[i]=0; }}

int main(){ fin>>n; back(1); fin.close(); fout.close();}

Cinci+Doi=7

#include<iostream.h> int x[8]; void afis() { cout<<x[1]<<9<<x[2]<<x[1]<<9<<"+"<<endl; cout<<" "<<x[3]<<x[4]<<9<<"="<<endl; cout<<"------"<<endl; cout<<x[5]<<0<<x[6]<<x[7]<<8<<endl<<endl; } int cond(int k) { if(k==7) if(x[1]+x[4]+1!=x[7] && x[1]+x[4]+1!=x[7]+10 ) return 0; if(k>=6) { if(x[1]+x[4]+1<10)

if(x[2]+x[3]<10 || (x[2]+x[3])%10!=x[6]) return 0;

if(x[1]+x[4]+1>=10) if(x[2]+x[3]+1<10

|| (x[2]+x[3]+1)%10!=x[6]) return 0; } if(k>=5) if(x[1]+1!=x[5]) return 0; for(int i=1;i<k;i++)

if(k>=5) if(x[1]+1!=x[5]) return 0; for(int i=1;i<k;i++) if(x[i]==x[k]) return 0; return 1; }

void back(int k) { for(int i=1;i<=7;i++)

{x[k]=i; if(cond(k)) if(k==7)

afis(); else back(k+1); } }

void main() { back(1); }

Page 103: Fileshare.ro SC

103

Problema programarii spectacolelor Intr-o sala de spectacol trebuie planificate n spectacole intr-o zi. Pentru fiecare spectacol se cunosc ora de inceput si ora de terminare (numere intregi). Sa se planifice un numar maxim de spectacole astfel inct sa nu fie doua spectacole care sa se suprapuna.

#include<fstream>using namespace std;ifstream fin("date.in");ofstream fout("date.out");

struct spectacol{ int s,d;};

void citire(int &n, spectacol a[]){ fin>>n; for(int i=1;i<=n;i++) fin>>a[i].s>>a[i].d;}

void ordonare(int n, spectacol a[]){ int i,j; spectacol aux; for(i=1;i<n;i++) for(j=i+1;j<=n;j++) if(a[i].d>a[j].d) { aux=a[i]; a[i]=a[j]; a[j]=aux; }}

void afisare(int n, spectacol a[]){ for(int i=1;i<=n;i++) fout<<a[i].s<<","<<a[i].d<<" ";}

void greedy(int n, spectacol a[]){ spectacol s[100]; int i,k; k=1; s[1]=a[1]; for(i=2;i<=n;i++) if(s[k].d<a[i].s) s[++k]=a[i]; afisare(k,s);}

int main(){ int n; spectacol a[100]; citire(n,a); ordonare(n,a); greedy(n,a); fin.close(); fout.close();} greedy restaurant

Se citeste un numar natural n>=4. Sa se afiseze toate permutarile multimii {1, 2, ... n} care au proprietatea ca diferenta absoluta a oricaror 2 elemente alaturate este cel putin egala cu 2. 

#include<iostream.h> int x[100],p[100],n; void afis() {for(int i=1;i<=n;i++) cout<<x[i]<<" "; cout<<endl; }

int cond(int k) { if(k>1) if(x[k]-x[k-1]==1 || x[k]-x[k-1]==-1) return 0; return 1; }

void back(int k) { for(int i=1;i<=n;i++) if(!p[i]) { x[k]=i;

p[i]=1;if(cond(k)) if(k==n) afis(); else back(k+1);p[i]=0;

} }

void main() { cin>>n; back(1); } backtracking

#include<iostream.h> int x[50],n; void afis() { int i; for(i=1;i<=n;i++) cout<<x[i]; cout<<endl;} int cond(int k) { int i; for(i=1;i<=k-1; i++) if(x[k]==x[i]) return 0; if(k>1)

{ for(i=1;i<=k-1;i++) if(x[k]-x[i]==1 || x[k]-

x[i]==-1) return 1; return 0;}return 1;}

void back(int k) {int i; for(i=1;i<=n;i++) {x[k]=i; if(cond(k)) if(k==n) afis();

else back(k+1); } } void main() { cin>>n; back(1); }Sa se afiseze toate permutarile multimii {1,2,...,n} care au proprietatea ca pentru orice element x din permutare (exceptandu-l pe primul) exista un element generat anterior care sa aiba valoare cu unu mai mica sau mai mare ca x. backtracking

Page 104: Fileshare.ro SC

104

Problema comis-voiajorului (varianta 1 greedy)

#include<fstream>using namespace std;ifstream fin("date.in");ofstream fout("date.out");

int x[100],pus[100],n,s;int a[100][100];

void citire(){ int i,j; fin>>n; for(i=1;i<=n;i++) for(j=1;j<=n;j++) fin>>a[i][j];}

void Write(){ for(int i=1;i<=n;i++) fout<<x[i]<<" "; fout<<endl<<s;}

void voiajor(int k){ int min=100000,imin; for(int i=1;i<=n;i++) if(!pus[i] && a[x[k-1]][i]<min && i!=x[k-1]) { min=a[x[k-1]][i]; imin=i; } x[k]=imin; pus[imin]=1; s=s+a[x[k-1]][imin]; if(k==n) Write(); else voiajor(k+1);}

int main(){ citire(); x[1]=1; pus[1]=1; voiajor(2); fin.close(); fout.close(); return 0; GREEDY}

Fiind data o tabla de sah de dimensiunea nxn si un cal în coltul stânga sus al acesteia, se cere sa se deplaseze calul pe tabla astfel încât sa treaca o singura data prin fiecare patrat al tablei. 

#include<fstream>#include<iomanip>using namespace std;const int dx[8]={-1,1,2,2,1,-1,-2,-2};const int dy[8]={-2,-2,-1,1,2,2,1,-1};int a[201][201],n,gata;ifstream fin("cal.in");ofstream fout("cal.out");

void afis(){ int i,j; fout<<"n="<<n<<endl; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) fout<<setw(4)<<a[i][j]<<" "; fout<<endl; } fout<<endl; gata=1;}

int inside(int i,int j){ return i>=1 && i<=n && j>=1 && j<=n;}

int nm(int i, int j)//calculeaza in cate pozitii poate merge din i,j{ int inou,jnou,k,x=0; for(k=0;k<8;k++)

{ inou=i+dx[k]; jnou=j+dy[k]; if(inside(inou,jnou) && a[inou][jnou]==0) x++; }

return x;}

void calgreedy(int i, int j, int pas){ int k,v,min=9,inou,jnou,ii,jj; if(!gata) { a[i][j]=pas; if (pas==n*n) afis(); else for(k=0;k<8;k++)

{ inou=i+dx[k]; jnou=j+dy[k]; if (inside(inou,jnou) && a[inou][jnou]==0) { //cauta pozitia cel mai greu accesibila v=nm(inou,jnou); if(v<min) { min=v; ii=inou; jj=jnou;} } }

if(min!=9) calgreedy(ii,jj,pas+1); a[i][j]=0; }}

int main(){ fin>>n; calgreedy(1,1,1); fout.close(); return 0;} Greedy

Page 105: Fileshare.ro SC

105

Problema rucsacului (cazul continuu)  GreedyO persoana are un rucsac cu care poate transporta o greutate maxima g. Persoana are la dispozitie n obiecte pentru care stie greutatea si castigul obtinut daca transporta obiectul. Fiecare obiect poate fi transportat integral sau taiat. Sa se precizeze ce obiecte alege persoana si in ce proportie le ia astfel incat castigul total sa fie maxim si sa nu se depaseasca greutatea maxima a rucsacului. 

#include<fstream>#include<iomanip>using namespace std;ifstream fin("date.in");ofstream fout("date.out");

struct obiect{ float g,c,r;//greutate, castig, raportul cat se ia din obiect};

void citire(float &g, int &n, obiect a[]){ fin>>g>>n; for(int i=1;i<=n;i++) { fin>>a[i].g>>a[i].c; a[i].r=0;//initial nu se foloseste obiectul }}

void ordonare(int n, obiect a[])//ordonare dupa castig/greutate{ int i,j; obiect aux; for(i=1;i<n;i++) for(j=i+1;j<=n;j++) if(a[i].c/a[i].g<a[j].c/a[j].g) {aux=a[i]; a[i]=a[j]; a[j]=aux;} }

void afisare(int n, obiect a[]){ float c=0; for(int i=1;i<=n;i++) { fout<<a[i].g<<","<<a[i].c<<","<<setprecision(4)<<a[i].r<<"\n"; c=c+a[i].c*a[i].r; } fout<<"castig maxim="<<c;}

void greedy(float g, int n, obiect a[]){ obiect s[100]; int i,k; float sp=0; k=0; i=1; while(sp<g) { if(sp+a[i].g<=g) { sp=sp+a[i].g; s[++k]=a[i]; s[k].r=1;//obiect intreg } else { s[++k]=a[i]; s[k].r=(g-sp)/a[i].g;//obiect fractionat sp=g; } i++; } afisare(k,s);}

int main(){ int n; obiect a[100]; float g; citire(g,n,a); ordonare(n,a); greedy(g,n,a); fin.close(); fout.close();}

Page 106: Fileshare.ro SC

106

Quicksort

#include <fstream>using namespace std;ifstream fin("date.in");ofstream fout("date.out");

int poz(int a[50000], int s, int d){ int i,j,di,dj,aux; i=s; j=d; di=0; dj=1; while(i<j) { if(a[i]>a[j]) { aux=a[i]; a[i]=a[j]; a[j]=aux; di=1-di; dj=1-dj; } i=i+di; j=j-dj; } return j;}

void QS(int a[50000], int s, int d){ int p; if(s<d) { p=poz(a,s,d); QS(a,s,p-1); QS(a,p+1,d); }}

void citire(int a[50000], int &n){ int i; fin>>n; for(i=1;i<=n;i++) fin>>a[i];}

void afis(int a[50000], int n){ int i; for(i=1;i<=n;i++) fout<<a[i]<<"\n";}

int main(){ int a[50000], n; citire(a,n); QS(a,1,n); afis(a,n); return 0;} QSort

Sortarea prin interclasare (MergeSort)

#include <fstream>using namespace std;ifstream fin("date.in");ofstream fout("date.out");

void inter(int a[50000], int s, int m, int d){ int i,j,k,c[50000]; i=s; j=m+1;k=1; while(i<=m && j<=d) if(a[i]<a[j]) c[k++]=a[i++]; else c[k++]=a[j++]; while(i<=m) c[k++]=a[i++]; while(j<=d) c[k++]=a[j++]; k=1; for(i=s;i<=d;i++) a[i]=c[k++];}

void msort(int a[50000], int s, int d){ int m; if(s<d) { m=(s+d)/2; msort(a,s,m); msort(a,m+1,d); inter(a,s,m,d); }}

void citire(int a[50000], int &n){ int i; fin>>n; for(i=1;i<=n;i++) fin>>a[i];}

void afis(int a[50000], int n){ int i; for(i=1;i<=n;i++) fout<<a[i]<<" ";}

int main(){ int a[50000], n; citire(a,n); msort(a,1,n); afis(a,n); return 0;} Merge Sort

Se citesc 3 numere naturale S, n si e cu urmatoarele semnificatii: S este o suma de bani care trebuie platita folosind bancnote care au valori puterile lui e de la 1 la e la n. Se se afiseze modalitatea de plata folosind un numar minim de bancnote de tipurile precizate. Sa se afiseze la final numarul de bancnote folosite. Datele se vor citi din fisierul eur.in, iar rezultatele se vor afisa in fisierul eur.out.--------------------

#include <fstream>using namespace std;ifstream fin("eur.in");ofstream fout("eur.out");int main(){ int S,n,e,t=0; fin>>S>>n>>e; int p=1,k=0; while(p*e<=S && k<n )//calculez bancota maxima (<=S avand cel mult valoarea e la n){ p=p*e; k++; } while(S>0) { if(S>=p) fout<<S/p<<" bancnote de valoarea "<<p<<endl; //bancnotele de valoare p t=t+S/p;//numar bancnotele folosite S=S%p;//cat mai ramane de platit p=p/e;//bancnota urmatoare ca valoare (mai mica) }

Page 107: Fileshare.ro SC

107

Se citeste un vector cu n elemente numere naturale. Sa se calculeze CMMDC al elementelor vectorului folosind divide et impera. #include<iostream>

using namespace std;

int cmmdc(int a[100], int s, int d){ if(s==d) return a[s]; else { int x,y; x=cmmdc(a,s,(s+d)/2); y=cmmdc(a,(s+d)/2+1,d); while(x!=y) if(x>y) x=x-y; else y=y-x; return x; } }

int main(){ int a[100],n,i; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; cout<<cmmdc(a,1,n); system("pause"); return 0;}

Sa se rezolve ecuatia x^3+x-1=0 pe intervalul [0,1] folosind metoda divide et impera. #include<iostream>

using namespace std;

float f(float x){ return x*x*x+x-1;}

float DEI(float s, float d){ if(d-s<=0.0001) return s; else { float m=(s+d)/2; if(f(m)==0) return m; else if(f(m)<0) return DEI(m,d); else return DEI(s,m); }}

int main(){ cout<<DEI(0,1); system("pause"); return 0;}

Se citesc doua numere, n si x, n natural si x real pozitiv. Fara a folosi functia pow, extrageti cu 3 zecimale exacte radicalul de ordinul n din x.  #include<iostream>#include<cmath>

using namespace std;

float f(float y, int n, float x){ float p=1; for(int i=1;i<=n;i++) p=p*y; return p-x;}

float DEI(float s, float d, int n, float x){ if(d-s<=0.0001) return s; else { float m=(s+d)/2; if(f(m,n,x)==0) return m; else if(f(m,n,x)<0) return DEI(m,d,n,x); else return DEI(s,m,n,x); }}

int main(){ int n; float x; cin>>n>>x; cout<<DEI(0,sqrt(x),n,x); return 0;}

Scrieti o functie minmax care sa determine elementul minim si elementul maxim dintr-un tablou cu elemente intregi folosind metoda divide et impera. 

void minmax(int v[], int s, int d, int &minn, int &maxx){ if(s==d) minn=maxx=v[s]; else { int a,b,x,y; minmax(v,s,(s+d)/2,a,x); minmax(v,(s+d)/2+1,d,b,y); if(a<b) minn=a; else minn=b; if(x>y) maxx=x; else maxx=y; }}

Folosind metoda divide et impera, scrieti o functie care sa determine daca un tablou cu elemente intregi este ordonat crescator. 

int ordon(int v[], int s, int d){ if(s==d) return 1; else if(ordon(v,s,(s+d)/2) && ordon(v,(s+d)/2+1,d) && v[(s+d)/2]<=v[(s+d)/2+1]) return 1; else return 0;}

Divide et impera

subproblemele (aflam maximul pentru fiecare din ele) iar solutia problemei va fi data de valoarea maxima dintre rezultatele celor doua subprobleme. -----------

Trebuie tiparita valoarea maxima dintre numerele retinute in vector de la i la j(initial i= 1, j=n). Pentru aceasta procedam astfel :daca i=j, valoare maxima va fi v[i] ;

contrar vom imparti vectorul in doi vectori (primul vector va contine componentele de la i la (i+j) div 2, al doilea va contine componentele de la ((i+j) div 2 +1 la j ) , rezolvam

< -----------

Maximul#include<iostream.h> int v[10],n; int max(int i ,int j) { int a,b; if (i==j) return v[i] ; else { a=max(i, (i+j)/2); b=max((i+j)/2+1,j); if (a>b) return a; else return b;} } main( ){ cout<<"n=";cin>>n; for (int i=1;i<=n;i++) {cout<<"v["<<i<<"]=";cin>>v[i]; } cout<<"max="<<max(1,n);}

Page 108: Fileshare.ro SC

108

Cautarea binara

#include<fstream>

using namespace std;ifstream fin("dateo.in");ofstream fout("dateo.out");

int main(){ int x,i,n,a[100],s,d,m,gasit=0; fin>>n; for(i=1;i<=n;i++) fin>>a[i]; fin>>x; s=1; d=n; while(s<=d && !gasit) { m=(s+d)/2; if(a[m]==x) gasit=1; else if(a[m]<x) s=m+1; else d=m-1; } if(gasit) fout<<m; else fout<<"Nu se gaseste"; fin.close(); fout.close(); return 0;}

Se citeste un numar real x. Sa se calculeze radical de ordinul 3 din x folosind un algoritm de tip Divide et impera.

#include<iostream>using namespace std;double r3(double x, double s, double d){ if(d-s<=0.0001) return d; else { double m=(s+d)/2; if(m*m*m<x) return r3(x,m,d); else return r3(x,s,m); } }

int main(){ double x; cin>>x; if(x>0) if(x<1) cout<<r3(x,0,1); else cout<<r3(x,0,x); else if(x>-1) cout<<r3(x,-1,0); else cout<<r3(x,x,0); system("pause"); return 0;}

Se citeste un vector cu n elemente numere naturale. Sa se determine elementul minim din vector folosind divide et impera.

#include<iostream>

using namespace std;

int min(int a[100],int s , int d){ if ( s == d ) return a[s]; else { int m = (s+d)/2; int m1 = min(a,s,m); int m2 = min(a,m+1,d); if ( m1 < m2 ) return m1; else return m2; }}

int main(){ int a[100]; int n ; cin>> n; for (int i = 0 ; i < n ;i++) cin>>a[i]; cout << min(a,1,n); system("pause"); return 0;}

Se citeste un vector cu n elemente numere naturale. Sa se calculeze suma elementelor vectorului folosind divide et impera.

#include<iostream>

using namespace std;

int suma(int a[100], int s, int d){ if(s==d) return a[s]; else return suma(a,s,(s+d)/2)+suma(a,(s+d)/2+1,d);}

int main(){ int a[100],n,i; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; cout<<suma(a,1,n); system("pause"); return 0;}

Turnurile Hanoi#include<fstream>using namespace std;ifstream fin("h.in");ofstream fout("h.out");

void hanoi(int n, char a, char b, char c,char t1[10], char t2[10], char t3[10]){ if(n>=1){hanoi(n-1,a,c,b,t1,t3,t2); int x=strlen(t2); t2[x]=t1[strlen(t1)-1]; t2[x+1]=0; strcpy(t1+strlen(t1)-1, t1+strlen(t1)); fout<<t1<<endl<<t2<<endl<<t3<<endl; fout<<a<<"->"<<b<<endl<<endl; hanoi(n-1,c,b,a,t3,t2,t1); } } -----------------------

Turnuri Hanoi Part2int main(){ char t1[10]="A", t2[10]="B", t3[10]="C"; int n; fin>>n; for(int i=n;i>=1;i--) t1[n-i+1]=i+'0'; t1[n+1]=0; hanoi(n,'A','B','C',t1,t2,t3); fin.close(); fout.close();}

Divide et impera

Page 109: Fileshare.ro SC