+ All Categories
Home > Documents > J>erban, ~erban Programarea in limbajuIC/C+++(Cerchez).pdf · CuvantInainte Cartea defata...

J>erban, ~erban Programarea in limbajuIC/C+++(Cerchez).pdf · CuvantInainte Cartea defata...

Date post: 25-Dec-2019
Category:
Upload: others
View: 27 times
Download: 3 times
Share this document with a friend
144
r- (-, I I l I ' I , _It ,- i \- ! ("'"""" r- I iEmanuela <C<'rehezin. 12;{)4.1968,Ja. -este .absol veata.a F.acultlllii de lMatematicll. esectia dnformatica =3i.a 'Seminamlui 'pedagogic postuniversitar (1997) .rprofesoara de dnformatica -(grad didacticI), .membra in Comisla'Natioaala-dednfbrmatica. Autoareaa maipubljcar laEditura 'Polirom:;Lnternet. Manual pentru diceu·(2000. savizat :'MEN), .Jnjormatica.Manualpemruclasa ..aX-,.a<{coautorMarinel.,.Paul :1]erban., :2000, -avizatMEN). PC. PasJ;cu.pas .;(coautor Marinel-Paul 2001), dn/ormatlea.pentrugimnaslu (coantor MarineI-P.aul J>erban, 2002, .avizat MEC), :In/onnatiea..O<legere<dep1Obiemepentru1Ieeu(2oo2),iProgramarea inJimbajul.CIC++ pentru -liceu '(coautor Marinel-Paul •.2005). Marinel-Paul *"bau (n. 29.06.1950, la Arad)esre .absolvent >II F.acultlllii .deMatemattca- Mecanicll,"Universitatea din"Iunisoara (1973) ; (1974), profeaor.dednformatica (grad didactic I),mem.bru in Comisia Nationala.deInformatica. De.acelasi .autor;.la Bditura Poliromau.aparut : Jnformatica. Manualpentru clasaaX-a (coautoareEmanuela Cerchez, 2000,avizatMEN), PC. .ll:zs cu pas (coautoare Emanuela Cerchez, 2oo1),Infonnatieapentru gimnaziu(coautoare Emanuela Cerchez, 2002, .avizatMEC). Programarea inlimbajul CIC++ pentru liceu .rcoauroare Emanuela Cerchez, 2oq5). Autoril au.o bogata.experienta in pregatirea de performanta a elevilor : austin cursuri la Centrul de Pregatire a Tinerilor Capabili de Performanta din Iasi, propun probleme pentru olimpiadele §i .concursurlle.nationale §i judetene de Informatica, -susjln.activltatea .de pregatire.a lotuluinational .de Informatica, precum.si programul de pregatire.de perfonnantajn Informatica ..campion. e 2005 by Editura POLIROM www.polirom.ro Editura POLIROM Iasi, B-dul Carol 1 Dr. 4, P.O. BOX 266. 700506 Bucuresti, B-dul I.C. Bratianu 'nr. 6, et, 7, ap. 33, O.P. 37; P.O. BOX 1-728, 030174 Descrierea ClPa Bibliotecii Nationale a Rormlniei: CERCHEZ, EMANUELA Programarea in Umbajul C/C+ + pentru lieeu: metode §Ii tehnici de programare I Emanuela Cerchez, Marinel Serban. - Iasl : Polirom, 2005 2 vol. ISBN: 973-46-0109-1 Vol. .2, - 2005. -ISBN: 973-46-0092-3 1. Serban, Marinel 004.43C 004.43 c++ Printed in ROMANIA EmanuelaCer.chez,MarinelSerban Programarea in limbajuIC/C++ pentruliceu Volumul al 'II-lea Metode 1ehnici de programare POll ROM 2005
Transcript

~

r-

(-,I

I l

f~

I 'I ,

_It ~

,-

,~,

i

\-

[~

!

("'""""

r-

I-~

iEmanuela <C<'rehezin. 12;{)4.1968,Ja.~i) -este .absol veata.a F.acultlllii de lMatematicll. esectiadnformatica :(1990)~=3i.a'Seminamlui 'pedagogic postuniversitar (1997).rprofesoaradednformatica-(grad didacticI), .membra in Comisla'Natioaala-dednfbrmatica. Autoareaamaipubljcar laEditura'Polirom:;Lnternet. Manual pentru diceu·(2000. savizat :'MEN),.Jnjormatica.Manualpemruclasa..aX-,.a<{coautorMarinel.,.Paul :1]erban., :2000, -avizatMEN). PC. PasJ;cu.pas .;(coautorMarinel-Paul~erbao,2001), dn/ormatlea .pentrugimnaslu (coantor MarineI-P.aul J>erban, 2002, .avizat MEC),:In/onnatiea..O<legere<dep1Obiemepentru1Ieeu(2oo2), iProgramareainJimbajul.CIC++ pentru-liceu '(coautor Marinel-Paul ~erban•.2005).

Marinel-Paul *"bau (n. 29.06.1950, la Arad)esre .absolvent >II F.acultlllii .deMatemattca­Mecanicll,"Universitateadin"Iunisoara (1973) ; "peeia\izarepostuniversitar~in;mormatic~ (1974),profeaor.dednformatica (grad didactic I),mem.bru in Comisia Nationala.deInformatica. De.acelasi.autor; .laBditura Poliromau.aparut : Jnformatica. Manualpentru clasaaX-a (coautoareEmanuelaCerchez, 2000, avizatMEN), PC..ll:zs cupas (coautoare Emanuela Cerchez, 2oo1),Infonnatieapentrugimnaziu(coautoare Emanuela Cerchez, 2002, .avizatMEC). Programarea inlimbajul CIC++pentru liceu .rcoauroare Emanuela Cerchez, 2oq5).

Autorilau.o bogata.experienta in pregatirea de performanta a elevilor : austin cursuri la Centrulde Pregatire a Tinerilor Capabili de Performanta din Iasi, propun probleme pentru olimpiadele §i.concursurlle.nationale §i judetene de Informatica, -susjln .activltatea .de pregatire.a lotuluinational.de Informatica, precum.si programul de pregatire .de perfonnantajn Informatica ..campion.

e 2005 by Editura POLIROM

www.polirom.ro

Editura POLIROMIasi, B-dul Carol 1 Dr. 4, P.O. BOX 266. 700506Bucuresti, B-dul I.C. Bratianu 'nr. 6, et, 7, ap. 33, O.P. 37; P.O. BOX 1-728, 030174

Descrierea ClPa Bibliotecii Nationale a Rormlniei:

CERCHEZ, EMANUELA

Programarea in Umbajul C/C+ + pentru lieeu: metode §Ii tehnici de programare IEmanuela Cerchez, Marinel Serban. - Iasl : Polirom, 2005

2 vol.ISBN: 973-46-0109-1

Vol. .2, - 2005. -ISBN: 973-46-0092-3

1. Serban, Marinel

004.43C004.43 c++

Printed in ROMANIA

EmanuelaCer.chez,MarinelSerban~

Programareain limbajuIC/C++

pentruliceuVolumul al 'II-lea

Metode ~i 1ehnici de programare

POllROM2005

·Cuprins

CuvlJnt lnainte .... .••....•.......•....... ••.... .•.. .•..... •.•..•.................................................. 9

Capitolull. :Recursivitate ,', 11

1. Conceptul de -recursivitate _ -............................ 112. Mecanismulde realizare a -recursivltatll 12

Inversarea unui cuviint ...•..••._ _ _ 12

3. Utilitatea functiilor recursive 14Asociativitate •.•........•............................•.•.•................0 , ••••••••••••••••••••••• 16

4. Aplicatii 17Calculul celul mal mare divizor comun a doua numere naturale , 17Funqia Ackermann 17

. Numarare .•......................•....•.................................................................. 18Sumo puterilor rdddcinilor ........•........•........................................................ 19Anagrame 20Generare .......•....•.......•••................. 0••••••••••••••••••••••••••••••••••••••••••••••••••••••••• 21Conversie 22Codul Gray 23Desert ......•....•....•................................................................................... 24lVindows 26Restaurarea unui opel de functie ....•.............................................................. 28Imagine ••.•............................................ . .. . . . . . . . . . . .. . . . . . . . . . . .. . . . . . . . . . . . . . . . . .. . . . . . . 30

5. Recursivftate Indirecta 346. Aplicatii 34

Sirul mediilor aritmetico-geometrice al lui Gauss 34Deplasarea pe ecran a unei bare ..............•.................................................... 35Verificarea corectitudinii sintactice a unei expresii aritmetice 36Transformarea unei exprestt aritmetice fn jormli polonesii 38Evaluarea unei expresii aritmetice .. 40Rezlstan 42

7. Probleme propuse , 45

Capitolul 2. Metoda Divide et impera 52

1. Descrierea generala a rnetodei , 52

. 2. Aplicatii 53eel mal mare divisor comun .. o ••~ 53

.,i,

'.-'

'\. i-.J

ii

.-J

i..-J

,

i..,..-j

'-.-I

'....J

,~

H

'....J

'..---J

'....J

......,

Capitolul 4. Elemente de ccmbinaterfca. 126

f\ Generarea produsului eartezian ..............................•......................................... 126l JGenerarea permutarilcr .... ~.............................................................................128

Numarul de ordine al unei permutart ..•...•................................•........................ 129

r'": Generarea aranjamentelor , 131

iGenerarea combinarilor ...............................••................................................ 132

l ~ Numarul de ordine al unei comblnari 134

Partitiile unei multimi 136\1 Numarul Iui Stirling de speja a IT-a 137

t..JNumarul Iui Bell ................................•...................................•.............•....... 138Generarea functiilor surjective .- 138

r'; Partitiile unui numar natural 140

JGenerare de paranteze ;............•...................... 142

1ft!

::1111

IIIII~1~1'

rm1\1

11: IIj,qill

1~.llliii"j';:.1:

lii1:!"1·1i'

N~a'§irurilor _•.....•., ~ 143Numarul lui Catalan ••..•••.••••••••.•••.....•....•....•...•...•....•.•..••••.••.....••....•.••..•....... 144

Permutari -eu-repetitie ~ '. .••••.. .•••••••....... .•.... .•.• .•............ 145Numarul lui Stirling .de -speta I ...••••••....••••.••.•.....•••••.....••..•..•.•.......•.................. 146

.Apfjcatli ••.....•.•••..•••.•..•...•..•••..•••.•.••.•....•.•.....•.........•••.....••...•..•..........••...•... 1.47.Permutdri fara puncte fixe ...•.•........••....••.......•••..••.•......... ·•.•. . . . .. ..•.. . .•. . .•. . . . 147So/dali ...•••.....•...•..........•.......•••..•...•...... ~ .•...........•...•............................. 148Numere .................................................. ... . . . . .. . . . . . . . .••.. . . . . . . .. . . . . . . . . . . .. . . .. . . . . 149Aniversare ..•..~.................••.........•.............................................•.........•...•• 151'Ture .••••....••••...•.......••...................................•.........•............................. 152Permutiiri cu k inversiuni ...........•...•............................................... ;.......... 154Potrivlre .•............................. .•......................................... 155Vizibil ................... ...........•............ ....... ...........•.... ................................. 157Bonus ..................................................•.....•........................................... 161

Probleme -propuse.............................................. 164

CapitolulS. Me~da program~rjj-dinamice · 173

1. Prezentare generala ..................................•......................•......................... 173

2. Aplicatii ......................•...................................................................•...... 174Pachete : •.......•....................•................................................... 174Tren 177-Bvaluare optimala 180Pietre : 183Rucsac 185Transformare de cuvinte , 188Palindrom 192Suma .. ~ ..••••..•••..••.....................•...•...••.......••.••••••••..•.•••............•.•.....•..... 194Lacusta 198Paragrafare optimala 201Cod 205Scam 207Polilie 211

Probleme propuse 217

Capitolul 6. Solutii ~j indicatii 233

1. Recursivitate ....................•...................................................................... 233

2. Metoda Divide et impera 240

3. Metoda Backtracking \.......................................................... 244

4. Elemente de combinatorica : 264

5. Metoda programarii dinamice 271

Bibliografie 287

4.5.

r-r-

r~

I II I, ,

tl, ;I J

'-'1,j

Problema Tumurilor din Hanoi .••...•........••••.•••.•.••••..•~ ~•••••••••••••••.••• :54ProblemapUerilor .55Fractali -:57

("1 Problema .tiiieturilor...•.....•.......••..•••.•..••.•.••••..•..••••••...•••••••••.•••••••••••••••••••••...~·581. ..J Descompunere ......•......•.••.....•••.•... :••.: : ~ t60

3. Compararea -performanjelcr .uncr .algoritmide ..cautare '§l 'sortare ~ ,61Algoritmi de cauiare. cautarea binard ..•.•.•.••.••..••••_ ::61Algoritmi de .sortare '63Sortarea prin inierclasare {Merge Son), ~ ,.••....•..• 65.Sortarea rapidd (Quick son) '67

:-1 Probleme propuse .........................•....................•....•.••....•.......•........•........•.....·"69I;apitolul3. 'Metoda Backtracking ........•..........••..........•.......•.••........•........•••.•.....•... 14

1. Descrierea generala a metodei ·74Problema reginelor ·76

n 2 A I' ..; j' . P leapl ' -82i Plata unei .sume cu monede de valori date ....•....•...... .••••..••.. .•.••. .. . . . . . . . . .•.•.•..•. .. 82

Generareaslrului ...............................•...•......•..........••..••.••....•................... 84Generarede numere ...................................................••.....•.....•.......•.......... 86Comis-voiajor .......................•...................•.....•......................................... 88Medii ...............................•........................•.......................•......•............. 90Domino ." 93

fl 3. ~:E~~~::~:~:l=:::::::::::::::::::::::::::::::::::::::: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :1~~Labirint ....................................•..........•.............. ,............................•....... 103Fotografie ....................................................................•.......•.................. 105Gel mai lung prefix · 107A_ DCollapse :............................•.•... 112

Considerajii fmale asupra metodei Backtracking 118

Probleme propuse 118

Il

CuvantInainte

Cartea defata reprezinta eel de-aldoilea volum al lucrarii Programarea in limbajulC/C+ + pentru .liceu.

In primul volum .au fost l'rezentate elementele de bazll ale limbajului C/C++,instructiunile limbajului, structurile de date statice (tabloul, §irul de caractere, articolul)§isentistatice (stiva §icoada), precum §imodularizarea programelor cu.ajutorul functiilor.Cei care an parcurs sistematic acest volum pot fi considerati initiati in domeniulprogramarii calculatoarelor.

In al doilea volum ne .adresam celor deja inipali §i prezentam metode §i tehnici deprogramare. Maniera de. abordare este similara celei din primul volum: nu oferim 0

documentatie tehnica, preocuparea noastra esentiala fiind de a dezvolta gandirea algo­ritmica §i apoi abilitatile de a implementa algoritntii in limbajul C/C + +. Prin urmare,§i in acest volum sustinem demersuI nostru prin numeroase aplicatii rezolvate, ellexplicatii detaliate §i implementari in limbajul C san C++. De asemenea, propunemspre rezolvarenumeroase exercitii Siprobleme, de tipurivariate Side dificultategradata,

Acest mod deabordare recomanda cartea elevilor care studiaza la scoala informatica,eelor care. se pregatesc pentru examenul de bacalaureat, celor ce doresc sil realizezeperformante in Informatica, sa fie c~§tigiltorii concursurilor §i oIimpiadelor scolare.Cartea poate fi de un real folos §i studentilor care studiaza programarea calculatoarelorin primiiani de facultate. Nu in ultimul rand. ea poate constitui un material didacticvaloros -pentruprofesorii care predau informatica.

Continutul teoretic, aplicatiile rezolvate, precum Iii cele propuse spre rezolvare aufost utilizate de autori in pregatirea temeinica a numeroase generatii de elevi, atAt laclasa, cat Iii la CentruI de Excelenta 13.§i. Succesele obtinute de acesti elevi 0 recomanda !

Autorii

l

I

iI

-II

i

I1'I

l~,,;II 1rf!r11.11

~I 'L' !I: i

i~'t-"r'i)

I I

lit.k I

1I

DrunlJn! :, j

nn, ,I J

nI !, ,, j

CAPITOLUL II

Recursivitate

1. Conceptul de recursivitate

in informatica §iin matematica, .recursivitatea este .un concept fundamental.Spunem ca 0 notiune este definitli recursiv daca in cadrul definitiei intervine ins~i

notiunea carese defineste.De exemplu, .un descendent at unei persoane esteun copil at sau sau un descendent

al unui copil .aisau. in acest CO2, pentru a defini notiunea de descendent am folositnotiunea 1ns~i.

In matematica aparfrecvent relatii recursive, denumite §i ~relatii de recurenta", Deexemplu, sa consideram sirul Fibonacci: 0, 1, 1, 2, 3. 5, 8, 13. 21, ...

Observam ca in acest sirprimii doi termeni sunt 0 §i I, iar in rest, fiecare termen seobtine tnsumand cei doi termeni care il preced. Prin urmare, 0 definitie recursiva pentrusirul Fibonacci este :

[!I ', "

fib:N -4N

fib(n) ~\~ib(n-1) +fib(n -2),daca n s; 1daci n>l

Exemplul precedent tncalca a doua parte a acestei reguli.

Apare intrebarea: orice descriere de acest tip este corecta? Saconsideram urmatorulexemplu :

Observati di f (0) =1, iar daca rc-L, pentru a calcula f (n) trebuie sa evaluam maiintai f (n+1). Dar pentru a evalua f (n+1) va fi nevoie de f (n+2), deoarece n>Oimplicli n+1>0 s.a.m.d. Prin urmare, functia f nu poate fi evaluatli decat pentru O.

Regulile fundamentale pentru ca recursivitatea sa fie definita corect sunt:

1. trebuie sa existe cazuri elementare, care se pot rezolva direct;2. pentru cazurile care nu se rezolva direct, recursivitatea trebuie sa.progreseze catre un

caz elementar.

~

i1 j

nnl j

C""', Il J

tlUr-:

f:N-->N

f(n) ~ (i'+f(n + 1),daca n =0dacii n >0

ilII(\

~~III, I

I:

~]~~Ii,!l~

i":il',,I I

:1::II:~l

Inversarea unui cuvant

2. Meeanismul derealizarea recursivitiitli

Sa se scrie 0 functie recursiva care citeste un cuvant caracter ell caracter §i.afiseazacuvantul, apoi inversuI acestuia. Marcajul de sfaqit de cuvant este caracterul spatiu.

13

Stiva x

~. x

Sum EB. x

Sum 0

La cel de al treileaapel, se aloca pe stiva 0 noua zona dememorie pentru variabila x , in care se citeste •i ' • se afiseaza peecran, se apeleaza a patra oara functia oglinda () .

La ultimul apel este citit caracterul spatiu ~i este afisat pe ecran

de doua ori.

La cel de .al doilea apel, se .aloca pe etiva 0 noua zona dememorie pentru variabila x , in care va fi citit caracterul •0' ,

acesta va fiafi~at pe ecran ,apoi se apeleaza din nou functiaoglinda () .

CD

RECURSIVITATE

.'Char ·x;cin~get(x);

-cout; -c x;..if (x ! = I I) oglinda () ;

cout; < "X;

Sa unnarim executia algoritmului 'pentru cuvantul de intrare doi.

La primul -apel al functlei oglinda () sealocape"stiva 0 'zonadememorie pentru variabila x,localafunctiei, se citeste in variabilax caracterul •d I , se aftseaza I d I --pe ecran.apoi, deoarece caracte­rul cititestediferitdespaliu, seapeleazlidinnou functia oglinda () .

void oglinda ()

La terminarea celui de al doilea apel, se revine in -primulapel al funcjiel, cand va fi afi§at caracterul 'd', dupli care serevine in programul principal.

FiguriIe ilustreaza configuralia stivei la_ fiecare moment.

d

Dupa afisare, se revine in apelul precedent (eel de aI doileaapel al functiei oglinda n). la instrucjiunea de dupa apel, seafi~eaza valoarea variabilei locale x, ~i anume '0 '.

i

a

Sliva xLa terminarea acestui apel, se revine in apelul precedent (eel

de aI treilea apel aI functiei oglinda (», la instructiunea dedupa apel, deci se scrie valoarea variabilei locale x, care in

acest caz este ' i I •

Stiva x

Stiva x

EBStiva x

.~i'.0

d

'PROGRAMAREAiN UMIlAJUL C/C++PBNTRUUCEU

i.nt main ()

j oglinda(); return 0; }

#include <iostream.h>

void oglinda();

Recursivitatea se realizeaza prin intermediul functiilor,o functie se numeste recursive daca se autoapeleaza,Autoapelarea se poate realiza in doua moduri: direct (in acest caz, in corpul functiei

apare explicit un apel recursiv) san indirect (in corpul functiei apareapelul unei aItefunctii care, la randul sau, apeleaza direct sau indirect functia respectiva),

Mecanismul care face posibila recursivitatea deriva din modul de functionare afunctiilor, Ca in cazul oricarui apel de functie, §i in cazuI functiilor recursive.se aloca 0

zona de memorie pe stiva pentru valorile parametrilor, precum §i pentru valorilevariabilelor locale. Aceasta zona de memorie ramane atocata pe tot -parcursul executieiapelului functiei, fiind eliberata la momentul revenirii in functia .apelanta. Stiva nu estegestionata explicit de catre programator, ci de catre sistem, Pentru a intelege mai exact,sa analizam urmatoarea problema.

Evident, -3 .uitat cazurile elementare. Ca -unnare, .recursia 'nu se .opreste niciodata :pentru.a calcula suma cifrelor numarului natural. se elimina succesiv cifrele.sale,panacand argumentul n .devlne o. Din acest moment.ise evalueaza1a infinit s urn(0) .deoareceoz i e .este permanent o.

Deci,coreet .ar -ft fost :

sum(n) = f0, ~daca n =0In%lO+sum(nllO), daca n c-O

12

1'"

i,,j

~

o·greseala care .apare frecvenr.este msa gi rncalcarea primei -reguli. 'De -exemplu,.am solicitat .unui -elev cSa -descrie.o functie .recursiva .caresa ::caIcuIezesuma .eifrelor-unui numar narural. A'abordat .problema excelent r-suma cifrelorunuinumarmatural.:n -se.obtine ;adumind.:ultima~cifrii;anumaruluim{n%1.0).cU-suma cifrelor mumarului-narural, :care.se_obtineeliminand.ultima:cifdi-din n {sum (n J J. 0» ~i:a$cris -relatia-urmaroare :

sum: ";N~ 'N~um(n)=n%lO+sum(n/~O);

r

~

! ,j\ unsigned ~ong fact(int n)1 . { unsigned ~on9 f=l i

L.

for (int i=li i<=ni i++) f*=ii.. return fi, 'I

'15

fib(S) )

fib(S-----.....

------- fib(l)}b(~

fib(l) fib(O).

·RECURSIVITA1E

fib~»> "-fib(3) fib(2)

/ ......... / .........fib(2) fib(l) fib(l) fib(O)

/ .........fib(l) fib(O)

Observati ca pentru a calcula eel de al cincilea termen al §irului Fibonacci a fostcalculat cel de al treilea termen de dona ori, iar eel de al doilea, de trei orl.

In general. pentru a calcula fib (ri) , trebuie sa calcuHim fib (n-l) §i fib (n-2).Dar pentru a calcula fib (n-1), trebuie sa calculam fib (n-2) §i fib (n-3) (decipentru a calcula fib (n) trebuie sa calculam de doua ori fib (n-2) §i 0 data fib (n-3»)

s.a.m.d. Analiza precedenta ne conduce la eoneluzia ca varianta recursiva de caIcui alnumerelor Fibonacci este dezavantajoasa, deoarece se calculeaza de mai multe ori aceleasivalori.

Dezavantajul de a calcnla acee~i valoare de mai mnlte on ar putea fi eliminat dacaam repne valorile deja calculate. Cum pentru a calcula un termen sunt necesari doar doi

if (x <= 1) return 1;return fib(x-2) + fib(x-l)i

Sa analizam aceasta functie recursiva, Pentru aceasta, sa urmarim mai int3.imodul deexecutie a functiei pentru uncaz 'particular, sa spunem x= 5. In .acest caz,schemaapelurilor recursive este :

unsigned ~ong fib(int x)

Exercitii

1. Calculati cate apeluri de functie sunt necesare pentru a calcnla recursiv tennenul ndin sirul Fibonacci.

.2. Modificati programul recursiv de caicul al termenilor sirului Fibonacci astfel Incat saafi§eze §i succesiunea apelurilor recursive.

Daciirealizlim 0 comparatie intre varianta dterativa de .calculal factorialuluisi varianta.recursiva, se observa ca varianta recursiva .este dezavantajoasa, -deoerece mecesita .timp-de executie :suplimentar:pentruoperapilecll stiva (la apel -:alocarea:memorieimecesarepentru parametruI functiei, pentru -valoarea calculata -de functie '§i pentru adresa -de-revenire, jar Ia incheierea executiei unuiapel-celiberarea memoriei alocate).

'Sirul Fibonacci

1Jnaltexemplu .bine cunoscut este sirul Fibonacci. Definitia recursiva pe careamprezenrat-o la inceputul capitolului -permite .descrierea .naturalaa unei functii recursive.de calcul al termenului n din §irul Fibonacci .astfel :

,PROGRAMAREA·iN LIMBAJUL C/C++ 'PENTRULlCEU

if (!n) return Ii

return n*fact(n-l)i

nr_{l' daca n e O.- l·2·3· .... n, daca n c-O

Aceasta definitie conduce la urmatoarea functie tterativa de calcul :

, :;,

Exercitia

ilModifieap programul-astfel tneAtsa citeasca 0 propozuie terminata ell ... " ,cuvinte1eLltiind separate prin cate un singur spatiu, sa afiseze propozitia §i apoi,pe .aceeasi Iinie,

cuvintele din propozitie in ordine Inversac separare printr-un -spatiu.

n! ~.Utilitatea funetiilor recursivenl. ~cursivitatea constituie 0 tehnica de a deserie intr-o maniera eleganta §i concisa

prelucrari de natura repetitiva.De multe ori intalnim procese care se exprima in termeni reeursivi. La matematica,

i:ea mai simpla si mai familiars funcjie exprimata in termeni reeursivi este factorialul :, I

! J 1_(1. daca n e um e n.(n-l)!, daca n>On Folosind aceasta definitie, putem descrie 0 functie recursiva de calcul aI factorialului

I lnui numar natural :, ~

i I[I 14

1 unsigned ~ong fact (int n)I ' (

)~!!J Desi este simplu, acesta nn este eel mai bun exemplu pentru a ilustra recursivitatea,pentru ea funcjia factorial poate fi descrisa in mod echivalent astfel :r;

nObservafie

La fiecare apel ,31 functiet se artilizeaza variabila-z. De§i poarta.acelasi nume.iestevorbarrdevariabile -diferitec careau zone-de anemorie-diferite (zonele alocate pC .sriva lafiecare) l.apel)..La fiecare moment:.este vizibiUi -doar wariabila x corespunzatoare .apelului .curent, J.(cea .de Ja varful -srivei). Aces! mod -de funcjionare -este ~-normal" .§i -deriva .din

'proprietatile 'Structurii.de tip stiva : .unapel genereaza o operatiederip PUSH,.accesul~Ieste permis -doar Ia varful stivei (TOP). jar incheierea-execllliej'genereaza 0 operatiede

ltip POP;LJ .

.Asociativitate

:termeni-precedenti._sunt'suficientetreivariabile : -tennenul curennsi.cei-doi-termeni carepreced termenul .curent. .Objinem-varianta dterativa de calcul"" celui -deal n-lea rermendin 'sirul Fibonacci.

.Din -exempleleprecedente .s-ar l'utea -deduce -,c~ trecursivitateaprezmta memai dez­<avantaje. Acestea au .fost .exemple extrem .de esimple, :pentru .care se putea -descrie .cu~urinlii ,§i°solutie -iterativa. Sli:anaJizlim.acumproblema urmlitoare.

Fie M 0 muhime .nevida §i -*-: MxM ---+ Mo operatie binara asociativa .definita pe multimeaM. .Scrieti 0 functie 'recurstva care sa determine numarul -de.modalitagi in care .se 'poateevaIuaexpresia Xl *X2* ... *Xn ' unde Xl' X 2••••• xriEM. n>O.

De exemplu, -pentru n=3, numarul .de -modalitagi jn carese poate evalua -expresiaX l*X2*X J

este 2 :Xl* (x2*x J ) sau (X l * X2) *xJ •

Pentru n=4. numarul de modalitat! deia -evaluaiexpreaia x l*x2*xJ*x 4 este 5:( (Xl *x2 ) *xJ ) *x4 san (Xl *x2 ) * (X 3*X 4 r sau (Xl * (X 2*xJ ) ) *X4 san Xl * ( (X 2*X 3 ) *X

4)

sau Xl * (x2 * (X 3 * X4» ·Problema estetnsa de a calcula numarul de posibilitati deevaluare pentruorice

numar natural n.Observam, inprimul rand. ca pentru n=lsau n=2 ,00 exista decat 0 singura posibilitate

(acestea sunt cazuri elementare), Daca ne-z, pentru aevalua produsul Xl*X 2* ••• *Xn'trebuie sa aplicam asociativitatea ~;i sa impartim termenii in doua, grupandu-i intreparanteze: (Xl *X2* ... * X k) * (X k+1 * •.• *xn). Vom evaluaapoi parantezele, urmandsa efecruam operatia * Intre rezultatele obtinute in urma evaluarii parantezelor, ~

Notam cu P (n) numlirul de posibilitati de a evalua °expresie cu n termeni. Impartindtermenii la pozitia k (l';k<n), deducem eli: P(n)=P(k) XP(n-k) (pentru oricemodalitate de evaluare a primei grope de k termeni se.poate asocia 0 modalitate deevaluare a celei de a doua grope de n-k termeni). Cum imparnrea se poate face in oricepozuie x, incepand cu pozitia I pAna Ia pozftia n-I. deducem urmatoarea formularecursiva de calcul pentru P (n ) :

III

1\"'II)!k.l~,

'III~',i" "" I; II I

'1!1~:B~II ,"'llj, "::1:

11I

"ir'l"n\"~~"::::'! i! I~l i1fir'!lit,

17

dacam=O

dacln=O

altfel

.RECURS1VITATE

{

n + l ,ac (m,n)= ac (m-1.1),

ac (m -l,ac (m,n -1)),

{a,

cnundc (a,b)= cmmdc (b,a%b),

unsigned Cmmdc(unsigned X, uns~gned yl

:if (! y) return X;

xeturn Cmmdc(y, x%y);

.i.nt main ()unsigned a, b;cout; « "a, b= If, cin » a » b;cout « "c.m.m.d.c. ("«a«", "«b«")= "<xcmmdc La , b);

l' #include <iostream. h>

:,

SoliqieLa lnceputul exercitiilor de programare am descris 0 varianta iterativa a algoritmului luiEuclid. Putem defini In mod recursiv functia cmmdc: N X N -> N astfel :

daca b=O

dacab s-D

Calculul celui mai mare divizor comun,adoua numere naturale

Date a ~i bEN. scrieti 0 functie recursiva de calcul.al celui mai mare divizor comun at-numerelor a ~i b folosind algoritmul lui Euclid.

4. Aplicapi

xeturn 0; }

Funcfia AJ:keT71Ulnn

Evaluati functia Ackermann pentru m ;;;i n numere naturale date.Functia Ackermann este: ac : N X N -> N,

ExercijiuDescrieti 0 'functie iterativa care sa determine nnmarulde -modalitaji :in care se poate:evaluaexpresia x1*xi* ... -*xn ' undex., x 2• ~ ..• XnEM. n>O.

in.capitolele urmatoare (,..MetodaDivide ..et.imperd'''.§i~etoda.Backtracking") vomstudia §i.alteprobleme.:a carer rezolvare in termeni -recursivieste relativ .shnpla, in timpce o solutie .iterativa este mai dificil .de implememat.

dacan:S;2

daca n>2

PROGRAMAREA <IN LIMBAJUL'c/C++ 1'EN1'RU L1CEU

Punctla recursiva care rezclva problema este :

II ,

p{n)~ n-l1: P(k)· P{n- k),

k=1

unsigned ~ong P(int n)

(

J.ong S=O;i.nt k;

if (n <= 2) return 1;for (k=1; k<n; k++)

S += P(k)*P(n-k);return S;

'16

III

c-'

!I~I

I"

t!

,~i

ilt!'

~' "! ~i i~!~ll."~IiI.:ij,ll'

Ii)" ~

'~."',i.l'''I'i IIiI,"

11

'1," ,',.'1.,'II''I, \ I~i,-!I~t

11~"

11,11',111

J111'

"111,',,1,1.III!,: r'

·l'f,:,1"ji,iil,1

,I, illj,~,:1m~l\

19·RECURSIVITATE

cout -« '''n= "", cin » n;

for (int i=O; i<n; i++) cin » a[i];

cout « "x=", cin » x;

cout « x«" apare in sir de "«Numar(1)«" ori.\n";:return 0;

j.-f (i==n) zeturn 0;.i-f (x==a[i]) xeturn --1+Numar(i+1.);.xeturnNumar(i+~);

:int main ()

:int Numar (int i)

Fie ecuatia de gradul al doilea x 2-s'x+p=O cu 5, pER §i n E N. Fara a calcularadacinile Xl si X 2 ale ecuatiei, sa se calculeze sn=X I n+x 2'',

InmuIrind prima relatie eu Xl n. iar pe cea de a doua eu x2''. obtinem :

Xl n+2_s'X I O+l+P'XI0=0

X2

0+2_S' X 20+I+p'X

20=0

Suma puterilor riidiicinilor .

Soliqie

lnrrucat Xl si x2 sunt radacinile ecuatiei, au loc relatiile :

X12-S'X

I+p=O

X 22-S'X

2+P=O

ObservatieDeoarece la fiecare apel recursiv se utilizeaza aceleasi valori pentru a, n , ~i x, nu Ie-amtransmis ca parametri, ci le-arn considerat variabile globale. Aceasta tehnica, prin carereducem numarul de parametri alocati pe stiva, reprezinta 0 importanta optimizare asubprogramelor recursive.

Exercitiu

ApeluI Nurnar (1) din programuI precedent va avea ca efect parcurgerea veetorului a dela inceput catre sfarsit. Modificati prcgramul astfel incat parcurgerea sa se realizeze dela sfarsit carre Inceput.

nn.... ,........ ~ ........... A iN LIMBAJUL CIC++ 'PENTRU LICEU

~signed ~ong .ac(unsignedx, ~nsigned -y)(

-;ffinclude ·<iostream.h>

.if (Ix) zeturn y+1;if (!y) xeturn ac(x-1, 1);xeturn ac(x-1, ac(x, y-1»;

int main ()

unsigned m, n;

cout « "m= ", cin » m;cout « "n= ", cin » n;

cout < "ac tv-c-cm-cco, "<xn-c ")= "< ac(m, n)-«endl;return 0;

O.SOIUJie

~,

I,~ __1

IIU

,.....,

Varianta recursiva a functiei Ackermannnecesitii un timp indelungat de calcul,determinat de numarul mare de apeluri recursive, precum §i un spatiu mare de memorie,

r;leterminat de ..adancimea" recursivitatii, functia fiind folosita ca un test al calitatii! rnplementarii recursivitatli in limbajele de programare.L.J

I 1, IL..... 18 ......, .....u.<\.rUv~. ~

rTVumiirareii,

l. 'Fie a l • a 2' ••• , an un sir de n .(0 < n < 20) numere intregi §i x un numar intreg. Scrieti 0

,-functie recursiva care sa determine numarul de aparitii ale lui x in sir.: is..lolutie

~deea este simpla : comparam x cu primul element din sir; daca sunt egale, numarul deI paritii ale lui x in sir este 1+ numarul de aparitii ale lui x in restul sirului ; daca nu sunt1. _~ale, numarul de aparitii ale lui x in §ir coincide cu numarul de aparitii ale lui x inrestul sirului,

n Parcurgerea sirului poate fi realizata cu 0 functie recursiva care va avea ea parametrui ;ozitia elementului curent din sir.

Jl #include <iostream.h>

, , int a[20], n, x;

nL.J

:11U

Anagrame

1. Un cuvanr este anagrama altui cuvant deca el contine aceleasi litere cu eel initial, eventual Intr-oalta ordine (de exemplu, "armata" ~i "tamara").

Obtinem .urmatoarea relajie de Tecurentapentrusuma-puterilorradacinilor uneiecuatii .de gradul II :

21

~i "_

·RECURSIVITAlE

Fie n E N*. Sa se genereze toate succesiunile de n (n<20) caractere(asemanator eodurilor Morse).

De exemplu, pentru n=2 Yeti afisa :

char x[100], y[100);cout « "x= "; cin.getline(x,lOO);cout < "y= "; cin.getline(y, 100);if (strlen(x) !=strlen(y» cout « "NO!" « endl;

else if (EAnagrama(x,y» cout « "DA!" « endl;else cout; < "NU!" < end!;

int main. (). (

#include <iostream.h>#include <string.h>

return 0;

char *p;if (! e x s s ! *y) ..return l;p=strchr(y, *x); //caut in y primul caracter din x

if (!p) xeturn 0; //nu l-am gasit"*.p=NULL; strcat"(y,p+1) ;//l-am gasit, il sterg din yzeturn EAnagrama(x+l, y);

int EAnagrama(chax *x, char '*y)

Generare

Solutie

Pentru a verifiea dad; 1iirul y .reprezinta oanagramaa '§irului x , verificam daca eele doua.siruri-auaceeasi .Iungime, .ln .caz .afirmativ.-exista '§anse ca sirul y-sa fie o anagrama .a:§irului x ,-'Functia 'recursiva EAnagrama () ·ttesteaza<.dacaambele :§iruri sunt vide, caz incare tnroarce valoarea 1, deoarece y .este o anagrama a lui x . Daca nu sunt vide, verificadaca prima litera din x -segaseste sau nu in y. .ln.ceaafirmariv, elimina.dln y prima litera.din x si se reduce problema Iaverificarea sirurilor x+l§i y, doua siruri de lungime maimica. Altfel, Tunctia EAnagrama () intoarce a .intrucat am gasit 0 litera in x care -nu estein y.

cin»s»p;

daca n e o

daca n e L

dacin>l

"Introduceti coeficientii ecuatiei ";"n= "; cin » n;

cout « "S("«n«")="«Sum(n)«end1;return 0;

int n;

cout «cout «

insumand cele ·doua -relatii, -obtinern :

-PROGRAMAREA iNLIMBAJUL C/C++ ·PENTRU LICEU

8n+2-s·sn+1+p,sn=0

(Xl n -+2+X 2nt2) -5· (Xln+l+X~n+l)+p. (Xln+xt) =0

Ceea cese poate scrie -in mod echivalent :

Deci, Snt2=s,sntl-P-sn'

if (In) return 2;

if (n==l) return s;

return s*Sum(n-l)-p*Sum(n-2);

{

2'Sum(n)= a,

5' Sum(n -1)- p 'Sum(n -:-2),

#include <io5tream.h>float s, p;

float Sum(int n)

int main ()

20

Exercitiu

Descrieji 0 varianta iterativa de rezolvare a problemei precedente ~i comparati cele douavariante de rezolvare.

iI~

!~I1

i~.~

~

~li~

i!

Fie x , y dona siruri de maximum 100 de caractere. Scrieti un program recursivcare satesteze ·daca sirul y este 0 anagrama! a strului x,

~

}

rI :

,-,

j ~ n E N seris in baza 10. Scrieti un program recursiv de conversie a numarulul naturalL lin baza 10 Intr-o baza d~ta b, 1<b<10.

fofuJie

i !ltru a converti un numar natural din baza 10 intr-o baza data b, se executa impartiriJudeesive Ia baza b, pam cand obtinem catul o. La fieeare nou pas, catul nenul objinutla pasul precedent devine deimparpt. Resturile objinute, considerate in ordinea inversarinerii lor, reprezinta numarut convertit in baza b.

l J#include <iastream.h>void Canversie(int x, int b)n{ if (x)

!! {Conversie (x/b , b);, .c cu t; < x%b;}

1:1

"

I:'

i!

Ili~,I'lii~lIltll

1111ll l­IllqI~,ill1"11'\' 1."1' '1'

i'I'::!;,

lil:111: .j'\Ii!::'I'i ~i, i If1'·1'

ili"1',!tf:III I·,I"" I""

:jill 'I iI:i III"l ,(!

1""1'1\I!~ I 'J'nu-i['i:liiiliiJ

"23:RECURSIVITATE

<fstream.h>NMax 10NrMaxS (l«NMax)

.:i.nt :main ().:i.nt .n , b;

cout « '''_n= "'; . cin»n;

cout « "b= "; cin»b;Conversie(n,b);.%eturn 0;

void Afisare ()ofstream f("Gray.out");for (int i=O;i< l«n; i++) //1« n este 2 la puterea n

{for (int j=O; j<n; j++) f«C[iJ.[j];f«endl; }

f.clase();

int n r C[NrMaxS] [NMax);

-void Afisare();void GenerareCod (int);

.int main (){ cout < "n= 11; cin»n;

GenerareCod (n) ;Afisare () ;return 0;

. :/I:include#define#define

Codul Gray

Vom 'genera-secventele .intr-o rnatrice C ell z'' linii (numarul de secvente binare delungime n) ~i n eoloane.

Observam ca pentru n=l, c 1 =[~J

Daca presupunem ca am determinat eodul Gray de Iungime n (cn) ,

pentru a genera codul Gray de lungime n+l, plaslim pe primele z"linii~i n eoloane Cn' completand coloana n+1 eu o. Urmatoarele 2nIinii lecompletam oglindind cn pe primele n eoloane si completand coloanan+ 1 eu 1. tn acest mod, se respects conditia ea orieare doua Iinii sadifere printr-o smgura pozitie,

[

rc:l 0]CJ=Cn,'~ ..~ r

Fie n E N*.Sa se genereze toate secventele binare de lungime n .astfel .tncat orieare donasecvente consecutive sa difere primr-o singura pozitie (codul Gray de lungime n),

.Soliqie

GenCod (i+l) ;

GenCod(i+l);

PROGRAMAREA iN LIMBAJUL C/C++ PENTRU LlCEU

cout«a«endl;

a [i] =' . ';a [iJ =' ';

if (i==n)el.se

GenCod(O);return 0;

j'22

nSo1uJie .

J ,!Vomreprezenta o:succesiuneintr-un·vector a-de n .clemente. Generarea 0 vom face .cuajutorul unei functii 'recursive, GenCod ( ) _. Functia -va.avea 'lUn:singur,parametru,.L, -care

~indiea pozitia -curenra in vector. Daca parametrul i -este.egal ,eu .n , lungimea :suceesiunii'[ cerute, .deducem .ca lnveetorul a am .objinut-o .solutie, -pecare ·0 .:afi§:am. Daca 'Len,

.trebuie sa ocupam pozljia i dm vectorul.a (mai :intaicu.." ."'.,apoi -cu.,,_-"),-apolgeneramin mod 'recursiv resnu succesiunii (apelam GenCod (i+.l».

r-"',i' #include <iostream.h>I I. B char a(20);

~ int n;\ i, 'Ijl "Void GenCod (.int i)

'I1 I

li :

i .~I int main ()

!! cout.« "ne "; cin»n;IIIfi, !

1 jConversie

Date de intrare

Desert

Cerirud

Scrieti un program care sa determine distanja maxima pe care 0 poate parcurge IndianaJones eu benzina gasita la oatil.

'.l··i.l:'1,II!!1:11 i

lilr....~ ,I~, I

II.. ~I·l"..J'...., II '"'Rl' I 1

11~!\1I•..I: ., 1'1"III"

111li

Ill(.II!"

'II~~l'I1ld.'1 1

ri~1:1~·! !

25

desert.out76.000

desert.in4 3 10

Olimpiada Municipala de Informatica, Iasl, 2003

RECURSIVITATE

desert. out60.000

desert.in2 3 10

Solutie

Pentru a ealcula distanta maxima care poate fi parcursa avand la dispozitie n recipientevom utiliza 0 functie recursiva di s t ( ) .

Data la oaza exista un recipient, acesta va fi tumat in rezervor, iar distanta maximace poate fi parcursa ell el este k/p . Daca -la oaza exista doua recipiente, unul va fi pusin rezervor, celalalt va fi pus in masina Si astfel se parcurge distanta 2*k/p.

Daca numarul de recipiente este mai mare de dona, turnam continurul unui recipientin rezervor, al doilea recipient il punem in masina §i parcurgem 0 distanta x, lasamrecipientuI plin aici, dupa care ne intoarcem la oaza. La oaza punem in masina altrecipient, parcurgem aceeasi distanta x , lasam recipientuI plin ~i revenim la oaza. Dupa2n-3 astfel de drumuri, la distanja x de oaza se afIa n-1 recipiente pline. Vom calculadistanta x astfel meat dupa 2n-3 drumuri de lungime x rezervorul masmii sa fie gol (x:=:k/«2*n-3) ep j }. Suntem tmr-o situatie similara en eea mitiala : rezervorul masinii estegel, avem n-1 recipiente eu benzina, dar am parcurs deja 0 distanta x.

#include<stdia.h>#define InFile "desert. in"#define OutFile "desert.out"

int n, k;

long double p;

int main ()FILE *fin, *fout;long double d;

long double dist(int n)

( if (n<=2) return k*n/p;return k/({2*n-3)*p)+dist(n-l);

Exemple

Restrictii

Date .de .iesire

Fi§ieruI desert.. au t contine '0 singuralinie pe care-estescrisunnumar real reprezentand-distanta maximlice 1'0ate fi parcursa de Indiana Jones, exprimatain ldlometri.

.. 1::::;N$100

.. 2':::;;K$SO.. S':::;;P':::;;20

.. Distanja maxima parcursa va fi afi§ata ell trei zecimale, cu rotunjire.

f

eu 1 coloanax-l

PROGRAMAREA iN LIMBAJULC/C++ 'PENTRULICEU

GenerareCod(x-l) ;£or (int i=(l«(x-l»-l;{>=O;i--)

Iloglindim C(x-l) si~ompletam

{:for (.int j=O; j<x-:l; j++)

C[(l«x)-i-lj [jJ~C[il [jl;C[ (l«x)-i-l] [x-.l)=l; )

.e.Ls.e

24

~ 'Void GenerareCod (int .x)

i { .if (x~~l) C[l) [Oj~l;

I

De exemplu, pentru n=3. fisierul de iesire GRAY. OUT va fi :000100110010011111101001

Indiana Jones trebuie sa salveze Chivotul Legilor din mainile nazistilor, EI a ..rechi­zitionat" 0 masina eu care a reusit sa ajunga, ell ultima picatura de benzina, pana la 0oaza. Din fericire, in aceasta oaza, nemtii au undepozit de combustibil. Combustibiluleste stocat in N recipiente de capacitate K Iitri. Masina lui Jndiana Jones are un rezervorde capacitate K litri si un portbagaj in caremaiincapeexactunrecipientde-Klitri.Lafiecare 10 0 de kilometri masina consuma P litri de benzina.

Fisierul desert. in conrine 0 singura linie pe care sunt scrise trei numere naturaleseparate prin cate un spatiu :

desert.in I SemnijlcapeN K P N - numarut de recipiente ;

K - cati litri de benzina sunt intr-un recipient;P - cali litri de benzina consuma masina la 100 de kilometri.

~ I

r'j

I i

27

Olimpiada Municipala de Informatica, Iasi, 2005

RECURSIVITA'IE

vo~d citire(void)int i;FILE * fin = fopen (INPUT_FILE, "r");fscanf (fin, n%d", &N);for (i=O; i<N; ++i)

fscanf(fin, n%d %d %d %d", &f[i].ls, &f[i] .cs,&f(i] .ld, &f(iJ .cd);

fclose(file) ;

#include <stdio.h>4I:define INPUT_FILE "win. in"#define OUTPUT_FILE "win.out"#define NMAX 100

int N; lIN reprezinta numarul de ferestrestruct { int Is, Id, cs, cd;} f[NMAXJ;Ilf - vector Cll N componente in care retinem ferestrele

~nt inchisa[NMAX];1* inchisa[i]=O daca fereastra i este deschisa,

respectiv 1 daca fereastra i este inchisa *1~nt rez;1* rez - variabila globala in care calculam numarul total

de click-uri necesare *1

"in. .in -'win. out -win.in :w:i.n.out win.in win.·out

3 3 3 3 3 1

3 J. 6 4 4 1 6 3 334 4

124 6 2 2 5 5 , 1 1222 355 1 4 3 6 5 5 6 6

Solutie

Vom reprezenta 0 fereastra ca 0 srrucrura eu patru campuri : coordonatele coltului din.stanga-sus §i coordonatele .coltului din dreapta-jos.al ferestrei. ,...J

Vomaborda problema recursiv : pentru a inchide fereastra cu numarul nr trebuie sainchidem, in prealabil, toate ferestrele deschise ulterior. care acopera coltul din dreapta-susa1 ferestrei nr. Acest lucru este realizat de functia recursiva inchide () , ce are caparametru numarul ferestrei care trebuie sa fie tnchisa. Pentru a nu inchide de mai multeori aceeasi fereastra, vom retinemuttimea ferestrelor inchise in vectorul caracteristicinchisa.

Exemple

PROGRAMAREA.iN LIMBAJUL c/c++ PENTRUUCEU

£in=£open (In"File, '''xt''') ;

:Escan£ (fin, "'%d %d %Lf", .sn , &k, _&.p);

£close (rin) ;p~p/100;

d=dist(n);£out=£open(OutFile, '''we'');£printf (fout, ''''%.3Lf\n'', d);£close (rout) ;xeturn 0; }

-rO< NS;1 0 0

.'1 ;1'::::;R1S;R2S;10000

-; .J.'::::;Sl::S:S2::S:10000

Date de intrare

ri§ierul de intrare win. in contine pe prima linie un numarnatural N, reprezentandL.u..unarul de ferestre deschise pe ecran.

Fieeare dintre urmatoarele N linii contine cate patru numere naturale separate prinr.te un spatiu, Rl, 81, R2 ~i 82, eu semnifieapa"am deschis 0 fereastra care are coltul! :n stanga-sus pe linia Rl §i coloana 81, respectiv coltul din dreapta-jos pe linia R2 §ilcoloana 82". Ferestrele se deschid in ordinea in care apar in fisierul de Intrare.

i'zre de iesire! jFisierul de ie§ire win. out va contine 0 singura linie pe care va fi scris numarul minim~click-uri necesare pentru a Inchide prima fereastra deschisa.

••LstriClii

r.WindowsI I

l -Vasilefoloseste un sistem de operare care deschide ope ecrannumeroase .ferestre, EcranuIeste tmparPt in patrate elementare (care au aria 1 »L), .formand un caroiaj in care liniile

i"sunt numerotate 'de la 1 de sus in jos, iar coloanele sunt numerotate deIa 1 de la stangaI \a dreapta, Astfel, fiecare patrat elementar de pe ecran poate fi .identificat specificand' .numilnIl Iiniei sinumarul coIoaoei pe care seafla, Fiecare fereastra este un dreptunghirfIDlat din unuI .sau mai multe pan-ate elementare. a fereastra nou deschisa poate sa se

I iuprapuM (partial sau total) peste .alteferestre, ,deschise inpreaIabiI. Putem lnchide 0

, .ereastra daca executam un click in patratul elementar ce constituie coltul din dreapta-susal ferestrei (daca acesta este vizibil),n Scrieti un program care sa determine numarul minim de click-uri necesare pentru al jehide prima fereastra pe care am desehis-o.

II

l i26-

ni 1

nnl j

Restaurarea unui opel de functie

Se citeste din fisierul f. in un sir de maximum 100 de caractere care reprezinta 0

succesiune de nume de functii §i variabiIe, formate dintr-un singur caracter. Pentrufiecare functie ce intervine in sir se citesc numele §i aritatea (numiirul de argumente) depe 0 linie din fisier. Restaurati sirul de caractere, punand la locul lor parantezele §ivirgulele, astfel tncar sa reprezinte un apel de functie eoreet.

''')

~ ,. 1

!i ~II11 '

1

'1, ili'li, '"

i!~"" ,.11:·,1I:' I'"III~; ,'!',llr~:,\,f,q~t 'J

,:~~~l,rl[111 ", \

II :[;: u 1I! d I

III' i"liAr

1,11,[ ,'il

Illi:1"'):1'h i

'I' H '",; 1

"'I',l,~. :H,\,!

!',,1

11' 1, ,~

""-1

"I'l'",!i;\1 1

',,1' i"IU :

Illii',!,,,:III'I:j:j.i\

29RECURSIVITATE

De-exemplu, -pentru fisierul de mtrare :-£xgxyzhxof 3

g 3h 1

functia -resreurata -va fi :f(x,g(X,y,2),h(x»

Solutie

int main ()int i=O;Ci tire () ;Restaurare(i) ;return 0;

Observatie

Solatia se bazeaza in mod esential pe faptul ca datele de intrare sunt corecte (deci apelulde functie poate fi restaurat).

#include <fstream.h>#define NrMaxF 100char NF[NrMaxF]; //NF contine numele fiecarei functiichar 5[100]; /lsiru1 care trebuie restauratint AF[NrMaxF); IIAF contine aritatea functiilorint NrF; IINrF - numarul de functiivoid Citire();int AR(char);void Restaurare(int ~);

VOID memora datelede .intrare in doi veetori: NF, in care retinem numele functiilor, inordinea din fisierul.de intrare, §i AF ~ in care retinem aritatea fiecarei functii (numarul de.argumente). Pentru a restaura apelul de functie din sirul de caractere, citit de pe primaIinie.a fisierului de intrare, vom utiliza o functie recursiva denumita Restaurare () ,care are un singur parametru (L), ee indica pozitia la care am ajuns cu restaurarea in sirulde intrare.

in functia Restaurare () venficam daca pe pozitia i in sirul de intrare este un mimedefunctie, Daca CIa, se serle numele funcnei. urmat de" ("" dupa care se restaureaza (cu.ajutorul functiei recursive) fiecare argument al funcjiei, separand argumentele prinvirgula, Numarul de argumente se obtine din vectorul AF. Dupa ultimul argumentrestaurat se inchide paranteza (se scrie pe ecran ,,) ").

Daca pe pozitia i in sirul de intrare nu este 0 funcjie, se scrie pe ecran caracterulrespectiv (este 0 variabila).

r

nr -*/

0;i++) inchisa[i)

return 0;

;'PROGRAMAREAiN LIMBAJULC/C++ PENTRU J:..1CEU

,'%eturn 0;

++rez;

'void inchide (int nr)

{/* functia inchide fereastra cunumarul£or (int i=N-l; i>=nr+l: i--)

if (!inchisa[i] && peste(i, nr»inchide (i) ;

inchisa[nr];::l;

void rezolvare(void)for (int i=O; i<N;rez = 0;

inchide (D) ;

void afisare(void)

{ FILE * fout = fopen (OUTPUT_FILE, "w");

fprintf (fout,"%d\n", rez);fclose(fout);

int main (void)

ci tire () ;

rezolvare();afisare () ;

28

I int peste (:int .e , ::i.nt ,b)

,

/* .Iunctia .xecuz-neeae valoarea :l daca fereastra .ra vea-t.e -peatie

.coLtul din .dxeap t a-csus .a'L 'ferestrei .b.si Din caz contrar ""* /(.if (f[a) .ls .<= "f[b] .. J.s && £[a] .•.Ld >= .£[b] .•ls.&&

.; f(a] .. c s ._<= f[bJ_cd .&& .r Ie j c cc c-« --f[bJ ...cd),I Ieturn :1;

f

III

II

III

kterciJiu

Modificati programul astfel tncat sa testeze daca restaurarea este posibila,,"""l }magine

Ma consideram 0 imagine alb-negro de dimensiune LxL pixeli. Un pixel poate fi albI !codificat cu valoarea 0) san negro (codificat cu valoarea 1). Imaginile pot fi compresateL.-'lh diverse moduri. Una dintre cele mai cunoscute scheme de compresie este urmatoarea :

~. Daca imaginea este fermata atat din pixeli 1. cat §i din pixeli 0, se retine valoarea'[ , 1, care indica faptul ca imaginea va fi partitionata in alte patru subimagini, asa cum.1 este descris la pasuI2. Altfel codificam intreaga imagine ea 00 sau 01, semnificand

faptul ca intreaga imagine este fermata numai din pixeli 0, respectiv numai dinr-: pixeli 1.i !, "

"P.ROGRAMAREkiN ,LlMBAJUVCIC++ PENTRU L1CEU

'Void~itire ()l-i:fstream :f("'f~in") t

:char 'C;

±nta;

I_getline(s, ~OO);

whi~e Cl.f_'eof () )( .f»c»,a;

~F[NrFJ=c; AF [NrF++] =a;f. close () ; }

iiil;

('I!i."IfI~I',!lt,!,Ill'IW~J~'li-)::,Ii'"Ii!"),'I":1![~:I,n,~:,

i'II!",I,:'"I,'! 'I

I it: l,:~

:,1,':

ii"',"·I:,:{

1

!,!li,H,If 1;11"

'I];j~(,:,;!.Q)'i'I'"

!I'fi'i''\I!'!Ilil:

'J'i!:.1),lJI'~

31

'fBlDl~

I ~

RECURSIVITA'IE

D

Fisierul de iesire imagine. ou t contine 0 singura linie pe care se afla un numar naturalce reprezinta dimensiunea imaginii compresate.

Fisierul de intrare imagine. in contine pe prima linie numarul natural L. reprezentanddimensiunea imaginii. Urmatoarele L .linii contin imaginea codiflcata, fiecare liniecontinand exact L valori 0 sau .1, separate prin cate un spatiu.

Restrictie

1';;L';;240

Exemple

imagine. in imagine.out imagine.in I~magine.out4 30 81 1 1 1 o 0 0 0 1 1 1 11 1 0 1 o 0 0 0 1 1 1 1o 1 0 0 o 0 0 0 1 1 1 1o 011 o 000 1 1 1 1

1 1 1 1 1 1111 1 1 1 1 1111 1 1 1 1 1 1 1111 1 1 1 1 1

Date de iesire

Date de intrare

2. 0 4magine.:I .este imparpta In patru subimagini A,:B, C, n dupa .cum ·este ilustrat infigura urmatoare :

,Apoi se aplica din nou pasul 'I, -pentru fiecare dintre cele patru subimagini, ,in ordinea

A,:B, C. J).

Numarul de biti (cifrede osau 1) obtinuti in urma compresiei reprezinta dimensiuneaimaginii compresate.

Data fund 0 .imagine, ~a se determine dimensiunea imaginii compresate.·

reprezinta un nume de funetie

//restauram. argurnentele functiei!/separandu-le prin virgule

//s[iJ

& i)

t ccue-cc : {'i

for (j=l; j<k; j++)

(Restaurare(i);cout«',';

Restaurare(i);cout-cc ") "s l

oint AR (char c)

{//£unctia intoarce 0 daca cnu este un nume de functie,Ilrespectiv aritatea functiei, in caz contrar£or (int j=O; j<NrF; j++)

if (NF[j] == c) return AF[j];:return O;}

void Restaurare(~nt

(int k, j;

cou t c-cs [i] ;

k=AR(s [i++]);

if (k)

30

n, .... J

~i ]

ni I

I J

nI j

r

nL. j

n11

nL j

Expliccqii .1. Compresia imaginiidin .exemplulI .se realizeaza .astfel :

[1 ~ ~ 1]~ ~ ~ ~ =1(~ ~) G~) (~~) G~)o 0 .i ~

~1 1 CO) CO) (0) (1) 01 ~ (1) (0) (1) (0) 1 (0) (1) (1) (1)~

~1 1 00 00 00 01 01 1 ·01 00 01 00 1 00 01 01 01

'Deoarece dupa compresare suntnecesari 30 ·de hip. dimensiunea imaginii compresate-este 30."2. Compresia drnaginii din exemplul 2 'se realizeazaastfel :

0 0 0 0 1 1 1 1

0 0 0 0 1 1 1 1

0 0 0 0 1 1 1

1 [1

1 1

~m0 0

~w1 1

~w1 1

~]0 0 0 0 1 1 1 1 1 1 1 0 0 1 1 1 1

~1

1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1

1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1

1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1

~ 1 01 00 01 01

In accst caz, dimensiunea imaginii compresate este 9.

OIimpiada Municipala de Informatica, Iasi, 2005

SolutieTextul problemei sugereaza 0 maniera recursiva de rezolvare a acesreia.

Orice imagine este definita prin coordonatele colturilor stanga-sus (xt , yi), reapectivdreapta-jos (x2, yz). Functia recursiva care determinil.num1irulde biti ai imaginii compresateare ca parametri coordonatele ccljurilor. Initial, aceste valori sun! 0, 0, n-1, n-1, indicandccljurile din stanga-sus (0, 0), respectiv dreapta-jos (n-1, n-1) ale imaginii iniliale.

In functie este apelata, in primul rand, 0 nom functie care verifieil. daca toli bitii dinimaginea definita de coordonatele (xl, yL, xz , y2) sunt identici. Acest Iucru se poateface, de exemplu, comparand top bitii din accasta imagine ell primul bit din ea.adica eeldefinit de coordonatele {xL, yt), transmis, de asemenea, ca parametru. Daca toti bijiisunt identici, pentru aceasra imagine se vor consuma exact 2 biti, 00 sau 01, deci functiava retuma valoarea 2. Incaz contrar, dimensiunea folosita Ia codificare este egala cu1 + numarul de bitl fclositi pentru cele patru subimagini in care se Imparte imaginea.

Deoarece cele patru subimagini se objin prin injumatatirea repetata a "laturii"imaginii, prima impresie este aceea ca dimensiunea imaginii trebuie sa fie 0 putere a lui2. De remarcat tnsa ca nu in mod obligatoriu cele patru subimagini trebuie sa fie deaceeasi dimensiune. Pentru ca algoritmul sa lucreze coreet, se detertnina mijloacelecoordonatelor xl ~;i x2, respectiv cele ale. coordonatelor yl §i y2, calculand parteaIntreaga, §i se reapeleaza functia recursiva de patru ori, care 0 data pentru fiecaresubimagine, Insumandu-se valorile rezultate.

l~':

'.'.!l1'\~

i.!iIJ..·']',Ii!,!'litp! l

i'~Wili:ii'. _. iill",l. \:1~,j',..J". il:l,I",~,. ,'.\·1'" II" ,

"" I"!I"..'I.',lr···illl;'.:

:\:1 1.11

1 ,i,' I

lj'l"'. I,I;,r} Iq,'.....1',·1, '.'.'..'Ill',l·t,,!,j11'1 1·'Iifl,!"· :"1'[~ \ 11 ~ :', ;

1;',I\{'i '1LIII"!: :hl,\,! i!iill l..-J

'1 111\.1:!;ii::\:~;Aili!

33

2 biti

int y2)

RECURSIVITA1E

int Mijloc_x, Mijloc_y;if (pixeliEgali (xl, y1, x2, y2, imagine [xl] [yl] ) )

Ildaca toti pixelii sunt identicireturn 2;llpentru aceasta zona se utilizeaza

.ef.ee

(Ilirnpart imaginea in patru subirnaginiMijloc_x = (x1+x2) 12; Ilmijlocul pe orizontalaMijloc_y = (y1+y2)/2; (Imijlocul pe vertical a

Ilapoi, evident, numarul de pixeli necesari esteIII+suma pixelilor necesari pentru cele 4 subimaginireturn l+Lungime_Comp(xl, Mijloc_y+l, Mijloc_x, y2)

+Lungime_Comp (Mij loc_x+l, Mijloc_y+1, x2, y2)+Lungime_Comp(xl, yl, Mijloc_x, Mijloc_y)+Lungirne_Comp(Mijloc_x+l, yl, x2, Mijloc_y);

-int i, j;£or (i=xl; i<=~2; i++)

£or (j=yl; j<=y2; j++)if (imagine[i] [j] !=Pixel)

Ilam gasit,un pixel diferit de Pixel

-return 0,return 1; Iltoti pixelii sunt identici cu Pixel

}unsigned ~on9 Lungime_Comp(int xl, int y1, int x2,

FILE ~Fin,*Fout;

char imagine [MAX] [MAX];

int pixeliEgali(int xl, int yl, int x2, int y2, int pixel)Ilfunctia determina daca zona de coordonate Xl, yl, x2, yl

Ilare doa~ pixeli 0 sau doar pixeli 1

#include <stdio.h>ltdefine MAX 250

Dacil.insli o fmagine'este definitll de coltul din stiinga-sus·~iJungimea1aturii (x, y, L),"in ..cazul.:incare L -nueste 0 putere.a lui 2, .la unmoment .dat ,unele:subimagini -pierd.din:dimensiune, :determinarea mumarului-de :hip neces~ .codificariifiinderonat.

De exemplu, :pentruL=31, .la calculareamijlocului laturii vom.obpne L ' =15, ceea.ceinseamnil.eil.·subimaginile, innumlir de patru, vorfidefinite de: (x , y, L' ),(x+L', y,L'), (x, y+L', L'), (x+L', y+L', L'),:adica(I, I, 1.5), (16, 1,1.5), (I, :16, ·15),

(16, ~6, 15). ,Deci, s-au pierdut ·ultima linie ~i ultima coloana de biti .din imaginea initiaHi.

r'PROGRAMAREA -iNLIMBAJUL C/C++ .iPENTRU UCEU32

.r-,'Ul mediilor nritmetico-geometrice al lui Gauss" ,, ,

FIe' doua sirurl (an) neN, (bn) neN definite recurent astfeI :

~o=ai bo=b; (a, b>O)i :3.n = {an _ 1 +b

n_

1} /2

I b =sqrt (a -b )n n-l n-l

~crieti un program care sa calculeze an §i bn

• pentru neN citit de la tastatura.

~O Reenrsivitateindireetiii I, ,

l-_~ursivitatea se poate realiza §i in mod indirect,atunci cand in cadrul blocului uneifunctii apare .apelul uneialte funcjti care, 1a randul sau, apeleaza direct sau indirect

i;Jnctia respectiva. .

I ! De exemplu, sa presupunem eli in functia A () intervine un apel al functiei B () , inLulncpa B () intervine un apel al functiei c () • iar in functia c (), un apel al functiei A () .

r L~nctia"A ',!"J..-J Fu~ctia C ( )JI 1 "'j ..;7if

Functia B ( ) ~'- -~I

l J Observati ca functia A ( ) se autoape!eazil, prin intermediul funcjiilor B() ~i c () . Prinurmare, functia A () este indirect recursfva.

r,1 I A I' to'L.' p lea II

.~

~!.f

IIil

~ "~~~I';:· 'II, .',iA'1\. !}~ !:~..,I

!!H/ 1, ,

'II'" p,\ 111k!,tl

I!,II 1·J~_l ~I11,r'<'!1j':.:lltf~l~'!: liIftl.i'l1;J~I"l~!, ii, : ~~

Illili:"il··,1"'IL'\1'(1 ',1

Ildlllll!

Iii' , ''1,-''I~ "-"

"

ilk1

1

/

1":,J:in

I~' I I "I .1'1'"!;:I~ I[li;

ri ' i II~: ~dillf; I1,1

1'."1':i 1; (Iill' ~

jlojll-":'l.l~Hi;;fJ'~~n'ijI;11;:III""

n;llr:\{j) ';'j

m1!h.i'i:'P

!I'iii,

j~-!:r tl':

'lSRECURSrvITATE

#include <conio.h>il:include <dos.h>

int i=li

voi.d InSus{);

Deplasarea pe ecran a unei bare

Exercitiu

Executati programul pentru valori mari ale lui n. Ce observati ?

£looat a (int n)if (! n) return aO;return (a (n-l) + b (n-l» /2;

flo oat b (int n)

{ if (! n) return bO;return sqrt(a(n-l) * b{n-l»;}

Sa se simuleze deplasarea pe ecran a unei bare colorate, intre partea de sus ~i cea de josa ecranului, folosind 0 functie pentru deplasarea in jos si una pentru deplasarea in sus.In momentul atingerii uneia dintre margini, bara l§i continua deplasarea in sens contrar.

int main (){cout «"a, b, n= "; cin » aO » bO » n;cout «"b("«n«")="«b(n)«" a("«n«")="«a(n)«endlireturn 0;

, ,

£J.oat a (int) ;£J.oat b (int) ;

int n, aO, bO;

sotutieObservam ca pentru a.calcula termenul .de rangn din sirule sunt necesari aermenul.derang n-l .din -§irul a, .deci -va -fi apelata-recursiv, iD. mod direct, functia -care calculeazatermenii sirului a, cu parametrul n-.l, precum.si termenu! n-ldin~iruI.b.Va·fi~pelatii

functia care calculeaza termcnii __sirului js cu parametruI n-l, .care, 'la'randulei, va apeladinnou .recursiv (in mod indirect) funcpa ce calcujeaza a n_2

§i functia care calculeazab

n_

2etc.

#include <iostream.h>#include <math.h>

n-l» ;

DO('\r::!D A lU' A D'C A 'iN LlMBAJUL CIC++ ,PENTRU LICEU

oint .ma.Ln ()

intn, .L, j;

Fi-n = :fopen (" Lmaqd'ne , Ln" I ''',rt'''};£scanf (Fin, '''%d'', .&n);

£or (i.=Oi i<n; 1++)

.£or (j·=Oi j<n; j++)

£scanf(Fin, "%d", ,&imagine[i} [j]);fclose (Fin) ;

Fout =fopen("imagine.out", '''wt'');

//apelez functia de calculare a numarului de pixeli//necesari pentru intreaga fotografie

£printf (Fout, "%lu", Lungime_Cornpresie (0, 0, n-l,fclose(Fout);.return 0;

i r,

rl ,

r!

r'i .,I .

lJ

I Il j 34 •__._.. •

.Observatie

Am ales pentrusimplitate expresiiaritmetice pentru care operanzii sunt formaji dintr-un.singur caraeter• .jar -operatorii pot fi -doar + .~§i -'"k .• De asemenea, -nu .se accepta .spatii.Aceste restrictii nu sunt semnificative.

.Scneti .unprogram care-sa cneasca,-de.Iaaastatura, .un.sirde .caracrere si.sa verificedaca sirul .reprezinta o expresie.aritmetica aintactic corecta.

.Solutie

Yom.descrie care 0 functie de .analiza -sintacnca -penrru fiecare unitate stntactica ceintervine in definitia notiunii de expresie : :factor, termen, expresie. Observati ca pentrua analiza sintactic 0 expresie este: mecesara apelarea functiei de analiza sintactica atermenilor componenti, pentru .a analiza un termeneste -necesara .apelarea functiei deanalizasintactiea a unuifactor, iar functia de analiza sintactica a unui factor poate apelafuactia de analiza sintactica .a uneiexpresii.

36 PROGRAMAREA'iN LIMBAJUL -C/C++ ·PENTRU.LICEU

'Void InJos () ;

:.:i.nt meLn ()

.InJos () ;

:return 0:

void InJos ()

{

if (++i== 25) InSus{):

~~se //sterg ecranul si redesenez bara{textbackground(O); clrscr();

window(!, i, 80, i); textbackground(5); clrscr();del~y(500);

InJos();}

rRECURSIVlTATE . 37

InJos () ;

void InSus ( )

if (--i == 1)

e~se

textbackground{O); clrscr();

window(!, i, 80, i); textbackground(S); clrscr();delay(SOO);InSu5 () ; }

#include <iastream.h>#include <string.h>#include <ctype.h>

char e[200], op[]="0123456789abcdefghijklmnoprstuvx y z";int 19, i; ND;

int ValidareExpresie();int ValidareTermen();int ValidareFactar();

Exercitiu

Modificati programul astfel meat barn sa se opreasca Ia apasarea oricare! taste.

int'ValidareFactar()tint r=l;i.f (e[i]==1 (') Ilfactorul e a expresie intre paranteze

{ND++; Ilnurnar 0 paranteza deschisa care nu e inchisai++; Iltrec peste' (I

r=ValidareExpresie(); Ilvalidez expresia din parantezei.f (! r) return r; Ilexpresie incarectaif (e[i] !=') I) Ilparanteza este inchisa carect?

{cout«"Eroare! Pe pozitia "«i« " este necesara )";

r=O; }e1se

int main ()cout «"Introduceti expresia "; cin.getline(e,200);

19=strlen(e) ;if (ValidareExpresie(»

cout « "Expresia este sintactic corecta!\n";return 0;

constanta "1 citra r----

variabiUi. .. , fiterii r--.

con

factor

Verijicarea corectitudinii sintactice a unei expresii aritmetice

Numim expresie aritmetica 0 constructie definita prin urmaroarele diagrame de sintaxa :

expresie~ b- termen I I7n LS;)r ~ •stan

IFerciJiullViodificati programul asrfel.incat sit permita utilizarea in cadrul expresiei a constantelornaturale, .intregi, reale Si a variabilelor pentru care nurnele respecta sintaxa unui Identi­[lator CIC + +, jar spatiile care apar in expresie sa fie ignorate.I I.l j

Transformarea uneiexpresii aritmetice in formd polonezd" .i ~nd data 0 expresie aritmedca sintactic corecta, in conformitate cu definitia de Ia~.lJblema precedenta, scrieti un program care sa afiseze notatia poloneza a expresiei (informa postfixata),n~ceasta notatie a fost in~usa d~.ma!ema~cianul polonez J. Lucasiewicz si permite

'S rerea tara paranteze a one] expresn arnmence.l JPie E 0 expresie aritrnetica. Notatia expresiei in forma poloneza postfixata este :

-r-Paca E este fermata dintr-un singur operand, atunci EP=E ;i '[, ,r. ,~

PROGRAMAREA -iN LlMBAJUL CIC++PENTRU LICEU

39

paranteza

paranteze

sau a cifra

'RECURSrvITATE

void TransformFactor()(if (e[i]==' (I) //factorul e 0 expresie intre

(i++; //trec peste' ('TransformExpresie();//transform expresia dini++; ) //trec peste') ,

e~se //factorul este 0 litera

p[lgp++]=e[i++];

int main ()cout«"Introduceti expresia It; cin.getline(e,200);

19=strlen (e) ;TransformExpresie() ;cout«"Expresia in forma poloneza "«p«endl;

return 0;

Observajii1. Notapa-poloneza ;aunei:expresiiaritmetice .nu este .unica..De .exemplu, pentru

E=a+b+c, .aplicand .:asociativitatea adunarii, obtinem E1=a. E2=b+c, caz .in careEP=abc++'.sauEl=a+b, E2=C, caz in care EP=ab+c+.

'2. lntr-unmod .analog ,se poate .defini notapapoloneza a unei expresii -aritmetice informa prefixata (operatoruleste pIasat In fata operanzilor).

#include <iostream.h>#include <string.h>

char e [2001, P [200];

int i, 19, 19p;

void TransformExpresie();void TransformFactor();void TransformTermen();

SolutieVom des erie functii. de transformare in nctatie poloneza pentru fiecare unitate sintacticace intervinein .definitia notiunii de expresie antmetica.

.daca E=E1,a

£2' .unde ;a:este'lllvoperator,.,:iar-E1 ':§i E 2 'Sunt :.eXpresii -aritmetice, atunei

E P=EtE2 P,Q, ,; .<ClacaE= (E 1) .,atunci -EP=E t .De'.exemplu,-pentru expresiaaritmetica 'E= (a +.b) *,(a *c+ b*-d) .,notatiapolonezaeste

.ab+ac'*,bd*+*. .

&& ! ND)

primul factor din termen//mai llrmeaza factori

//trec peste '*'

//trecpeste 1actor

//valiqez primul termen//mai urmeaza termeni

//tr:ec'peste '+'

(i++; I/trecpeste ')'ND--i}} /Iscad ~umarul deparanteze ramase ~eschise

oe~se I/verific .dace .:factorul oeste 0 .litera .aau 0 _~.ci£ra

i£ (Istrchr(op, tolower(e[i]){cout«'''Eroare! Pe pc a.Lt.Le -'''«i«'' trebuie un operand";

r=Oi}:e~se i++:

return Xi

int ValidareExpresie()lint r=ValidareTermen(}:while (r && i<1g && e[i] == '+')

(i++ir=ValidareTermen():}

.if (r && 1<1g)

.if (e[il [= ')1 II e[iJ == ')'

(cout < "Eroare!"; r=O;return X;

int ValidareTermen()tint r=ValidareFactor()i I/validez_hi~e {r && i<1g && e[i] == I*I}

{i++;r=ValidareFactor(}:}

return XiI iI ;

~I II ,

~l i

fr\ i'(

I38

rl

r!! Il j

n! !L J

Evaluarea unei expresii aritmetice

Fiind data: 0 expresie aritmetlca sintactic corecta, scrieji un program care sa evaluezeexpresia pentru valori date ale variabilelor ce intervin in expresie.

Sohqie

in mod asemanator rezolvarn problemelor de analiza sintactica a unei expresii aritmetice§i de transformare a unei expresii in notatie poloneza, vom descrie 0 funcjie de evaluarepentru fiecare unitate sintactica ce intervme In definitia notiunii de expresie aritmetica.

41

cifra

//trec peste factor

//evaluez primul factor//mai urmeaza factori//trec peste '*'

//trec peste ')'este 0 litera sau 0

/Ievaluez primul termen//rnai urmeaza termeni

//trec peste '+'

//factorul

//factorul e 0 expresie intre paranteze/Itrec peste '('

return f;

return t;

int EvaluareTermen()lint f=EvaluareFactor();whi1.e (i<lg && e[i] == '*')

( i++;

f*=EvaluareFactor();}

RECURSIVITATE

int EvaluareExpresie()lint t=EvaluareTerrnen();while (i<lg && eli] == '+')

{i++;

t+=EvaluareTermen();}

xeturn f;

int eval (char c)

{ / /functia intoarce valoarea operandului c.if (c>='O' && c<='g') xeturn c-'O';

/Icaut -vaLoaz-ee variabilei in tabela de simbolurifor (int k=O; TS[kJ.ns != c; k++);xeturn TS [k] . V;

int EvaluareFactor(){int fi

if (e.Ll l ee ' (')

{'i++;

f= EvaluareExpresie();i++; }e1.se{ f=eval(e[i]);

i++; )

"Void _Citire (){ifstrearn fin ("expres ..in'" ).;::i.nt'NrS=O;£in.getl{ne(e,200);lg=strlen(e) ;1Whi~e (!-;fin.-eof () )

{f.in»~S[NrS]_ns»TS[NrSJ .v;NrS++; }

:fin.close{) ;

T..pROGRAMAREA iN LIMBAJUL C/C++ PENTRU LlCEU

void TransformTermen()

-.TransformFactor 0; /Itransforrn primul £actor .aL "tezmenuLuflWh.:i~-e (i<lg.&& e[iJ == "'*') Ilmai -urmea z a factori

i++; //trec peste '*'TransformFactor();p[lgp++]='*';

void TransformExpresie()

{TransformTermen(); I/transform primul termen din expresie~hi~e (i<lg && e[i] == '+') //mai urmeaza termeni

(i++i //trec peste '+'TransformTermen();p[lgp++l='+';

#include <fstrearn.h>#include <string.h~

struct {char ns; int v;} TS[200];char e[200];int L, 19;void Ci tire () ;int eval (char) ;int EvaluareExpresie();int EvaluareFactor{);int EvaluareTermen();int main (){Citire();

cout«"Valoarea expresiei este: " < EvaluareExpresie () ;return 0;

40

--,

11~li I,

l>; ~"

.: 11

1,' .tl~'

~' I .]\ ~ : I

'i ,!tl i"

';~ 11

1;:1 Ii"'1'1'7,/,;':1'Ii, 'I I'

t11":11,';,': :'11II!n,

:II~:' bf

}~,.r·:~i'!li"j'I,I::.);'1' '1'i ,'., U

1'I'"I: 'i 41,

':'11> ' I:~'~::!I ~(

'I'll "HII1Ij~: 'I "'i'l'IL"III' ,I:,1"111~i!jl'!H:,!j,i1'111Ifil~:" i

"l!,I, ,:~lill,

1!~I:1li! .,':, Ii:

Q'll

' :l.li'l'ill!lf !~t:'ii' ,I,"'J'II''~I.'I ',I,~,(: "{!

, "il,:~:ilt'~ilil:xl'l!!,'

:'!1Tli:.,:,'JlI'i1

i~:il:i:j;i

ll ;

::\'i: !:

:'Ji)',1: ',":1.;".,

;':J t:1, :~, 'I,i[

"',"jl:" ,\1 ~ I;,"'ii

43

Ir e z . ou t .130

RECURSMTATE

OIimpiadaNajlonala de Informatica, Buzau, 2004

Irez.in .R2(RS,R69,R12)R80

I~ez.outIrez.out

78

rez.in(RS,R3(R12,R4),R3)

rez.inR42R33R3

Sfar~ituI circuitului in serie este marcat de aparipa caracterului virgula. sau parantezl'iinchisa. sau de sfar§ituI §irului s.

Functia rezparale1 ():

Calculam suma §i produsul circuitelor legate in paralel (acestea sunt circuite in serlea caror reziston:ta. se determ.in3. prin apelul functiei rezserie (». Evident, sf'ar§itulcircuitului paralel este marcat de intalnirea caracterului paranteza inchisa..

Solutie

Vom citi codificarea circuituIui Inrr-un §ir de caractere s . Pentru a calcula reaistontacircuitului, vom utiliza doua functii recursive:

.functia rezserie () calculeaza rezistonta unui circuit serie .sau a unui circuit formatdintr-un singur reziston ;functia rezparalel () calculeaza rezistonta unui circuit paralel,

Functia rezserie o :

Insumam intr-o variabila (suma) rezistontele circuitelor legate in serie. Acestea pot ficircuite formate :

dintr-un singur reziston (daca pe pozitia curenta in sirul s se afHi litera R) ~ in acestcaz, la variabila suma adunam valoarea rezistonului;

- dintr-un circuit paralel (dacli pe pozilia curentli in §iruI s se afl~ caracterul parantez.deschisa.; in acest caz. la variabila suma adunamrezistonta circuitului paralel obtinutaprintr-un apel al functiei rezparalel (),).

Date.de .iesire

"Fi§ierul.deae§ire-rez.,-outcontine 0 singura Iiniepecareestescrisarezistonta circuituluispecificat1n~ierul.deantrare. ' ..

Exemple

RestricJii 'Ji .precizari

.. a -< .lungimeacodificarii amui.circuit -=:;; 10010 .,. a < -reztstonja .oricarui -reziston <10 O... 0< TezistontaoricliruLcircuit -c 2000000000 (doua miliarde),• :Sirulprin carese .codifica un .eircuit nu contine .spatii..Pentru datele de test nu ~e vorobtine imPlirliri Ia O.

PROGRAMARENm LlMBAJUL C/C++'PENTRU LICEU

-I 1::) 1-

-I Rl I j R2/_

Rezistonta .acestui circuit va fi Rl+R2.

Legarea celor doi -rezistoni in paralel .se .realizeaza .astfel :

42

Reziston

i !

;---, ,, 1: 1

t ~J Rezistonta acestui circuit va fi (Rl *R2) / (Rl+R2) . Piindca rezistonjele pot finumainumere naturale. lmpaqirea este Intreaga (adica rezultatul este catul1mparprii lntregi a

-lui (Rl*R2) Ja (Rl+R2»).

1 I Prin Iegarea mai multor rezistoni in serie Si in paraIeise obtin circuite, Circuitele pot'~. fi legate in serie si/sau in paralel dupa aceleasi reguli. Rezistonra unui circuit se calculeazgaplicand reguliIe de mai sus.

r- Un circuit va fi codifica(printr-un sir de caractere construit dupa urmatoarele reguli :[ • Daca circuitul c este format dintr-un singur reziston Si acestaare rezistonja de; 1 valoare x , atunci codificarea circuitului c este Rx. Rezistonta circuitului c va fi x ,

• Daca circuitul c este obtinut prin Iegarea in serte a dona sau mai multe circuite,r codificate cl' c, • ., -, c/:. atunci codificarea circuirulul c -se obtine concarenand in: i ordine codtficarile circuitelor C 1 C2 ••• Ck o Rezistonta circuitului c se- objine prin,~ tnsumarea rezistonjejor circuitelor cl' c

2• "', c

k•

• Daca circuitul c este obtinut prin legarea in paraIel a doua sau mai muIte circuite,:- atunci codificarea circuitului C se obtine incadrand Inrre paranteze rotunde codificanle

circuitelor din care este format §i separandaceste codifican prin virgula: (Ct. c2

••. , Ck ) . k>l. Rezistonta circuitului C este egala cu catul impRrtirii produsului dintrerezistontele c t ' c 2 ..... c k §i Suma rezistontelor circuitelor c

t' c

2..... c

k•

';erinlii

Scriep un program care sa determine rezistonta unui circuit.,-;')ate de intrare

Fi§ierul de intrare rez. in contine pe prima Jinie un §ir de caractere care reprezintlir-~diticarea unui circuit confonn regulilor de mai sus.,

....,I i, i

I Ic

....,, 1

[ :

(J 'Gigel este electronist ..aD1ator.EI2fim:JAca .a .inventat<o;;noU~hcomponentaelectronica,-denumita .reziston. :tn.mod .ciudatrorusr, zrezistonii au zusre .proprietap -care .noua ne sunari .foarte cunoscut.

I I Orice -reziston .este caracterizar :printr-o .marime :fizica mumita Iezistonta. .Aceasta(1 poateavea ca valori numal .numere naturale. iRezistonii pot 'fi Iegaji fntre ei .In:serie .sau...., in paralel, .formand -astfel circuite.I 'I Fie ,doi rezistoni avand rezistonteleR:l, .respectiv R2. LegareaIn oseriea rezistO~o:r~_ .se .realizeaza .astfel :

void afisare (void)

{FILE *fout=fopen (OutFile, "w");

fprintf(fout,"%ld\n",r);fclose (fout); }

~ong rezserie ()

{1ong val, suma=O;

if (p>=n II s[p]==', I 11 s[p]==') I)

return 0;

whi.1.e (p-en && s[pJ!=',' && s[p]!=')')

.if (s[p]=='R')

{P++;

val=s[p]-lO';p++;

~f (s[pJ>='O' && s[pJ<='9'){val=val*lO+s[pJ-'O';p++; } 3. Care este efectul urmatorului program pentru n=4?

I~I';'~,1'1',

iII!",

~f~ri11'\1

fl'll':,Ie' ,",\~Il f'l"rl i ~IJ,,~ a ,H~ ~I'l ~I I"ij' "\-JI!~'il :Illi:i~ :;'. ~i f';':~ i'I'l ';liii':!I'~";

'I!ll• :'11F>~ ~j,J"j, ""'Illil' ::" 'II, I

~~~'I!I~~I}'l ~i'I'i,I!II: ,1'1':," I:.ll"'lil ,"',,' 1.,1.-.1

"I" I

~. " '":, ,ji·l~t

,',i:/:,j'!'!4Jlil ~, ,,",Ii ''~I,kill,:--,

~I"I' 'I""'II"'l,i Iii, 1""1' ,~iJI~ 11,· ;

;''1-111_~ill, I '"Sir I

·,'Hi ~I~~"' .\"1"11

'

'I,:" I,J',1II I" .;'~'I'I!I~;': ';~d':

'1Ii'I:'I'li

;::'1·,'1',1' :,''-::'':'''--1I.")I,'I!

,:.ri':''I k\·j;i11!~Ii

:::'i \;~,

45

dacan:S:;l"

daca n par

daca n impar

dacax=O

altfel

a) f:N->N

{

O'f (n)= f(n+l),

f(n-l),

b) f:Z->Z

f(X)={~X_l),

~1se ~uma+=rezparalel();

return .suma;

'surna+=v"al; .

RECURSMTATE

p++;xeturn produs/suma;

~ong rezparalel(){~ong :suma=O, produs=l, val;'WhiJ.e (s[pJ !=')')

(p++;val=rezserie();suma+=val;produs*=val;

I. Sa consideram urmatoarele definijii recursive:

Sunt corecteaceste definitii ? Justificati raspunsul.

2. Stabiliti valoarea de.adevar a urmatoarelor propozitii, Justificati.a) Intotdeauna 0 solutie recursiva de rezolvare a unei probleme este mai avantajoasa

decat 0 solutie Iterativa.b) 0 functie se numeste recursiva daca §i numai daca in corpul sau intervine un apel

al san.c) Numai in cazul in care 0 functie este .apelata recursiv la apel se aloca pe stiva

parametrii, variabilele locale §i adresa de revenire din functie.d) Reducerea numarului de parametri ai unei functii recursive reprezinta 0 optimizare

a acesteia.

7. Probleme propuse

r*include <et ddo c h>

4Fdefine InFil.e",' z-ez, Ln'"

4tdefine OutFile".rez_ out II

.#define LMax 'lOOI

int n,p=O:-char s [LMax] ;

~ong r:

int main ()

(citire() ;

r=rezserie();afisare () ;

return 0;

Observati ca implementarea'foloseste -recursivhatea .indirecta.

PROGRAMAREA'iN .I.:lMBAJULC/C++'PENTRU LJeED

void citire(void):void afisare(void):~ong rezserie(void):~ong rezparalel(void):

void citire(void){FILE *fin=fopen (InFile, "r");

fscanf(fin,"%s",s) ;for (n=O; 5[n]; n++):fc105e(f1n):

44

,

fI

46-.....,

. I,LJ

nIInI ',._ .1.

0-f, ,._.. ~

4,

6. Ce va afisa pe ecran urmatorul program ?

!\~!

t ~1, .

I,Iljl!1,,1'II'lUi ,e

"IJ '~

I.i~:,iI;I~I" ,~11~ '~'.j.:

lII{.'",I,,.Y"j '.'il,"j11, ' ,Sr 'JI ,'I

~" ,

:'l~),: ;Ja::!

~II",\I'!,',i~ I~f;,r;

~: i~lji!:'Iit~t",j ,I', ,It·1\,',I :\,'i.I! 't~~~i:'lj'~:l"•

'~" !~: ,-jr·!

.111JI

1~~1'11~:i~ ~;,p'I:'!f~i :II!!,ililil"-;;l\::j~ ::1 !11! ~Ii

:ti!~1i'i::!t;;11;1'~' I 'Ifl"'1"'1::1"',1::!:lI:lii:!j:,:.:[I[:1

!1'1t'i

;'iJli::f;i'~li1

ill!'I",

"'1'1'"('1;,1:

'11,",JI'

II"ii

::-+1''I,1:1 :ii!":'

47

Bacalaureat, 2003

e) 14414 414410

I) 14414 414411234

.e) 101)4

c) 5

d) 3

c) j*j+suma (j-l)

d) j+surna (j*j-l)

c) 41441 144141234

d) 41441 144140

c) x-e-d

d) x>"<l

l.ong suma(l.ong i)

(if (i====O) return 0;l.ong j===sqrt(i);

return ... ;

void p (.;int n)

{if (n)

{cout«n%5; p(n/5); cout«n%5 ;}.e Lee cout«

RECURSIVITATE

..intrnain ()

{int n===1234

p (n) ; oou t c-cn

return o.;}

~include -<iostrearn.h>

.a) 0b) Nimic, .se obtine eroare Jacompilare,

7. ce va .afisa pe ecran urmatorul program?

a) x~~1

b) x-ed

Simulare bacalaureat, 2003

a) 1234 43211234

b) 41441 144140

int f(int x, int d)

(if ( ... ) return 1;

if (x%d====O)

xeturn (l+f(x/d,d»;

return (f(x,d+l»;

8. Cu ce expresie trebuie completata secvenja Iipsa (marcata prin ... ) din functiaurmatoare, pentru ca f (x, 2) sa aiba ca rezultat suma exponentilor factorilor primice intra in descompunerea lui x ?

9. Functia recursiva surna trebuie definita astfel tncat upelul surna (n) sa returnezesuma patratelor perfeete mai mici sau egale ell n. Care este expresia eu care trebuiecompletata definitia functiei ?

a) j*j+surna(j*j-l)

b) j*j+surna (j)

I

Ig

int main ()J {cout«Nr () ;p.return 0: }

"PROGRAMAREA 'iN "LIMBAJUL C/C++'PENTRU ,UCEU

.;if (!x [i]) return D;

return (x(i]==x[i+l])+test(i+l);

(if (x>l)s c r Le (x/2);

cout«x%2: )

4tinclude -<iostream ..rr>=i.nt .n-:

void "Test (int i)cout«'"*' ;if (i<n) Test (i+'l)_;cout« ,+ I;

Se considerli urmatoarea functie recursiva, Cese afiseaza pe ecran la apelul s erie (21 ) ?

.Simulare bacalaureat, :2003

a) 10101 c) 01010b) 11111 d) 00000

Care este efectul urmatoarelor programe?b)

*include <iostream.h>int Nr (){int i, n=O;for (i=O; i<10; i++)

n=Nr () +1;:return n; }

oint main ()

cout «"n= ", cin » .n r're s t t t j r:return 0;

int main (){cout«test (D);

return D; }

#include <iostrearn.h>char x [] ==="abbbabaaab";.;int test (.;int i)

i:nt main (){CQut«Suma();return 0; }

5.a)

I#include <iostrearn.p>:.i.nt Burna (){int a:

, cin»a;if (a>O) return Suma()+a;return 0;

Ivoid s cxd e ( ,int x)

,"-': I

,..,) :, .J,

1.1.

~,

, ,, I, '

­,,,, .

,,

r-:,,

r--:l

r~ II

10.Pentru deftnijia mrmaroare -afuncliei -s k (), stabilili.cate asteriscuri ",e",fi§eaza la.apelulak (6) .

a) Un numar imparde asteriscuri. b) 2c) 4 d) 6

Simulare .bacalaureat,200411. Transformati urmatoarea funcrie intr-o .funcjierecursiva .care ,sa -nu .utilizeze nici 0

structura repetitiva ~i ,sa returneze acelasi rezultat ca '.§i functia .data pentru .orice-valoare nenula a 'parametrului i. Scrieti versiunea modificata.a acesteia.

1~~lll:

i"filll~~I}I'rlj~:'r.l~~1

1"1"'J ~

1~':"r!I~"i .1;,(11

:!:i,i:

'j!;;!l~"tl '", 'L":~i'::j: :

lill,I'!i111'/',1 ',.

;lijj;)':~r'i:,III~III'I'r'~"!! '!:li.l~· "

II" ',: i~J~ ,~~ :'fj' I\l'~j I,! ;i:~i i..'',l,II""".,~:'~'~I "Y :';i'liiil:1i.;i

1'1;' L :"

'1

,1,\ -1 '~J 'I"I'101

; !~1iJ(::~~

i~I'lil 1"!!'I~:i\: "~:.I:'I'I' I , ,I} ",·, I

,(I, I;'I;:"I.--l

'111

1

" , ,:i, ,~; l~l~::

;:111'; ,

'{:I~!'iL\ 1

i~'!,i:~il:r i !(!iiI,lI lii '\:-'

;::;!tlP:'~

,:!:\it-"':';'!I""'\:li'hJ·i'lr"\j;\:r,:\~~"1'1 i'~ I, : ,! ;;,,'1 !'I_­l" ,,:1 .."\1.,' I Jt..

49

daca n s zdaciin>2

n!

dacii n >0

.daca n=O

dacan =0

daca n impar

daca.n par. n >0

RECURSIVITATE

{l '

a)xn

= n e-Lx·x ,

j1,

o 0

b)xn = x2"x2,

n-1 n-l

x oxT·x2 ,

{1, 2, "'f n} se noteaza c; §i este egal eu c~k!'(n-k) !

Se poate demonstra urmatoarea relatie de recurenta:

Estimati numarul de inmultiri efectuate de fiecare functie pentru n ~ 7, 8, 10. 15,16,20, 63, 64. Realizati 0 comparatie intre cele dona functii descrise, din punctul devedere al timpului de executie.

IS. Fie n E N §i k E {O, 1, "'f n l . Numarul de submultimi de k elemente ale multimii

c~ = C~_l + c~:~

Scrieti un program iterativ §i un program recursiv care sa calculeze c: pentru n §i k dati,folosind accasta relatie de recurenta. Realizati 0 comparatie Intre cele dona variante.

19. Fiind dat n, numar natural, scrieti un program recursiv §i un program iterativ caresa calculeze expresia: Eo = (2+ .,/3)0 + (2-.,/3)" .

Realizati a comparatie tntre cele doua variante de rezolvare a problemei.

20. Fie sirul definit prin recurenta :

f (n)~ll,\3·f (n-1)-2·f (n-3)+f (n-2),

15. Descriepo functie recursiva care 'sa calculeze suma cifrelorimpare ale unui numarnatural .transmis .ca parametru.

16. Fie a 'un 'vector eu n componente intregi (a -si 'n fiindvariabile globale). Scrieji 0

functie recursiva care ::sa verificedaca 'oricaredoua .elemente .consecutive in 'vectorsunt .diferite,

17. 'Fie x., n E N. x>O. .Scrieti u functie -recursiva -pentru calculul lui x'', utilizand.nrmatoarele .definitii recurente :

Scrieti un program iterativ §i un program recursiv care sa calculeze eel de al n-leatermen din sir. Compared eele dona variante.

21. Scrieti un program care genereaza toate palindromurile de lungime n (O<n<40),scrise in baza b (1<b<10). Numim palindrom un numar care citit de la stanga ladreapta san de la dreapta la sranga este acelasi, De exemplu, 1331, 12321-

22. Se dau numerele naturale n §i m. Se considera 0 retea dreptunghiularli avand z" Iinii§i 2" coloane. Se cere, sa se atribuie nodurilor retelei numere naturale distincte din

,!,

Bacalaureat, august 2001

daca a=b

dacii a> b

dacii b>a

:PROGRAMAREAiN LIMBAJUL C/C++',:PENTRU LlCEU

{

a.cmmdc(a,b)= cmmdc(a-b.b),

cmmdc(a,b-a),

if (i==O) return 0;return mk(i-l)+i;

return j;

int oms (l.onq i)

lint j=O;whil.e (i%10==0)

{ j++;i/=10;

int mk (int i)

(

Ce valoare va returna mk (8)? Dar mk (50)?

48

12. Se considers urmatoarea functie definita recursiv :

f~

Bacalaureat, 200013, Scrieti un program recursiv de calcul a functiei Manna-Pnueli, f: Z ~ Z

f(X)_(X-l, dacax:Z:12- f(f(x+2», daca x<12

14. Descried 0 functie recursiva de calcul al celui mai mare divizor. comun al douanumere naturale, utilizand urmatoarea definitie recurenta :cmmdc:N x N -> N

I'lVo:i:dsk';(unsi'9I1ed :int .:x)

{unsigned int i;

.

:fo r (~=J.:;~·<=xI2; i++) :sk(i};

printf '''*'');

II

--c,

""\1'\1

.t',I"

n:[i Ii

II ~1!I,'1

I",~·l·,·lj~ <,'

III i'I":,I \

,\,,1';11\., ;"111

'l'~t

1:' I"j: ,,\",.,8,1.

'IIi!::'i '~!h~

111'/',/",:,!1

~" ' I Ifj>qI'd t.'

\ i ;,,~

"ll: J:~rti! "~j~~d'~ ';L'

'i"!' '111,,1

ilil:!:

\

11.;: ''I" I'1'1'>: I~t}i' ,j'I"I'"-I ...":'~(:il\ ~

';Jil(::"Ill:'11'1 '!I

l'I'd'ii",'1<:'i',I!I~;:

:11!~il':i .n!~ ~I,.on,.'" ..,~~.. i

:'i.i:H:l'l;;'~:"I~i:1,,,,1, •!:;~:IHH,J':';:$:rd'-:!.:j;l1'\

I'~,~FF:::

0'''''('I"

:'1:\'

I::1<1·1 '

I:i: '.1,

-51

masa.in masa.out( (CH) 2 (OH2H) (C (H) ) 0) 3 222

Concursul ..Urmasii lui Mcisil", Iasi, 2003

RECURSIVITATE

masa.out148CH(C02H)3

masa.in

Exemple

Cerin[ii-Scrieti un program .care citeste o formula chimica .In care intervin numai atomi .dehidrogen, oxigen §i carbon §i calculeaza masamoleculei reprezentatede:fonnularespectivli.

Date .deiturareEigierul-de intrare masa. in contine pe prima Hnje ·0 formula .chimica construita .duparegulile de mai sus.

Date.de·ie#re

Pe prima lime a fisierului de iesire masa. out va aparea .masa moleculei .descrisa defonnula data.

Restrictii ~i prectzariLungimea unei formule nu depaseste 100 de caractere.

Masa unei molecule este un numar natural ce nu depaseste 10000.-Un.atom dehidrogen are masa 1, unatom de carbon aremasa 12, .iar un:atom de:

oxigen are masa 16.NUID.3ru1 care indica repetitiile unei litere sau ale unei grupari este intotdeauna mai

"1Il3Ie dedit 1 ~i mai mic strict decat 1O.

i

D2

B2

A3

A2

A2

A2~

ciYIl

'PROGRAMAREA iN LIMBAJUL C/C+ +'PENTRU DCEU

Al

C

-so

r,!

",,

anultimea {a .J.. ~ ..• 211l+n}. 'astfel dncat -pentru .oricare xloua -vArfuri vecinetpeorizontala aau verticala) :reprezentarea lor 'binara .sa difere printr-o .singura pozitie.

f-: 23. ,ConstruitifuIDlao:poloneza-postfixata .aexpresiilor:

l,~ ';a) .a*b*c+2*d* (a+,1+2*b*c)

;,

b) 2*,a*c* (a*b+c+3*d+a*b*c*d)

r' 24.'scriep un program de evaluare a unei expresii aritmetice hrnotatiepolonezainforma~j postfixata.

25. Curbe Hilbertr" lnfigura urmaroare sunt reprezentate treicurbenotate HI. H2. H3, numite curbele! ! Hilbert, de nivel 1,2, respectiv 3.t ..l

HI H2 H3~

\ Observati ca 0 curba Hilbert de nivel i (Hi) se obtine prin compunerea a patru curbe~,i Hi_I Cll dimensiunea la jumatate, rotite ca in figura §i unite prin trei segmente de Iegatura

(reprezentate ingrosat). Scrieti un program bazat pe recursivitate indirecta care sar7 vizualizeze in mod grafic curbele Hilbert de nivel n (citit de la tasratura).ii .26. MasaL. ~ 0 molecula poate fi definita ca 0 secventa de atomi §i poate fi reprezentata printr-of""""l formula chimica, De exemplu, litera H desemneaza un atom de hidrcgen, litera ci dcscmneaza un atom de carbon, D desemneaza un atom de oxigen. Formula CODH

l .~ reprezinta molecula fermata dintr-un atom de carbon, doi atomi de oxigen §i un atom dehidrogen.

r Pentru a scrie formule in mod eficient utilizam urmatoareje reguli :1;\ • Literele ce dcsemncaza unii atomi pot fi grupate intre paranteze. De exemplu, formulai. CH (OH) contine gruparea OH. Gruparile pot fi imbricate, adica 0 grupare poate

contine alte grupari. Pentru a simplifica formula, aparijii consecutive ale .aceleiasilitere pot fi inlocuite cu litera respectiva urmata de numarul de aparitii. De exemplu,formula COOHHH poate fi scrisa C02H3 ~i reprezinta 0 mclecula constituita dintr-unatom de carbon, doi aromi de oxigen ~i trei atomi de hidrogen.

• De asemenea, aparitiile consecutive ale aceleiasi grupari pot fi inlocuite de gruparear-;, respecdva, urmatiidenumliruleideaparilli. De exemplu.formula ca (C02H) (C02H) (C02H)

poate fi scrisa CH (C02H) 3. Molecula reprezentata de aceasta formula consta dinpatru atomi de carbon, patru atomi de hidrogen §i sase atomi de oxigen.

• Masa unei molecule este egala cu suma maselor atomilor din care este constituita.,..-."

:":, ,(1

eel mai mare divizor comun

2. Aplicatii

~'l~'

~;I'

Ilill"II'

!'II; ~11jl'II"'~ ~ :'l~ ,,~,I, /!i ~'I ,;':,I'l':';\:rtt 'I

,~ ' I ~!I 1'; :I Ii,' '~'t~""

'!"" ~I'I:""'"~, ';" - 'j

I 'I' '.: ,. i' .;':' i

Jill"!' ", 1i1"1'1I­: 1':1 li!1:'>/) ,~

'1,1:\. I:;!)\11'1 1"II "IlL ,:~t,,',!(';-"J\\II'j'i:!ljl;(j,!~ ,~ri,(! i'~I,;I::, '-.J'"'11'(:1\~;'II'\ :l:~~:!i! ,~:d i 1~ill' 111,:, :;:, ~I'II ' 1:"---,,

'1'1'1''''eilll;J~':i:',ji, "Iil,:/\i"iyllh ':

::'·I!:/~(,Ill!· :;i:'llr,,~~

I 'd:::, ""'I' !

",1.l1·:"\"!

,1'1'-­, !I;.

','I I"

53

lui Euclidunsigned Euclid(unsiqned x, unsigned y)

//calculeaza cmmdc(~, y) prin algoritmul

unsigned r;while (y) {r=x%y; x=y; y=r;}

return X; }

MEroDA DIVIDEerIMPERA

±f (d < ,8) //problema sepoatexezolva direct

Prelucrare (d, SolP);;else

Divide(d, ns, ds);/~imparte problema in nssubprobleme, ~le carordimensiuni sunt retinutein -vectorul "ds*/:for (i=O; i<ns; i++) Divide....:etl_impera (ds [i), 5 [i);

/*rezolva cele ns subprobleme in acelasi mod*/combina (ns, 5, SolP); }/*combina solutiile subproblemelor, pentru a obtinesolutia problemei initiale*/

Solutie

Solatia Divide et impera consta in Impgrtirea sirului aD. a1 • · • • •• a n_ 1 in doua subsiruri,aD, al' .••• am' respectiv a m+1••••• a o_1 (unde m reprezinta pozitia din mijloc) §i aplieareaasociativitatii operatiei cmmdc :

cmmdcfag, al' ...• a n_1)=crrundc(cmmdc(ao' ...• am).cmrndc(am+l' ...• an_I»

#include <fstream.h>#-define NMax 20unsigned a[NMax], n;void Ci tire (){ifstream fin("cmmdc.in");fin»n;for (int i=O; i<n; i++) fin»a£i];fin. close (); }

Fie n valori naturale aD. a!' ...• an_I' Determinati eel mai mare divizor comun al lor(cmmdcfag, a!' ...• an_I» prin metoda Divide et impera.

)

Metoda pare destul de complicatllv dar in .realitate este mult-mai simplu. in cele maimulte .situatii, problema ·se imparte in .doua subprobleme de dimensiuni -aproximativ

egale.

rit

void Divide_et_impera (int d; Sol-utie & SolP){ /*functia rezolva 0 problema de dimensiune d, retinand

solutia in parametrul de ~ip variabila SolP*/int ds[NMaxSubprobleme], ns, i;Solutie s[NMaxSubprobleme];

CAPITOLUL.2

Metoda Divide et dmpera

Pentru a intui mai bine cum functioneaza aceasta metoda, s~ ne gandim la modul deorganizarea unui turneu de tenis. Concurentii participanti sunt impirtip in doua grupe.Se organizeaza turneul in cadrul fiecarei grupe, iar firiala se va disputa Jntre cei doicii§ti~tori ai turneului pe grupe. Castigatorul finalei este cii§tig~torul Intregului tumeu.Organizarea tumeului pe grope se face dupa acelasi procedeu: se impart concurentii dincadru1 grupei pe semigrupe, se organizeaza turneul pe semigrupe, iar ca~tig~torulgrupeise decide Intr-un meci de semifmala intre cei doi castigatori din cele doua semigrupes.a.m.d, llnpiU1irea se repeta pana cand avem doar doi jucatori, care joaca un meci....direct",

Pentru a descrie intr-un mod cat mai general aceasta metoda. sa consideram difunctia Divide_et_impera () trebuie sa rezolve 0 problema de dimensiune d §i saobtina solutia problemei in parametrul SoIF. Pentru aceasta, se lmparte problema datain ns subprobleme. Cum nu este obligatoriu ca subproblemele sa aiba aceeasi dimensiune,retinem in vectorul ds dimensiunile celor ne subprobleme, Rezolvam cele ns sub­probleme, apeland pentru fiecare dintre ele functia Divide_et_impera () §i rejinemsolutiile objinute in vectorul s , Prin combinarea solujfilor subproblemelor din vectorul5, obtinem sohitia problemei date.

Divide .et impera .este o metoda generala .de elaborare a algoritmilor ce consta In douaetape :

• Divide. Problema data este tmpllrtitli in doua sau mai multe subprobleme de acelasitip, dar .dedimensiuni mai mici.Subproblemele se rezolva direct, daca dimensiuneaIor permite aceasta (cazuri elementare), san, fiind de .acelasi tip, -se.rezclva in modrecursiv, prin acelasi procedeu.

• Impera. Se combina sclujiile subproblemelor pentru a obtine solutia problemeiinitiale.

1. Descrierea generalaa metodei

Problema Tumurilordin Hanoi'

:- Solutie

r-' Avem la dispczijie trei tije numerotate I, 2. 3 si ndiscuride diametre diferite. Initial.L. toate discurile.sunt plasate pe tija 1 in ordinea.descrescatoare a diametrelor, considerand

sensul de la baza la varf. Problema consta in a muta 'discurile de pe lija 1 pe tija 2,:"':'" folosind ca tija de manevra tija 3, respectand .urmatoarele -reguli :

I lli . dii ' - la fiecare pas se mu un smgur 1SC;

", "- orice disc poate fi asezat doar peste un disc cu diametru mai mare.

'j11~1'InII!I~~~~Ill' .I,r,!i~I\!11'~~'~I

Illmtl

i~ill:ill"lll11,1,1.\,I pi"· .",Jlf~lJ'i Il'i..'\'~'H:I,

~ !~~':illi 1',1ill'cil\'!~, ,l;; I

til,: l'):r!

II.,' ,.; Ii!I,,;;':,':\111'1 "i, "1~

~t "H'~i'

'1'1" ::'::"IJ,,~, ,I'';

Ili:j~\\!II"~ :''~~"" ,ltlj)i!;"),-'~!'~l: 1,"~.1:­j~:'~!: ..!I'\!; n~t]i'!: : "

iif::riil:.--,::It:t:,::':'(J"N;):t:,;'1"'::ffl,l:!:~I:l":!~:,::f:~1l!;il:ik',i'·1 '.,':·:('il

fl('

'.i',

>1·I.... "

,~,:::' , '."j I''T'i"I':\':'1

!i!I'

55

~include <fstream.h>

Muta_Discuri(n,1,2) ;fout. close () ;return 0; }

ofstreamfout (~',hanoi_out''');

METODA.DlVIDE,ETJMPERA

.i.nt main ()i.nt n;

cout«"n= "; cin»n;

~oid Muta_Discuri(int~, int i, ~nt j)/lfuncti"a :muta .x discuri de ope tija i -pe tija j

;i'f (x>1)

(Muta_Dds cur i, (x-I, L, 6-i-j) ; / / 6-~-j e s t;e tij avde vmanevr af outi-c-cd-c-c" -> '''«j«endl;

'Muta_Discuri (x-1, 6-i-j, j);}-e1.sefout«i«"-> "<c j c-ceocn..

Problema plierilor

Exercitiu

Calculati numarul de mulliri efectuate de acest algoritm,

Pentru a detennina toate elementele finale ~i succesiunile de plieri corespunzatoare unuivector cu numerotarea elementelor p... q, VOID utiliza functia Pliaza (p, q). Dacap=q, atunci vectorul este format dintr-un singur element, deci element final. Daca p<q,calculam numarul de elemente din vector (q-p+l). Daca numarul de elemente din vectoreste impar.ielementul din mijloc «p+q) /2) este eliminat, plierea la stanga se face de lapozitia (p+q) /2-1, iar plierea la dreapta de la pozijia (p+q) /2+1. Daca numarul deelemente din vector este par, plierea la stanga se poate face de la pozitia (p+q) /2, iarplierea la dreapta de la pozitia (p+q) /2+1. Vorn codifica plierea la stanga repnand in

Solutie

Se considera un vector de lungime n. Definim plierea vectorului prin suprapunerea uneijumatati, numita donatoare, peste ccalalta jumatate, numita receptoare, cu precizarea cadaca numarul de elemente este impar, elementul din mijloc este eliminat. Prin pliere,elementele subvectorului obtinut vor avea numerotarea jumatatii receptoare. ,Plierea sepoate aplica in mod repetat, pana cand se ajunge 1a un subvector format dintr-un singurelement, nurnit element final. Scrieti un program care sa afiseze toate elementele finaleposibile §i sa se figureze pe ecran pentru fiecare element final 0 succesiune de plieri.

Olimpiada nationala, Arad, 1992 - text modificat

1,

pentru x e I

pentru x > 1

PROGRAMAREA "iN'UMBAJUL-C/C++ 'PENTRULICEU

unsign~dcmmdc(unsigned p,_'11Dsigned q)

{11£unctia intoarce cmmdc(a[p], , a[q])if -(q-p<= -1) /Icmmdc .ee 'Poate .ceacuie tcurecc

:;%eturn EucLdd Ia Lpl , -a[q]);

unsigned m=(p+q)/2;.return £uclid(crnmdc(p, _1II), crnmdc{m+l, q»;

}

::i.nt maLn ()

Citire();cout«"crnmdc= "«cmmdc(O, n-l) «endl;

return 0; }

1. Aceasta problema a fast propusa la sfarsitul seeolului trecut de catre matematieianul franeezEduard Lucas. care a comerciallzat-o sub forma unui joe ell opt discuri ~i trei baghete, numit"Turnurile din Hanoi". Jocul este inspirat dlntr-o srraveche legenda hindusa, in care se povestesteca zeul Brahma ar fi fixat pe 0 masa a templului sau din Benares trei baghete verticale de diamant,pe una dintre ele plasand 64 dediseuri de aur in ordineadescrescatoare a dlametrelor. Zi §i noaptecalugarii templului mutau discuri de pe tija 1 pe tija 2, folosind ca tijii de manevrli tija 3,respectand ordinea descresclitoare a diarnetrelor. Legenda spune ca atunci cand toate discurile vorfi mutate va fi "sfar§itullumii".

-,, .

:-

J

r. l VOID nota 0 mutare sub forma i-4j, unde L, j e{1, 2, 3}, i:;t:j, cu semnificatia ."se mumun disc de pe tija i pe tija J",

i Daca n=l, problema se reduce la a mutaun singur disc, ceea ce se poate face directi (caz elementar).L. Daca n>I, pentru a muta discul de diametru maxim de pe tija i pe j trebuie sa 11r--- "eliberam.", deci sa plasam cele n-l discuri de deasupra sa pe tija de manevra, Cele 3

tije fiind numerotate distinct cu valori din multimea {l, 2, 3}, suma numerelor tijeloreste 6, deci tija de manevra este numerorata 6-i-j. Discul de diametru maxim fiindeliberat, poate fi mutat pe tija j, dupa care cele n-l discuri de pe tija 6-i-j pot fi

r-"'" mutate pe tija j, folosind de data aceasta, tija L, care este goala, ca tija de manevra,i j Pentru claritate, 'sa notam prin H(x,i,j) sirul de mutari necesare pentru a muta x: "discuri de pe tija i pe tija j.

{' ->'H ,. ~ ],

(x- L, ])= H(x-1, i, 6-i-j)i--+jH(x-1. 6-i-j, j),

54

\'1

,I

~

,--,

r-

*include <iostream.h>~include <string.h>*include <stdlib.h>

4Fdefine NMax50

int n,efinal[NMax];//efinal(i} este 1 daca si numaidaca i e element finalchar m(NMax] (50];I/m[i]=codificarea plierilor care"ne conduc la elementul i

,,,irul mntilrilorsimbolul ~".,mmat<1epozitia Ls,.de1a"areseface pliereaspre stanga,dar",pliere Iadreapta-prin simbolul ~1J~,unDat<1epozilia Ldde 1a care -seface plierea.espre-dreapta, iFentrua idetenuina eoare -elementele -finale-din lintervalul p .. q apelam.recursiv -functla P~iaza.() pentru-prnnajumatate adntervalului, precedand toate succe­-siuaile tie pller! cuo 'pliere spre stanga, apoi apelam functia Pliaza () .pentru cea.de-a<touaj1.;JJIJAtate :a.intervalului, -precedand toate.succesiunile de-plieri corespunzatoare 'ell

opliere 1a .dreapta.Deexemplu.rpentru n-7 , .elementelefinale ,~i plierile corespunzatoare sunt:~, S3 Sl

3,S3 ,D3

5, D5 S57, DS D7

"1~ II' I,~iI" ,:1~,

JI~

1, 1~~t'( i'!I~; 1.1

"I:~~:i 1"" ,'.':1'.1, I

:!lf1jl]'t

; :11,\ : :

'I'I"!~I, ..

1 "I'il: .~~'~"i I

~I ' " ' ,"'j: :1'/"1" ,'!"}-('.;.t, :r:-''I- " "I,,,1 ,~~' Ii ~ , iWII~,~

~H!i'II':'"I( r'I'" :, :il';/: iIlg~­i'ltr lfiF', ";,,:'1':,1 !'ir I,'!' ,~',:/f....JI,;j:i;h;

;-!:t Is-:'11'i'f.\!tj.~;r,

~,i>r·,: i~1j,1;...J

jil:&;~rr:;illl.'1:1::'11,

ilt~1.1"'" ,:\::,"[::, !f!l:i!~-J

,:if:J',:1';'i ':, ~,: "

'Ii.,. '

::~i::ri"----"':iLI.1.1)J,:i :1~ ;'~ i; I; :'/11'---

1'1:,:',1 .

iii '·1l.·1,

51

·~or (i=Ld; i-<=q; .i++)

{:strcpy(aux,"·.D~'); .'StTcat{a?-x,sd)-; -at.r-cettaux ,> :;or:);

strcat (aux,m[i] );strcpy(m[i] ,aux); }

MEroDADIVIDEET1MPERA

int main ()cout -c '''n= -"; cin»n;P~iaza (1, n) ;cout«"Elernentele finale sunt:"«endl;£or (int i=l;i~=n;i++)

if (efinal [i] )cout«i«": "«m[i] «endl:

-return O:}

Soltqie

Vom descrie 0 functie recursiva denumita fractal () • cu trei parametri:

• x , y - coordonatele centruIui;• R - latura patratului central.

1. Istoria fractalilor a inceput brusc in 1975. cand matematicianul Benoit Mandelbrot a publicat 0

lucrare revolutionara, 0 teorie a seriilor fractale, urmata de 0 carte de referinta, Geametriafractali1 a naturii. Primii fractali au fost crearl de matematicieni ca Waclaw Sierpinskl, DavidHilbert, Georg Cantor, sub forma uncr exercitil .abstracte, flira ca acestia sll alba initial idee desemnificatia lor.

Scrieti un program recursiv care sa afiseze pe ecran in mod grafic un astfel de fractal.Latura patratului central L se citeste de la tastatura (O<L<260). Iterarea seface pfullicand se obtin patrate de latura 1.

In ultimul timp I , fractalii .au Inceput sa joace un TOl vital 'in toate ramurile stiirqelormodeme. Fractalii sunt forme pentru care fiecare parte se aseamana ell intregul. Deexemplu,infigurade mai jos este reprezentar un fractal sunplu, obtinut prin iterareaunui patrat :

Fractali

rIPROGRAMAREAlN LIMBAJUL CIC++PENTRU LlCEU'56

void Pliaza(int p, int q){//pliaza un vector eu cornponente numerotate de la p la qint Ls, Ld, i;char 55[50], sd[SO], aux[50];

//Ls,Ld - pozitiile de pliere spre stanga, respectiv dreapta;Ilss,sd - sirurile care se obtin din pozitiile de pliereif (p==q) efinal[p]=l; Ilvectorul contine un singur element

"e~se

{if «q-p+1) ,%2) I /vectorul are numar impar de elementeLs~(p+q)/2-1,

e~se Ls={p+q)/2;Ld~ (p+q) 12+1,

Pliaza(p,Ls); Ilpliez prima jumatateitoa(Ls, ss, 10); itoa(Ld, sd, 10);//elernentele'finale din prima jumatate ·se obtinIlprintr-o pliere prealabila la stangafor (i=p; i<=Ls; i++)

{strcpy(aux,"S");strcat{aux,ss);strcat(aux," ");strcat(aux,m[i]); strcpy(m[i],aux);)

Pliaza (Ld, q);Ilelementele finale din 'cea de a doua jumatate se obtinIlprintr-o pliere prealabila la dreapta

~

--,

59

I/vertical

ymax=ys; }placa prin gaura i

Ilorizontal

'METODA DIVIDEETJMPERA

Iinumarul de gauriy(NMaxGauri]; Ilcoordonatele gaurilorImax, hmax, xmax, ymax;

return 0; }

void Taie(int xs, int ys, int 1, int h){int i=O;Ilcaut 0 gaura in placa-whi~e «i<n) && !Interior(i,xs,ys,l,h» i++;if (i==n) I/placa nu are gauri

{if (1 *h>Amax)Amax=l*h, Imax=l, hmax=h, xmax=xs,

el.se I I taiem{Taie(xs, ys, 1, y(i) - ys);Taie(xs, y[i], 1, ys + h - y(i]);Taie(xs, ys, x[iJ-xs, h);Taie(x[i], ys, x s + 1 - x[i], h);}

.int n;

..int x[NMaxGauri],int Lp, Hp, Amax,

•!!'\tjI~

i

i

void Citire (){ifstream fin ("plaea. in") ;fin»Lp»Hp»n;-for (int i=O; i<n; i++) fin»x(iJ»y[i);fin. close (); }

.int Interior(int i, int xs, int ys, int 1, int h){/*intoarce 1 daca gaura i este in interiorul dreptunghiu-lui eu eoltul stanga-jos (xs,ys), lungimea 1 si inaltimea h */if ({x[iJ>xs) && (x[iJ<xs+l) s s (y[i-J>ys) && (y(i]<ys+h»

return 1;

.L:§i .h. Funcpa ·.Taie (xs ,ys,.1;h) -determina zonele .dreptunghiulare fara gauri cesepot -obpne -prin ttliieturi ·<iuse prin ;gaurile placii .eu .coltul stanga-jos {xs ,ys) .~i rtimen­-siunile J., h -pedirectii paraIelecu -laturile -placii, :relinand iu variabilele globaleAmax,-xmax, -ymax, LMax, RMax .aria maxima,.respectiv coordonatele unei placi dreptunghiu-Jare, tara -gauri, -de arie maxima. Pentru -aceasta, 'functia .cauta 0 gaura .din interiorulplaciicde:coordonate (xs, ys; .1, h). Daca oastfel.de gauranu exista,placa dreptunghiu­Jara,deariemaximalara_-gauri,estechiar (x s , ys, 1, h)-lii 0 eompar eu maximul global.Dacaa Iost'gasita 0 gaura decoordonate (Xi' y i) in tinteriorul -placii (xa , ys, 1, h),

. -reducem 'problema .la patru .subprobleme : ..determinarea .unei .zone· dreptunghiulare de.arie maxima, ·fara ~gauri. ee se poate obtine din .cele -dona placi obtinute printr-c taieturaonzontala prin gaura (Xi' yi)' respectiv eele doua placi obtinute printr-o taietura vertlcalapringaura (Xi' Yi)'

#include <fstream.h>·#define NMaxGauri 20

1,

"<iostream.h><conio~h>

·<graphics-. h>

int main (){cout«"L= u; cin»L;

grdriver=DETECT; Ilinitializez modul grafic

initgraph(&grdriver, &grmade,"c:\\borlandc\\bgi");

Eroare=graphresult();if (Eroare==grOk) Ilam initializat corect madul grafic

{ilstabilesc culoarea de fundal si culoarea pat rate lor

setbkcolor (WHITE);setfillstyle(SOLID_FILL,RED);Fractal (getmaxx()/2, getmaxy() 12, L);

getch () ; }closegraph(); Ilinchid modul grafic

return 0;

void Fractal (int x , int y, ..int R)

( if (R>O){ildesen e z fractalii din cele patru colturi

Fractal (x-R, y+R, R/2);

Fractal (x-R, y-R, R/2);

Fractal (x+R, y-R, R/2);

Fractal (x+R, y+R, R/2);Iidesene z deasuprapatratul de latura Rbar (x-R/2, y-R/2, x+R/2, y+R/2);}

int L, grdriver, grmode, Eroare;

-#include4f:includ e::fj:include

,

~

Ji ~

I

ifr

~ a"-'......~Tu:uu;.;.. t.; LIMBAJUL C.'(:-~ ~ ~~!,""'DT1 T U"CTT

r-P placa de tabla dreptunghiulara, de dimensiuni Lp xHp , are n gauri, in puncte de: ,!;oordonate tntregi. Sa se decupeze din placa 0 bucata de arie maxima, dreptunghiulara

)i tara gaurl, suind ca sunt permise doar taieruri pe directii paralele eu laturile pHicii.

~olulie

ventru a identifiea 0 zona dreptunghiulara avand laturile paralele eu laturile placii estesuficient sa retinem coordonatele coltului din stanga-jos (xs,ys) §i cele dona dimensiuni,

,Problema tiiieturilor

I. iI i Daca R>O, 'Vom~pela aecursiv -functia Fractal ()ce -patru ori, "J)entru.a,rlesenafractaliicorespunzlitori .celor patru colturi.ale l'atratuluide latura .R, .apoivom.desena -un­r\trat de Ianrras -~i eu centrul in l'unetuliieeoordonate (x.y),I I

~

~,

l',, ,: 1

l~, .\1

Olimpiada judeteana, Iasi, 1996

Descompunere

U .:int 'main ( )

I (CitiTe ();

ITaie (0, 0, Lp, Hp);

cout«"Placade arie -maxdma are coltul .st.ence-cj os C';cou'tc-cxmax'<xv , "t-ocymax-c«") \n";

-cout«"Lungimea='''«lmax«''; inaltimea="«hmax«endl;

.--return oi )

;~

:1 1

'i i

~, 'IWi .1" i

~~,

II!. iIlr~l1. 1

~r~t'~

.i!

,::,,',

:'!,

I~JIJ'1Ir-l'~ !. I1­!r~

~J,: 1~. 1

l:i~'1'1ii]

~r"l~I L

N' :~:~

~:i

¥i,,1· !

:Ij~

\ilV1~

·61

,:#i:nclude -cLos t reamc no4tdefine .:NMaxF.i,guri 'J. 0 0

.:int -a , .b , .-NrMi-n, timin(NMaxFiguri];

'Void Desc (int .x , inty, oint d[NMaxFiguri], :int ,&il.)

{.i.nt nl, n2,i, .d11NMaxFiguri], di (NMaxFiguriJ;

if (y-x >= .x) I r (x ==y» / /dreptunghi nedecompozabil{n=l; d[OJ-x; d[lJ~y; J

>e1.se

{/idescompunere in 'prima varianta~f (y-x < 2*x-y) Desc(y-x, 2*x-y, d1, n1);

.e1.ae.Desc (2*x-y, y-x, d1, n1);

/ /descompunere .Ln a 'douavarianta, daca ·este posibilif (x%2 == 0)

i-f (x < y-x/2) Desc (x, y-x/2, d2, n2);~~se Desc(y-x/2, x, d2, n2);

-e1.ae n2=NMaxFiguri;..if (nl <= n2)

{n=n1+2; d[O]=x; d[1]=y-x;

£or (i=2; i<n+2; i++) d[i]=d1[i-2J;)e~se

(n=n2+2; d[Ol=x/2; d[ll=x/2;for (i=2; i<n+2; i++) d[i]=d2[i-2);}

METODADIVIDEETJMPERA.

int main ()

cout « "a, b (a<b) = "; cin » a » b;Desc(a, b, dmin, NrMin);

cout < "Numarul minim de figuri: " < NrMin < endl;£or (int i=O; i<NrMin+1; i++) cout < dmin[i] < • '.;return 0; }

3. Compararea performantelor unor algoritmide cautare §i sortare

Fie a o' al' ...• a n _ l (neN*) elemente intregi ordonate crescator si x un numar jntreg.\edficap daca x apare in sirul a o, a l ••.• , a n _ l §i daca da, specificati pe ce pozitie.

Algoritmi de ciiutare. Ciiutarea binarii

-a

b-a

b-a/2

a

a/2

,

I ~a

k".I

II a/2-I

a/2

PROGRAlvJAREA"iN LIMBAJULctC++-'PENTRU LlCEU60

Solutie

Pentru a determina a descompunere d eu un numar minim n de figuri eomponenteaIeunui dreptunghi eu laturile x, y vom utiliza functia Descompune (x, y, d, n). Dacadreptunghiul este decompozabil, descompunem dreptunghiul in cele dona varianteposibile, pentru dreptunghiurile obtinute determinam 0 descompunere en numar minimde figuri compcnente, retinand pentru fiecare varianta de descompunere numarulminim de figuri obtinute §i dimensiunile acestora. Se alege varianta de descompunereeu numar minim de figuri §i se adauga dimensiunile eelor dona patrate corcspunzatoarevariantei alese.

Se considera un dreptunghide .dimensiuni as b , ell a, b numere naturale ce satisfacrelatia : b-a<a<b.

Existlidoua moduri .dc.a .descom-pune un asemeneadreptunghi in donal'iitrate ~i un dreptunghi. Procesul dedescompunere seiaplica .apoi drept­unghiului rezultat in, urmaidescom­punerii ~i continua in acelasi mod pana ase obtine un dreptunghi care nu maisatisface relatia de mai sus (nedecom­pozabil). Problema consta in a deter­mina .un sir de descompuneri in urmacarora sa rezulte un numar minim defiguri nedecompozabile.

Sa se scrie un program care citeste de la tastatura dimensiunile a ~i bale drept­unghiului initial ~i scrie in fisierul de s c . out deseompunerea ell numar minim de figuricomponente. 0 deseompunere este scrisa in fisierul de iesire ca 0 secventa de numereIntregi Po. P l , •..• Pk-l' dl' d 2 (unde Po' P l' ..... P k-l sunt lungimile laturilor patratelorobtinute in urma deseompunerii, iar d l ~i ~ sunt dimensiunile ultimului dreptunghi).

De exemplu, pentru a=21, b=34 objinem minimum 7 figuri, dimensiunile acestorafiind 21. 13. 4, 8, 1'. 1, 7.

I, \

62'PROGRAMAREA iN LIMBAJUL C/C++ "PENTRU.UCEU

MEroDA DIVIDEET IMPERA 63

Propozitie

Algoritmul .de cautare .binaraefectueaza cel mult [log2n]+1 compararii, in cazul uneidiutari eu succes, .respectiv [log2n]sau [log2n]+1 comparatii, in cazulunei cautari rarasucces • .unde n este dimensiunea -spajjului .de cautare,

Demonstratie

Sa analizam algorirmul in cazul celmai defavorabil (cand x TIU se afla in vector sau x seafla in vector, dar este depistat doar la ultimul apel), La fiecare .apel recursiv spatiul decautare se jnjumatii:telite. Dupa primul .apel. din. cele n elemente .inuiale, raman n I 2elemente. Dupa al doilea .apel, raman n/4=n/2 2 elemente s.a.m.d. Un rationamentinductiv ne conduce la aflrmatia ca dupa k apeluri recursive .spatiul de cautare va conpnen/2 k clemente, In final, numarul de elemente din spatiul de cautare trebuie sa fie eelmult 1, deci :

n/2 k::;; 1 => n :s; 2 k ee- log2n ~ k

Prin urmare, k - numarul de apeluri recursive - este egal cu [logyn] sau [log2 n]+1 .

Algoritmi de sortare

Observa/ii1.1nacest·C3Z, -rezolvarea problemei ;initiaIe::se .reduce la :fiecare 'pas Iarezolvarea unei

singure subprobleme.::2. Incazul in "care vectorul oeste .ordonat• .cautarea binara este maieficienta .decat

.cautarea .secventiala.

Fie n (neN*) elemente a o' a l ••••• an_I' Ordonap crescator elementele a o' al' ...• an_1oOrdonarea (denumitii in termeni de specialitate !;Ii sortare) este o. problema care

apare frecvent in practica, in orice domeniu de activitate. Cum, de obicei, numarul deelemente care trebuie ordonate este mare, iar rezuIt~tele trebuie obtinute in timp scurt,.aceastA problema a constituit un subiect de studiu important in informatica. Ca unnare,la ora actuala existi'i. zeci dealgoritmi de sortare.

Elevii 'pun de obicei intrebarea: "Unul nu este suficient? Am invatat deja in cIasa celputin trei algoritmi de sortare: Bubble Son. sortarea prin selectie ~i sortarea prininsertie! ",

AIgoritmii de sortare invatati pana acum aveau avantajul simplitiipi. Din pacate,simplu nu inseamna in mod necesar ~i eficient.

Analiza performante1or unui aIgoritm se face dupa dona criterii:

• Dimensiunea spatiului de memorie necesar. Un program necesidi.:- un spa/iu de memorie constant, independent de datele de intrare, pentru memo­

rarea codului sau, a constantelor, a variabilelor simple ~i a structurilor de datealocate static;un 'spa/iu de memorie variabil, a cami dimensiune depinde adesea de datele deintrare. constand din spatiul necesar pentru structurile de date alocate dinamic, a

crescator fl.

Ilx se gaseste in mijlOC

int main (){Citire ();int poz=Cautare(0,n-1);if (poz<O) cout«x«" nu se gaseste in sir\n";

eJ.se cout«x«" apare pe pozitia "« poz;

return 0; }

int cautare(int prim, int ultim){/*functia cauta valoarea x in vectorul a de la pozitia prim pa

n a

la pozitia ultim si intearce 0 pozitie pe care apare x, respectiv

valearea -1, daca x nu apare in sir */if (prim>ultim) Teturn -1; /Ispatiul de cautare este vid

int mijloc=(prim+ultim) 12;if (x==a(mijloc]) return mijloc;Ilx poate f1 doar in stangaif (x<a[mijloc]) return Cautare(prim, mijloc-1);

Ilx peate fi dear in dreaptareturn Cautare(mijloc+l, ultim);

void Citire (){cout«"n= "; cin»n;cout«"Introduceti elementele, ordonate£or (int i=O; i<n; i++) cin»a[i];

cout«"x= "; cin»x; }

#include <iostream.h>int a(10D}, n , x r

~,

~

~

! ', J

rr

,--'! '

""I~

! :L ..J!

, i

l 'SolulieVom meD10ra·.elementele -ee- -e i- _." :an_ l intr-un wector.Deoarece .elementele-sunt

fiordonate 'crescator,nu:este'l1lecesar:gacaut3m,.elementul·.x':Secvenpalc(comparand-pe'X'-x;lll 'flecareelement .din wector, l'ana candllgllsim .sau 'Pana .cand cam.epuizat -spatiul de"cautare), in.acestcaz, ;cautarea'secvenpala:nu~ste,eficienta,fiind necesaren :comparapiin .cazul eel -mai defavorabil {cazul.Jn care xnu-se::gase!;lte:in vector).Pentru a -diminua

rtimPUlde<;autare,:tinem cent-de faptul clielementele'sunt ordonate cresclitor:comparamllelementul x cu .elementul din mijloc. In cazde-egalitate, .cautarease incheie cu .succes,

ajtfel injumatli.!im-apatiulde cautare, .determinand jumatatea in care existli.'lanse;sa .segllseascli eiementul x '§i reluiind cliutareadoarl'enlru aceastli.jumlltate. Daea xestemair mic decatelementul,din mijloc, cautam -numai .tn prima -jumatate; iar .daca x este .mal

[; mare dedit elementul din mijloc, caut3m .doar -In.cea.de a -doua jumatate.Acest mod -de cautare este .absolut natural !;Ii n aplicam frecvent: niciodata nu-vom

,., cauta in eartea de telefonl'e~Popeseu Vasile" tncepand de la litera A. Desehidem eartea! i de telefon (sigur, -nufrx la -mijloc)§ine uitam : ~L.am·gasit'pe Popescu vastle ?". Dacal 1. .da, am incheiat cautarea cu .succes. Daca nu s caut numai in prima parte sau numai in cea

de a dona. dupa cum Popescu Vasile 'precedesausuccece m ordine lexicografica (ordinear din dictionar) -numele .de pe -pagina lacare oeste deschisa cartea, Cautarea decurge in

I ': continuare dupaacela§i 'procedeu.

La fiecare iteratie a ciclului for exterior este calculat max{a o' a 1·••••• a d r } §i plasatpe pozitia dr, elementele de la dr+1 la n-1 fiind deja plasate pe pozitiile lor definitive.Pentru a calcula max{a o' a

1••••• a

d r} sunt necesare dr operatii elementare, in total

1+2+ ... +n-1=nx (n-1) 12. Deci numaml de operatii elementare executate de algo­ritmul de sortare prin selectarea maximului este de nx (n -1 ) 12. independent de ordineaini{iala a elementelor vectorului.

Timpul necesar executiei unei operatii elementare poate fi diferit de la 0 operatie Ia.alta, dar este fixat, deci putem spune ca operatiile elementareau timpul marginit superiorde 0 constanta. Fara .a restrange generalitatea, vom -presupune ca toate operatiileelementare au acelasi timp de executie, fiind astfel necesara doar evaluarea numarului deoperatii elementare, nu 1]i a timpului total de executie a acestora. Analiza teoretica ignoratoti factorii care depind de masina sau de limbajul de programare ales §i se axeaza doarpe determinarea ordinului de marime a numarului de operatii elementare.

Scopul analizei teoretice a .algoritmilor este de fapt determinarea unor functii care salimiteze superior. respectiv inferior comportarea in timp a algoritmului.

Sa evaluam, de exemplu, numarul de operatii elementare efectuate dealgoritmul desortare prin selectia maximului, in functie de n. num.aml de elemente din vectorul caretrebuie soTtat :

caror dimcnsiune -depinde -de .instaataproblemei :derezolvat ··§i'din -spatiul de.memoric necesar .apelurilor «lepmceduri si rfunctii.:Progreselettehnologiceftc'ca Umportanta:criteriului spatiude enemorle utilizavs~

:scada.prioritar .devenind .criteriul -timp,.. Timpul de execiqie. Determinarea-rimpului de .executie -nuse-poate face .prin aularca

-programului.chiar-deammrmar.mare .de ori...deoarece mu2m .obtine dnformatii-decat.despre;,timpulde,execupe .a programului pe.anumiteeseturi :particulare -de-date de-intrare. in plusv ar fnterveni ~i .performantele-sistemufui .decalcul pecare rulamprogramul. Acesteargumenteme conducIaideeaca determinarea-timpului-de execujietrebuieflicutiiprintr-o .analiza teoretica.' Pentru .a analiza .teoretic .algoritmul, vompresupune ca se Iucreaza pe un calculator cclasic" •.in sensul ca 0 singura .instructiuneeste executata la unmoment dat. Astfel, timpul necesar executiei programului depinde.de numarulde operatii elementare (operatiial carortimp de executie este constant.independent .dedatele .de .intrare .aleproblemei) .efectuatc .de .algoritm, Privind .din'perspectiva-calculului -paralel• .acest mcd de analiza a complexitatii-timp a .unui.algoritm va fl. probabil, 'total .inadecvat pentru viitoarele generatii .de calculatoare.Dar .pentru algoritmii ....clasici.. ofera un criteriugeneral de comparatie, -fad. a finecesara 'implementarea si rularea pe un calculator.

65ME'IODA DIVIDE ET1MPERA

La 'fiecare Iteratiea ciclului for.elementele ao' a1

, •••• ai

_1

aunt.deja ordonate ~i.trebuie .sa -inseram -.valoarea a (i) pe pozitia corecta in airul ordonat. in cazul .cel mai.defavorahil, cand vectoruj este .initla! -ordonat..descrescator. fiecare element a [i) va fiplasatpe prima pozfjfe, deci ciclul for interior.se executa de i -1 ori. Considerfuld dreptoperatie elementara comparajia a {po z-1 ] >v• .urmara -dc deplasarea elementului de pepozitia poz-l.vomavea, in cazul eel maLdefavorabil. 1+2+ ... +n-1=nx (n-1) 12operatii elementare,

Sa analizam acum comportarea aIgoritmului in medie, Pentru aceasta, vom consideraca elementele vectoruliJi sunt,distincte §i ca oricepermutare a Ior.areaceeasi probabilitatede aparitie. Atunci, probabilitatea.ca valoarea a

i_

1sa fie plasata pe pozitia k in sirul a

o'a!' ...• ai_I' ke{O, 1 •...• i-l}~ este IIi. Numarul medfu de operatii elementare,pentru i fixat, este :

i 1 1 i . 1 i(i + 1) . i + 1 i-1L-'(k-i)=-'(Lk-")=-'(---")~__l=_k_1i i k"l i 2 2 2

Numarul de operatii elementare necesare in medie pentru a sorta n elemente prinalgoritmulde sortare prin insertie este :

::t i-

1=2:.(n(n +1) -l-(n :"")) ~2:.(n(n+1) -n) = n(n -1)

i=2222 22 4

void Citire (){ifstream fin ("sort.in");fin»n; for (int i=O; i<n; i++) fin»a(i);fin. close (); }

in cazul algoritmului.de:so~areprininseT1ie~.numarulde'operatii elementareexecutate.de algoritm depinde de rlatelede intrare.

I'£or (i=l; i<n; i++)

{v=a l Ll s Ilcaut :pozitia lui v in sirulaO, _._._., ai£or(poz=i; paz && a[poz-lJ>v; poz--) a[pozl=a[poz-1);a [poz) = 'V; }

Sortarea prin interclasare (Merge Sort)

Un algoritm de sortare care se bazem pe metoda Divide et impera este sortarea prininterclasare. Algoritmul de interclasare a doi vectori sortati produce ca rezultat tot unvector sortat, care contine elementele eelor doi vectori ce se interclaseaza. Deci. pentrua sorta elementele ao' al' ...• a n_1 vom imp3.rti ~iruI in doua sub~iruri ao' a

1•••.• am'

respectiv a m+1 ' a m+2 •••• , a n_1 (unde m este mijlocul intervalului), vom sorta sub§irurile(recursiv, prin acela§i procedeu). apoi Yom interc1asa sub§irurile sortate. pentru a obtine§irul ao' a 1 ••••• an _

1sortat.

#include <fstream.h>int a[lOOJ, n;

rI

'PROGRAMAREA"iN LlMBAJUL C/C++'PENTRU,LICEU

Ilcalculez rnaximul de la 0 la drfor (max=a[Ol, pozmax=O, i=1; i<=dr; i++)

if (a[i) > max) max=a[il, pozmax=i;a[pozmax]=a[dr]; Ilplasez maximul pe pozitia dra [dr] =max; }

for (dr=n-l; dr>O; dr--)

64

I

Sa analizam performantele algoritmului de sortare prin interelasare. Vom nota elln'T (n) numarul de operatii elementare executate de algoritm pentru a ordona n, ;: elemente. Observam ca la fiecare pas se impart elementele in dona, deci sunt necesare

'T (n/Z) operatii elementare pentru sortarea celor doua jum~t~li ~i tnca n operatiielementare pentru interclasarea jumatatilor, Prin urmare, obtinem urmatoarea relatie

~ de recurenta :

Sortarea rapidii (Quick Sort)

1. Algontmul de sortare rapida este deja implementat in bibliotecile celor mai utilizate medii deprogramare C/C++ (functia qsort ().

67

.dacan <2.daca n e z

). 10.T(n =\Z.T(n/Z)+n.

METODA DIVIDE ETIMPERA

i<n; i++) fin»a [iJ;

("sort.in");

a [100],i.nt

-vcd.d Citire (){ifstream finfin»n;for (int i=O;fin.close();

)

void Afisare (){cout « "Vectorul sortat este IT;for (int i=O; i<n; i++)

cout « a[il < • ';cou t c-cerid.L, }

Observatii

1. Acest :algoritm .necesita apatiu suplimentar de memorie -pe-stiva, -pentru memorarearezultatului Interclasarlt.

2. Numarul de operatii executate de .algoritm nu depinde de ordinea elementelor .dinsirul de intrare.

Aigoritmul de sortare rapida a fost elaborat de C.A.R. Hoare in 1962 ~ieste ·unuldintre cei mai utilizati .algoritmi de sortare'.

Sortarea rapida se bazeaza pe principiul Divide et impera : se selecteaza -primulelement din sir §i se plaseaza pe pozitia sa corecta in sirul ordonat, in stanga sa fiindplasate numai elemente mai mici decat el, iar in dreapta numai elemente mai marioAstfel, se reduce rezolvarea problemei initiale la rezolvarea a doua subprobleme (sortareaelementelor din atanga elementului fixat, respectiv sortarea elementelor din dreapta),suma dimensiunilor subproblemelor fiind n-1.

Deci: T (n)=n+ZT (n/Z )=n+n+22 T (n/22 ) =n'+n+n+2 3T (n/23 ) = ... =n+n+ ....+n+ZkT (n/2 k

) • Cum in final n/Z k trebuie sa fie egal.cu i , .deducem ca numarul de apelnrirecursive .este ,k= [1092n] -. 'Deci .numarnl de -operatiielementare 'efectuate" de acesr.a1goritm-desoTtareeste n[lo92n].

I,~o,"'o <zs t.reem. h>

,,,;

'PROGRAMAlffiA1N' LIMBAJUL C/C++,pENTRU :L1CEU

..int main ()

void MSort(int P, int q)(//sorteaza elementele alp), ..• , a l q l

if (q>p){

.int m=(p+q)/2;MSort (p, m);MSort (m+1, q);

Interc1asare(p, m, q);

Citire();Msort(O, n-1);Afisare();return 0;

-void Jnterclasare(int p, int~, iut q){/Iinterclaseaza .subsirurilesortate .a [p_._~m] .s f .a [m+L '. q]

int i=p, j=m+l, k=O:lieu i 'parcurgportiunea a Ip v vml , ell j .por t.Lunee .a Im-el. •.• q]

.i.nt b[lOO];//vector in care retinem temporar rezultatul interclasarii

whi~e (i<=m && j<=q)i"f (a[i]<a[j]) b[k++l=a[i++]:

·else b[k++]=a[j++l:

while (i <= m) b[k++]=a[i++];while (j <= q)b[k++]=a[j++]://transfer rezultatul interclasarii in vectorul a-for (i=Pi i<=q: i++) a[i]=b[i-p):}

-void Afisare (){cout -c "'Vectorul sortat este .... ;£or (inti=O; i<n: i++)

cou t; -c a [il -c I ':

cout«endl; }

,"

r:66

r,( Il ,

r

r;:i i

"

"

t j

~

i

i"'

l ;

n, :, :, :, ,

r-'

I

i i: ,, ,

r-:'i i1 ~J

~,,!

,68 -PROGRAMAREAiN:LIMBAJUL·C/C++PENTRU LleED

r!

METODA DlVlDE EF1MPERA 69

.i.nt main .()

- Se apeleaza QSort (4,6) ; se apeleaza functiaDivide (4, 6), care intoarce pozitia corecta insirul ordonat a elementului 8 ~i plaseaza toateelementele maimari decat 8 in dreapta (30 ~i

10), iar stanga lui Bnu plaseaza nimie. In urmaapelului, m=4 ~i a= (0,2, 3, 5, 8, 30, 10).

Probleme propuse

1. Scrieti un program care sa caIculeze minimul dintr-un sir de elemente, utilizandmetoda Divide et impera.

~

--

I,lll'I ~~I:I ~!t~1I:Fi~

'~F~i '

II,;:' ( 1II:(! !

I' +" I ~i l

'

"'I":': :, ·1 '

[,!'i"I!"l~1.',.":'I:T'I'; 1'I': I

1',,1;: Iis' ~~I~I 'I;"), 1

~~i~-i 'Jli§!J,'1':"lr 1rt~i' \; i"',t~ . i :

1':II'IU

;:1: l; il~f'~ wI: rl'l: .~

I",./.1:;1.'1\' ''iLI>~

it ;

#include <iostream.h>

~ong Ghici(int p, int q){if (p>q) return 1;

n-l+n-2+ ... +l=nx(n-l)/2

Analizand comportarea in medie a algoritmuhri de sortare rapida, deducem I canumarul de operajf elem.entareexecutate de algoritm este aproximativ egal cu 2 xn xIn (n) .in concluzie, in practica algoritmuI de sortare rapida este performant.

Ca un rezultat general valabiI pentru algoritmii de sortare, s-a demonstrat ca numarulminim de operatii necesare oricarui aIgoritm de sortare prin compararea elementelor esten Xlog2 (n) .

Sa analizam performantele acestui mgoritm. In cazul eel rnai defavorabil (de exemplu,cand vectorul era inipalordonat),se fac n-l apeluri succesive .ale funcjiei QSort, cuparametrii (D,n-1), (0,n-2), "" (0,1) (dacavectorulerainipalordonatdescresdi_tor)sau (D,n-l). (l,n-l) •...• (n-2,n-l) (dadivectoruleraordonatcrescator). Lafiecare apel.al functiei QSort esteapelata functia Divide (0, i) (sau Divide (i, n-cL) ),care efectueaza i-I. respectiv n-i-l operatii elementare. in total, numarul de operatiielementare este :

-'se:apeleaza QSort (5,'6) ; -:se.ape­Ieaza functia Divide (5, 6) ,.care'intoarce pczljia -corecta Jn slrulordo­nat a elementului 3o§i plaseaz1ipe 10in stanga sa, iar indreapta lui ~3 0 nuexista nimic. .In.urma apefujuj, m=6

I , ,121 a= (0, 2, 3, 5,8,10, 30).

2. Ghicirea unui numdr ascuns

Tu Iii calculatorul ati puteajuca impreuna urmatorul joc : unul dintre voi "se gandeste"la un numar cuprins tntre I 12i 1000, iar celalalt incearca sa-l ghiceasca, evident punandcat mai putine fnrrebarl. Singurele irurebari permise sunt:

- nNumlirul este egal eu.. , ? n

- ."Numarul este mai mare decat. .. ?"- "Numarul este mai mic decat... ? "

Celalalt jucator poate raspunde numai prin "Da" sau "Nu". Scrieti un program caresa simuleze un astfel de joe.

3. Care este efectul urmatorului program ?

,

Citire () ;QSort (0, n-l);

Afisare o..return 0;

void QSort{int p, int q){

I/sorteaza elementele a[p], .. _, a[q]

intm=Divide(Pr q);if (m-l > p) QSort(p, m-l);if (m+l < q) QSort(m+l, q);

int,Divi-de (int-p,.int,q)

{/*:p~,aseaza -e Lemen t.u.L .e Ip l rpe :pozitia :'Sa'co~ecta in -vect.oxu.Lordonat,.:i.n -s t.arrqa esa Iiind pl-asatenumai<elemente -maL -md cd., .iar:intireaptanumai'€lemente .ma L sma-rd :decat -e L si intoarcepozitia:pe'care<a £ost plasat~[pl*/

-i.nt st=p, dr=q, .x-ee (p] ;

'Whi~e (st<dr)

{"h:i~e (st<dr"&& a[dr]>=x) dr--;

.a Ls t l-ee l d.r l ;~hi1e (st<dr && a[st]<=x) st++;a[dr]=a[st);}

a[st]=x;:returnst; }

Pentru a tnjelege mai bine -modul de functicnare aacestui algoritm sa urmarimexecutia sa pentru n=7 §i a= (5, 0, 3, 8, 2, 30, 10). in programul principal se apeleazaQSort (0, 6) . In cadrul acestui apel :- Se apeleaza functia Divide (0, 6), care intoarce pozitia corecta in §irul ordonat a

elementului 5 §i plaseaza toate elementele mai mici decat 5 In stanga sa, iar elementelemai mari decat SiD dreapta. in urma apelului acestei functii, m=3 §i a= (2, 0, 3, 5,8,30,10).

- Se apeleaza QSort (0,2) ; seapeleaza Divide (0, 2), careintoarce pozitia corecta in sirulordonat a elementului 2 ~i

plaseazape 0 In stangasa, iarpe 3 In dreapta, Dupa apel, me L~i a=(D,2,3,5,8,3D,10).

1. Demonstrada riguroasa necesita cunostinte matematice avansate.<1"",III

I'

__~_ ~~ ......nU.....' • .Dn. IN LIMBAJUL C/C++ "'PENTRU LICEU

intr=(p+Q)/.2;xeturn .r*Ghicitp, X-J.) ......Ghici (r+~,q);}

int -maLn ()lint -n r.cout < "".n= ~"; c.Ln »n;cout -« Ghici (l,n)·«endl; :return O;)

1METODA DIVIDE EI'1MPERA

..int main()(intn;cout«"n= -IT ;cin»n;p(n/Z, n/2, n/2, I a');

£or(int i=1; i<=n; i++){£or (int j=~; j<=n; j++)collt «a[i] [jJ ;cout«endl;)

.:return 0;

71 I~!I1\1.

i'

r1I 1

5.Sumil maxima in triunghiSa consideram urmatoarea problema.Fie un triunghi T format din n Iinii (1 <n<100), fiecare linie i continand inumere

fntregi, ca in exemplul urmator :

j+1) ;Suma_Dr) ;}

5

4

6

o4

2

73 8

17

8

5

24

Este eficienta 0 astfel de abordare? Ce concluzie puteti trage? Cand este eficientautilizarea metodei Divide et impera? Descrieti un algoritm iterativ de rezolvare aproblemei.

6. Riglii gradatdMesterul Vasile are nevoie de 0 riglli gradata specials. Lungimea riglei este data (L),

dar gradatfile nu trebuie sa mareheze centrimetrii sau milimetrii. Pe rigla, gradatiiletrebuie sa fie plasate astfel :

- la mijlocul riglei (interval de lungime L/2) se plaseaza un marcaj eu lnaItimea de16mm;

- . sferturile (intervale de lungime L/22 ) trebuie marcate prin gradatii eu inalpmeade8mm;

- optimiJe (intervale de lungime L/2 3) trebuie marcate prin gradatii cu inliltimea de4mm;

Problema canst! in serierea unui program care sa determine cea mai mare suma denumere aflate pe un drum, intre numarul de pe prima linie §i un numar de pe ultima linie.Fiecare numar dinaeest drum este situat sub precedentul, la stanga sau la dreapta.acestuia.

Putem aborda aceasta problema intr-o maniera Divide et impera, seriind 0 functiecare sa calculeze suma maxima astfel :

i .int Suma (int i, .int j)

II {if (i<n).. lint Suma_St=Suma (i+1, j) I. Suma_Dr=Suma (i+1,. return T[i] (j]+(Suma_St>Suma_Dr ? Suma_St

return 0; )

ali] [j)~c;

(r>l)(p(x-r/2,y-r/Z,r/2) ;p(x+r/2,y-r/2,r/Z);p(x-r/2,y+r/2,r/2);p(x+r/2,y+r/2,r/Z); }

c++;if (r>l)

(P(x-r/2,y-r/2,r/Z,c);p(x+r/2,y-r/2,r/2,c);p(x-r/2,y+r/2,r/2,c);p(x+r/2,y+r/2,r/Z,c);}

return 0;

if

b)#include <iostream.h>char a [129] [129];

void P(int x, .int y, int r, char c){-for (.int i=x-r/2; i<=x+r/2; i++)

for (int j=y-r/2; j<=y+r/2; j++)

l ~r'i I

rt! '1' .int main ( )

lint n;cout«"n= ", cin»n;P (n/Z, n/2, n/2);

for (int i=l; i<=n; i++){for (.int j=l; j<=n; j++) cout«a[i] [j];

cout«end1;}

\'

r-j! ,

; I, In! ..i!

~

~l

[I

7. Triunghiullui SierpinskiUnul dintrecei mai faimosi ."prefractali" .este triunghiul construit dematematicianul

polonez Waclaw Sierpinski, pomind de I. un triungbi care se imparte in patru triunghiuriegale. Fiecare dintre cele patru triungbiuri obtinute -se imparte la randul lui in patrutriunghiuri egale. Procedeul continua .astfel _Ia mfinit".

lO.Se/eelie ,Pie n elemente (neN*) at' a 2 •.•••• an' Desorietiam:algoritmDivide et impera Care

'sa selectezecel -de.al k-lea eel maimic 'element .dinsir (k-eN*., kSn).

v - vertical), apoi pozitia 'de .Iacareseface 'plierea, ..poi anodul .de-pliere. (L _ 'Parte.stanga deasupra; R --partea<lreaptli .deasupra ; u - -partea<lesusdeasupra;n _ parte..de josdeasupra), doua l'lieri consecutive fiind .separate prm spatiu, Daca problema- nuare aolutie.iseva .afisa mesajul : .' Ghinion I •

rn PROGRAMAREA iN LIMBAJUL C/C++ 'PENTRU.L1CEU

<§.isprezecinille ,(intervale <de lungime L/2') rrebute marcate pringradatii .cuinaltime.<de2 mID;in srar§it, intervalele de -lungime L/ 25 .trebuie marcate prin -gradatii cu lungimea-de 1=.

Rigla va =ataca in figura urmatoare :

] ... 1. ..I . I i I . I • L .. ,I, •• 1

Scrieti 1111 program care sa .afiseze pe ecran in mod -grafic 0 rigHiastfel gradara.

r,I METODA DIVIDE Er_IMPERA

73

ri

"r':;:

" 1

. I-\ I,~

f

11'1~l

; II :

liil;J

Ill.

!',ll]

,I

'I," 1KJ!"iji. :~l,~II I:j(i,l!! ,Jl--..lI:

~t:

'::,!

Scrieti un program recursiv care Sa citeasca de 1a tastatura coordonatele varfurilortriunghiului 'initial §i afiseaza in mod grafic un triunghi Sierpinski obtinut dupa n iteratii(n citit, deasemenea, de la tastatura),

8. Pliere cu modijicarea valorilorFie un vector cu componente intregi. Prin plierea vectorului (definitli ca in aplicatia 3)

din dublul valorii fiecarui element din jumatatea receptoare se seade valoarea ele­mentului corespunzator din jumatatea donatoare. De ex.emplu, din (10. 20, 30, 40,50) se obtine dupa 0 pliere la stanga (C30, 0), iar dupa 0 pliere la dreapta (60, 90).Scrieti un program care sa verifice daca exista un element final ell valoarea 0 ~i daca da,sa afiseze succesiunea de plieri corespunzatoare.

9. Impiuurirea hartiloro harta strategica este reprezentata ca 0 matrice cu n linii §i m coloane, fiecare

componenta a matricii continand cota zonei de reren corespunzatoare, Determinati 0

modalitate de a tmpatun harta astfel mcat deasupra sa se gaseasca 0 zona de arie maximaavand aceeasi cota, Plierea hartii se poate face doar orizontal §i vertical (deci, pe direcjiiparalele cu Iaturile hartii) §i numal in doua part! egale (deci daca 0 dimensiune esteimpara, plierea de-a lungul laturii respective nu este posibila). Pe ecran se va aflsa ariazonei astfel determinate, cota corespunzatoare, precum §i codificarea sirului de plieriefectuate, folosind urmatoarea conventie : se precizeaza mai intAi directia (0 - orizontal ; ,

i;j'-l

"

r

i :

ilI 'I I

75MIDODABACKTRACKING

1. in limba englezl, back inseaIll1Ul: ,.inapoi" • iar track lnseamm "urm~".

void BRT (int k)

{//eand apelam funetia BRT eu parametrul k presupunem ea//pozitiile 0, 1, ..., k-l din veetorul x sunt fixate

Element MC[]; int nc;//tipul elementelor din Me depinde de problema concreta

Observati d,l'eparcursul.construcpei, -ccpilul face anumite verificari-tse .potrivestel'iesa aiel? rna l'0ate conduce la nnodeluldoritv), .eliminand astfel foarte multe .dintre-solutiile .posibile.~Cu-3lte .cuvinte, .cautarea .nu-este exhaustiva.

Un;alt aspect semnificariv .estefaptul.ca-se -iacreveniri. Dad! Ja un moment dat .numai.poate.continua:construcpa,.copilul revine Ja .pasul precedent, .lndep3.rteaza piesaaitilizata~i incearca'sa o'inloDuiasca,:dacaeste-posibil.Dadi. nu .este posibil, face reveniri-succesive, "Pan3. cAnd.~ase~te:o_piesa·pe care opoate Inlocui si apoi.continua constructia,Acest mod de abordare se .bazeaza pc 'principiul ~rncerc asa daca nil merge rna .intorcsl.tncerc -o alta varianta ! ",

FAre'sa stie, eopilul.din exemplu aaplicatmetodaBacktracking. 'Numele metodei estesemnificativ' ,§i s-ar putea traduce prin ."a 0 lua fnapoi pe urme" sau, -cu aproximatie,prin ."cautare cu reverure".

.Sa descriem .acum -lntr-un modmai general metoda Backtracking, in varianta ele­mentarav consideram .ca -solutia -problemei pe care .trebuie sa 0 rezolvam se poatereprezentaca .unvector .x=(x o' Xl' ••• , xn_1) . -Fiecare componenta Xi a vectoruIui poateIna valori intr-o anumita mulprne Si (i=O, n-u.). Produsul cartezian soxs1 x... xSn_

1

ee -numeste spatiul sotutiitor posibile,Problemele care se rezolva prin Backtracking nu impun generarea tuturor solutiilor

posiblle (generare exhaustiva), ci doar aacelor solutii care Indeplinesc anumite conditii,specifice problemei, .denumite conditii interne. Solutiile posibile care respecta conditiileinterne sunt denumite solutii-rezultat,

Unele probleme impun objinerea unei singure solutii-rezultat, §i anume a celei carefndeplineste o anumita conditie de optim, Aceasta este denumita soltqie optima.

Pentru a evita generarea tuturor solutiilor posibile, metoda Backtracking atribuie perand valori elementelor vectorului x. Mai exact, componenta x k primeste 0 valoarenumai in cazul in care componentele X O' Xl' ••• , X k_ 1 au primit deja valori. In acest caz,componentei X k i se atribuie pe rand acele valori (din multimea Sk) posibile careindeplinesc conditiile de continuare. Condijiile de continuare sunt condijii derivate dinconditiile interne care stabilesc daca pentru 0 anumita valoare pentru X k are sau nu senssa continuam constructia solutiei. Spunem ca 0 anumitii valoare pentru X k nu indepline§teconditiile interne daca oricum am atribui valori componentelor X k+1' ••• , xn_ 1 nu obpnemo solutie-rezultat (solutie care sa respecte condiplle interne).

Dupa atribuirea unei valori posibile care sa respecte condit-iile interne componenteix k ' se poate continua constructia solupei in mod recursiv (de data aceasta, sunt fixa~e

k+l pozilii).Pentru a descrie formatul general al metodei Backtracking Yom utiliza 0 functie

BRT (). Consideram ca n, num~ de componenteale vectorului, ~i vectorul X suntvariabile globale,

1!

CAPITOLDL3

n Timp de executie

40 109 secunde50 31 de ore

100 4.10 13 ani

Metoda Backtracking

r--, E l'ulin probabil sa l'utem ~tepta acit!Prin urmare, trebuie sa abordam astfel de probleme in alt mod. 0 idee ar fi sa

,procedam ca in muite situatii din viata de zi cu zi. Sane gandim la modul in care un copilrezolva un puzzle. Copilul nu face toate 'combinapile posibile de piese pentru ca apoi san Ie compare cu mode1ul pc care vrea Sa il oblin)\' El va lua mai incii 0 piesa. Va caUla apoi

l i in multimea de piese dimase una care sa se potriveasca la cea pe care 0 are. apoi inca una§.a.m.d. Daca la un moment dat ,,00 blocheaza" (nu mai gase~te nici 0 piesa printre cele

r----Ta.mase care sa se potriveasca), el nu distruge tot ce a construit ca sa 0 ia de la inceput.I ; Va indeparta mai intai ultima piesa pe care a pus-o ~i va cauta 0 "alternativa." (0 alta

;piesa. care s-ar potrivi in locul ei). Daca. gase~te, .continua constructia cu noua piesaaleasa. Daca nu gase~te, se mai intoarce un pas ~;i indep3.rteaz3. ~i penultima piesa pe care

_ a pus-o, cautftnd apoi 0 alta variantii. Procedeul continua pan3. cand obpne modelul, dorit.

11I j

nDeseori, jn-practica, apar probleme care implica .alegerea unor solutii optime dintr-un: [spatiu extrem de vast de solutii posibile.l i. Un teoretician ...pur" .ar raspunde: "Nici 0 problema! Construim (oate solutiile

posibtle §i Ie alegem apoi pe cele oprime !", Dar este realista oastfel de .abordare ?r, Sa analizam un caz foarte simplu: sa presupunem ca problemanoastra Implica! :, selectarea uneimultimi de n clemente care trebuie sa tndeplineasca .anumite conditii.< J pentru fiecare element i -presupunem ca exista Pi posibilitap de alegcre. A genera toate

solutiile posibile Inseamnd de fapt a genera toate elementele produsului cartezian {l, 2•... ,n,lP1

}x{1, 2, .. .: P2}x ... x{l,?, .,., Pn}.Acestprodu~cartezianarePlxP2x.... xPnl ilelemente. Chiar daca vom considera ca Pi =2, pentru once ide la 1 la n tot obtinem 2

n

solutii posibile, E mult? Sa evaluam cu aproximade timpul de executie a unui program

n bazat pe un astfel de algoritm, presupunand di dispunem de un calculator care executa, run millard de operatii pe secunda (10 9 operatli).I I, ,

~

i : • ... •[,1. Descrlerea generalaa .metndei

nI :

Conditii interne

Problema reginelor

Sa se plaseze n regine pe 0 tabla de ~ah de dimensiuni n x n astfel incat oricare donaregine sa nu se atace.

1!

.~

77

amk,eu parametru1k-l * I

D; }

Ilam obtinut 0 solutieIlprelucrarea solutiei consta in afisare

METODA BACKTRACKING

o#include ·<iostream..h>4/'include -<math .h>~include <conio.h>:int -n,NrSol, C [30] ';

vo~d P~aseaza_Regiria(int);

·j.nt:main ()

CQut«"n= 'fI; cin » n s

P~aseaza_Regina(O); ~eturn

"Void Afisare ()

tint i, j;

cout«"-Solutia nr ."« ++NrSol«endl;£or (i=O; i<n; i++)

{for (j=O; j<n; j++)

.if (j==C[i]) cout«" * ";-e.Lee cout;cc" 0 ";

cout«endl;)cout«endl; getch();

Sa analizam modul in care programul genereaza aceste solutii. Pentru aceasta, Yomurmari executia programului pas cu pas. Pentru adresa de revenire, • indica sfarsitulfunctiei main (), iar • indica acolada care marcbeaza sfarsitul instruc{.iunii for dinPlaseaza_regina (). Semnul , ? .. utilizat la inceputul unui apel recursiv indica faptulca variabilele locale au valori, dar sunt nedefinite,

rI

voi~ Plaseaza_Regina(int k){/*cand apelam functia Plaseaza_Reginaplasat deja regine pe liniile 0, 1,

., int if j, ok;I .i.f (k~~n)

IAfisare () ;e1.se

//trebuie sa mai plasam regine pe liniile k,k+l, ... ,n-l" for (i=O; i<n; i++)

//verific daca pot pIasa regina de pe linia k in coloana i{for (oke L, j=O; j<k; j++)

oif (C[j]~~i I I abs(C[j]-i}~~(k-j» ok-D;/*regina s-ar gasi pe aeeeasi eoloana sau aeeeasi diagonal a eu 0

regina deja plasata *1if (ok) IIva10area i respeeta eonditii1e interne

{C[k]=i; IIi este un candidat, i1 ext rag imediatP1aseaza_Regina(k+l);}}

rI

C[i.] C[j], ,, ,, •i. --1A

5<,

j~ 45

/Isolutia 'estecomplceta

/lcontinuam ,generarea

//extrag -un candidat din~MC

/Iapel recursiv

in -vect.oxuL Me cele -no -e Lemerrt.e dinconditiile de continuare*/

PROGRAMAREA iN LIMBAJUL C/C++PENTRU LlCEU

(k~~n)

Prelucrare_Solutie() ;

"e~se

{Candidat(MC~ .nc , .k);

/*£unctia Candidat"retinemultirnea :~k carerespecta

for (int i=O; i<nc; i++){x [k] ~ MCtil;

BKT (k+l);}

oif

1. C[i]E{O,l, ... ,n-l}, 'v'ie{O,l/ ... ,n-l}

(elementele vectorului c sunt indici de coloane);2. C[i],*C[j], V'i¢j, i,jE{O,l, ... ,n-l}

.(doua regine nu pot fi plasate pe aceeasi coloana) ;3. IC[i]-C[jll¢li-jl, Vi:;i:j, i,je{O,l, ...,n}

(douli regine uu pot Ii plasate pe aceeasi diagonalli).

Reprezeraarea informatiilor

Pentru ca doua regine sa nu se atace ele nu trebuie sa fie situate pe aceeasi linie,peaceeasi coloana san pe aceeasi diagonals. Cum numarul de regine este egal cu dimen­siunea tablei de sah, deducem ca pe fiecare linie trebuie plasata 0 regina. Deci, pentruca pozitia reginelor sa fie complet determinara, este suficient saretinem pentru fiecarelinie coloana in care esteplasatii regina. Pentru aceasta, vom utiliza un vector cell ncomponente, avand urmatoarea semnificatie : c lLJ reprezintii coloana in care esteplasata regina de pe linia i.

Din .descrierea -generala a metodei Backtracking nu reiese explicit unde.intervinerevenirea. Pentru aceasta.ttrebuie sa De gandim -lamodul de realizare.a -recursivitatii.

La fiecare apel recursiv se memoreaza pe stiva valorile variabilelor locale §i valoareaparametrufui. La incheierea unui apel recursiv, -seelibereaza zona de -memoriealocata pestiva §i se -revine la apelul precedent.

Pentru a tntetege rnai .bine moon! de functionare a .acestei metode saanalizamurmatoarea problema.

76

78 'PROGRAMAREA 'iN LlMBAJUL C/C++PENTRUUCEU 1 METODA JJACK:TI/ACKING 79

--------=:::-:.. Compar valoarea parametrului k ell n : deoa­

rece k-err, sofutta nu este completa ; deter­min candidatii pentru poaitia k=2.

Compar valoarea parametrului k cu n;deoareee k<n, sotutla nu este compteta :determin cendidattt pentru pozitia k=3.

Atribui variabilei i valoarea 0 lji verificdaca pot pIasa 0 regina pe pozitia 3, o. Pecoloana 0 este plasatli deja o-regina, veri­ficarea esueaza $i atriblli variabilei i valoa­rea 1. Din nou, pe coloana 1 existli.deja 0regirui, atribui variabilei i valoarea 2, darpozitHle 3, 2 -$1 2, 3 sum pe aceea$idiagonala. Atribui variabiJei i valoarea 3,dar pe coloana 3 existli deja 0 reginli. Amterminat ciclul for nira a executa nici unape! recursiv. Revin Ia apelul precedent,P1aseaza_reg~na(2).

Comparvaloarea parametrului k cu n;-deoarece k-cn, sclujta nu este completa:detennin candidatii pentru pozi{ia k=2.

Atribui variabile! i valoarea 0 -$i vecificdaca pot pIasa 0 regina pe pozttte 2, o. Peeoloana Oeste plasatli deja 0 regina, verjfi­carea esueaza -$i .atribui variabilei i vatoe­rea 1. Verificarea se termina eu succes,plasez 0 regina pe pozlna 2 I 1. ApeJamv·_··,,··,"

Plaseaza_Regina{2l

Plaseaza~Regina(l)~

Cand revenlmfuapeful Plaseaza Regi­na (1 ) , memoria '.llI1ocatl pe :stivi pentru

.apetul -Plaseaz.!:i. Regina (2) -s-a eli­berat .si revenim 1a-Instructiunea 'lie dupaapel : -intUnimacolada.de la blocul instruc­liunii __for c-$i marim war'iabila 'i cu 1 (i

devine 3). Verific4m -daca putemplasa 0_regimin pozipa 1,3. Verificarea:se termina.cu succes, -plasez 0 regina in pczitia 1,3,-$i:apelezTecursiv Plaseaza_Regina (2).

~Variabile globale SUva

0 CD 10 30 0 I 2 ? ? ? •NrSol n C 1 3 1 I •0 0 0 I ••k i j ok

VariabiIe g/ohale Sliva

o CD I 0 3 1 0 I 2 1 2 1 -INrSol n C 1 3 1 1 •9 0 0 1 •k i j ok

~Za_Regina{:Variabile giobale

Sliva '"OJ CD I 0 3 1 0 I 3 ? 7 ? •NrSol n C 2 1 2 1 •1 3 1 1 •0 0 0 1 •k i j ok

VariabiIe g/oha/e Sliva,

~OJ CD 10 3 1 0 I 3 3 2 0 •NrSol n C 2 1 2 ' 1 • :1 3 1 1 •0 0 0 1 •k i j ok

VariabiIeg/oba/e -Stiva

0CD] 0 2 0 01 fHffiIE!ijNrSol n C o 0 0 1.

k i j ok~

Vartabile-giobale

~I0CDl03 0 0 INrSol n C o 0 0 1 _

k i j ok

Atribui varlabilei i -valoarea 0 §i verificdaca pot piasa 0 regtna pe pczftia 1, O. Pecoloana 0 oeste plasatli. .deja o regina, -verl­ficarea -esueaza -$i atribui variabilei i valoa­rea 1. Nici .aceasta valoarea-nu este utila,pentru eli reginele din pozitiile 1, 1 -$i 0, 0sum pe aceeasl diagonala. Atribui variabileii valoarea 2. Verificarea se tenninli cu succes,plasez 0 regina in pozttla 1, 2 -$i .apelez .recursiv P1aseaza_Regina (2).

Atrtbui -varlabilei -tocale i waloarea 0 -§iverific ;..daca 'POt"PIasa 0 -reglna-pe .pozltta0, O. 'Verificareas-a·1erminatcu 'succes,

-plasea 0 regina pe pozitia 0, O§i apelez-recursivfunctla Plaseaza....::Regina (1).

Stiva

~ I-'o'---/r.o,-,/1;-r./_-/k i j ok

Stiva

[0 17 171? I_ 1k i j ok

Plaseaza

plaseaza_Regina-(l) c~rea"parametruIUik cu n;:::::--"deoarece k<n, -sclutla -nu-este -completa ;

.determin candidatii pentru pozitla k=l.

Variabile global::e~ _

0CDl o o o o iNrSol n C

Variabile globa/eo [3] '-1o~o-'0-0"1NrSol n C

Atribui variabilei i valoarea 0 si vertncdaca pot piasa 0 regina pe pozitta 2,0. Pecoloana Oeste plasata deja 0 regina, veri­ficarea esueeza lji atribul variabilei i valoa­rea 1. Nici aceasta valoarea nu este utila,pentru ca reginele din pozitiile 1, 2 -$i 2, 1sunt pe aceealji diagonala. Atribui variabileii valoarea 2, dar pe coloana 2 existA dejao regina. Atribui variabilei i valoarea 3,dar -$i in acest caz verificarea e-$ueau,pentru ca regina de, pe pozitia 1,2 este pe

aceea-$i diagonalli eu cea de pe pozitia 2 , 3. Sunrem in si£Uatia in care pe linia 2 nu putem pIasa nici 0 regina.Instructiunea for s-a terminat tara nici un apel recursiv, revenim laapeluiprecedent, Plaseaza_Regina (1).

Variabile globale Stiva

0 CD I 0 0 0 0 I~NrSol n C o 0 0 1_

k i j ok

Variabile globale Sliva

0 CD 10 2 0 0 I~NrSol n C o 0 0 1 •

k i j ok.

program principal

Yariabile globale 10[3]1 0 0 0 01.. ~-, n C

r--:

r-

rII ,, .

\ ;,

~

~

,-'! ,: J

i.....

,....,

~

i

n" IL j

I :

n, ,

,-II ,

; !

~

/r,

Plaseaza Regina(l)

·Plaseaza....:.Regina (3)

Plaseaza_Regina(O)

: 1i i

LJ

,i..-I

I i1 i

jI

.J

.U

81

i valoarea 0 ~i ved­a 0 regina pe poatnaOeste plasata deja 0

carea esueaza ~i atribuiloarea 1. Din nou, pe

deja 0 regina, atribui'area 2. Verificarea ses, pIasez 0 regina pei apelez recursivina (4).

a parametrului keu,soJutia nu este eom­

candidatii pentru pozl-

Compar valoarea paramerrulut k cun ~ deoarece k=n, soluna este com.pleUi, 0 afisez sl revin in subprogramulapelant, Plaseaza_Regina (3).

_":..Comparvaloarea -parametrulul k cun ; .deoarece k-cn.eolujianu.este eom­'pIet!; determin.candjdant penttu pozf­tiak=2.

'METODA-BACKTRACKING

Pl~seaza~Regina(2)

Atribuivariabilei i -valoarea 0 si verl­fie -dacli pot piasa o regtna pe pozitla2.0. Verificarea se rermina cu succes.

'plasez o reginli in pozilia 2, O!Si -ape-

~,......_...... '"

Plaseaza_Regina(3)~

Variabile globale II Sliva

[2][D11302! 1'" ? ? •NrSol n C ! 3 2 3 I -2 0 2 1 -I 3 1 1 -0 1 0 1 •

-Variabileglobale :Sliva

0eDI1 3 1 0 1 2 , , ? -'NrSol n C 1 3 1 I •0 1 0 1 •k i j ok I

V.ariabi/eglobale .Stiva

0 eD 11 3 0 01 2 0 2 I -INrSol n C 1 3 1 I ,0 1 0 1 ik i j ok

Variahile globale Sliva

0 [D-11 300 1 3 , , ? -NrSol n C 2 0 2 I -I 3 1 I -0 1 0 1 -k i j ok

Variabile globale Stiva

0 [D 11 3 0 21 3 2 3 1 -NrSol n C 2 0 2 1 •1 3 1 1 -0 1 0 I • ~k i j ok,

/Plaseaza_Regina(4)~

I II

Executia continua in acel~i mod pan3. cand stiva se gole~;te complet §i se revine inprogramul principal.

rI!,

cand reveniminapelul Plaseaza_Regi­na (1) , memoria elocata pe 'stivl pentruPlaseazii Regina (1)s-a eliberat ~i

revenim .la "instrccucnea oe ',dupli .apel :intMnim .acolada de lablocul Instructiuniifor. Ciclul for 's-a termmar.uevenim laapelul precedenr Plaseaza_Regina (0).

Atribui variabilei i valoarea 0 !Si verificdaca 'pot piasa 0 regina pe pozitla 1, o.Pozitla 1, 0 este in dlagoaala Cll pozitia0, 1. Atribui variabilei i valoarea 1, darpe coloana 1 esre plasata deja 0 regina.Attibui variabilei i 'valoarea 2. Niei aeeas­ta valoarea nu este lltila, pentru ea reginel edin pozitiile 0, 1 !Si 1, 2 sunt pe aceealjidiagonall1. Atribui variabilei i valoarea 3.Verificarea se tenniIm eu succes, plasez.oreginli in pozitia 1, 3 !Si apelez recursivPlaseaza_Regina(2).

'C!nd .revenimetn epelul :PlaseazajRe­":gina.(2 ).•:memoriaalocata-pe stiv41pCntru:.apelul'Plaseaz~ ,Regina (3) a-aeliberat,§i .revenimJa.,instrucllunea-de .(fup!-apel ::intilnim-acclada -deda~locuIdnsrructiunltfor ;§i -martm wanabtla i..cul (i devine2). Verificmndac!'Putem"Plasa 1HreginlJn:pozitia 2 , 2 •.dara-ar.afla-pe.aceeesl diego­'.Ilall-cu regina -de 'pe lJOzitia ,0, O. Atribuim-vartabitet i -ealoarea a, -dar pe-coloana 3-exista -deje 0 .regfna. -Prtn urrnare, .ciclulfor -s-a uermlnat fiirli .nici un alt .apel

-recurstv.rrevenim .Ia.subprogramul apelentP~aseaza_Regina(1).

Cand revenim inapelul Plaseaza_Regi­na (0). memoria alocata pe stiva pentru.apelulPlaseaza Regina (1) s-a eliberat~i revenim la insrructiunea de dupa apel :intalnim acolada de la blocul Instructtunttfor ~i manm variabila i ell 1 (i devine 1).Verificarea s-a terminat cu succesiv, plasez 0

regfna pe pozttia 0, 1 !Si apelez recursivprocedure Plaseaza Regina (1).---- -

Plaseaza Regina(l)- -::-,..

Compar valoarea parametrului k cu n ;deoareee k<n,solutia nu esre .completa ;determin candldattt pentru pozltia k=l.

PROGRAMAREA"iN LIMBAJUL C/C++PENTRU UCEU

Variabi/e globale Stiva

0 [D 11 3 1 0 I~NrSol n C o 1 0 1.

k i j ok

Variabile globale Stiva

0 [D 11 3l 0 I~NrSol n C 010111

k i j ok

Variabile globale Sliva

0 [D 10 3l 0 I~NrSol n C o 0 0 1 •

k i j ok

Variabi/e globale Stiva

0 [D 10 3l 0 I lolo~NrSol n C k i j ok

Variabile globale Stiva

0 [D 11 3l 0 I I 0 11 I 0 I 1 I-INrSol n C k i j ok

Variahile globale Sttva

0 [D1 0 3 1 0 1 2 1 2 1 -NrSol n C 1 3 1 I -0 0 0 1 •k i j ok

Variabile globale SUva

0 [D1 0 3l 01 2 3 1 0 -NrSol n C 1 3 1 1 -0 0 0 1 -k i j ok

-80

, .I

i !:82

r:PROGRAMAREA'iN LIMBAJUL-C/C++'PENTRU DCED 1 .METODA BACKTRACKING 83

1 i'·'2. Aplicajii

4finelude '<£stream4h>4fdefine. -NrMaxMonede '20

"· iPlata unei sume cumonede de valori date

Avand .Ia-dispozitie n .saculeti -cu monede, :fiecare !Saculet·contin§nd monede de .aceeasir valoare, -saee efiseze .toate modalitatile.de a plati '0 sumadatasfolosindnumai monedele! ;,din -saculeji.L.J De exemplu, -sapresupunem ea trebute saechitamsuma -s-uoosi.avem n=3 .saculeti

. de monede. 1nprimul saculet .se gasesc 6 .monedccu valoarea 3, in -aldoilea saculet -sengasesc 4 .monede eu valoarea 7, iarin uhimul saculet sunt 14 lIlonede cu valoarea 5.i ;Programul va afisa in fisierul.de Iesire (denumit suma . out) eele doua solutiiposibile de· .. plata astfel :

:unsigned V[NrMaxMonede], :M[NrMaxMonede], P[NrMaxMonede];'Unsi-gned 'n , .S, -Sum, Nr.sol;ofstream fout("suma.out");

void Ci t.d-re ()

{lleitesedate1e de intrare din £isierul suma.ini£stream fin ("suma.in");fin»n»S;

£or (int i=O; i<n; i++) fin»V[i»>M[i];fin. close () ; }

r .Solutia nr. 1, ,

i ! 3 monede ell valoarea 3!~ 3 monede ell valoarea 7

14 monede eu valoarea 5r:I i Solutia nr. 2, ,I : 4 monede eu valoarea 3

4 monede eu valoarea 7~12 monede eu valoarea 5i it IReprezentarea informatiilor

n Vom retine intr-un vector v ell n eomponente valorile monedelor din eei n saculeti, iarj ! intr-un alt vector, M,vom retine multiplicitatile, adica numarul de monede din fiecare'- Jsaculet in parte.

Solutiile vor fi generate tntr-un vector P CU n componente, avand semnificatia : P [i] ­

'I numarul de monede din saculetul i folosite pentru plata sumei s. 'c i e {O. 1, ...• n-1} .I ,

I !e ditii i" on uu tnteme

r-: 1. P[i] e{O, 1, '.', M[i]}, \fie{O. 1, .... , n-l}

saculetul k 1a valoareamemorata in Sum *1

/Iapel reeursiv

'Void Afisare ()

{I/afisez 0 solutie in fisierulde .Le s Lrefout« "Solutia nr. "«++NrSol«endl;for (int i=O; i<n; i++)

if (P[iJ)

fout«P-[i)«" monede cu valoarea "«V[i]«endl;}

void Plata (int k)

{/* cand apelam Plata(k) am seleetat deja monede dinsaculetii O,l, ... ,k-l *1

if (k==n) Ilam seleetat· monede de toate tipurileif (Sum==S) /Ivaloarea monedelor selectate e egala eu S

Afisare () ;else;

else //mai seleetam monede din saculetii k,k+1, ... ,n-lfor (int j=O; j<=M[k] && Sum+j*V[kJ<='S; j++)

(P[kJ=j; Iiselectez j monede din saeuletul kSum+=j *V [k] ;

/*adaug valoarea monedelor seleetate dintotala a monedelor seleetate

Plata (k+l) ;Sum-=j * V[k];}

/Irestaurez dupa apel valoarea'variabilei globale Sum

(Din saculetul i se pot folosi eel mult M [ i J monede.)

P [01 'V [01 +P [1 J -v r i J +...+P [n-lJ 'V[n-lJ-S

(Valoarea totala a monedelor selectate trebuie sa fie egala eu suma s.)

2.r-t

!1_..;

Pentru a genera solutiile vom utiliza 0 functie recursiva P1a ta () .: Cand apelami' functia Plata (k) , am stabilit numarul de monede din saculetii 0, 1, 2, ... , k-1. Pentru· ;a completa solutia, ocupam mai intAi pozitia k din vectorul P §i apoi apelam recursiv

J functia p 1a t a ( k+ 1) . Pe pozitia k poate fi plasat orice numar natural care reprezintanumarul de monede selectate din saculetul k (deci acest numar trebuie sa fie mai mic saur; egal cu M [kJ si, in plus, valoarea totala a monedelor selectate Sa nu depaseasca s).

int main ()(Citire ();Plata(O);

fout.elose()i return O;}

':,'

/-

Simulare bacalaureat, 2001

Generarea sirului

-'

)I

I'til'iml- ' I

M- ,

'["',:",;(('j ~i'~II~;~ 1I!I:!: !{;t+''-1'r;":,i''i('"(h{r j

Jj:", :A"i "'I'i~

iW,''fiJ'.,(( ,'1,Ii: i

i;[i Jit!';.;., r ~

, ,,: :

,) ~

85

..am £ixat in s~r k ~alori

Iisirul este complet

'Vo.id cen (i.nt k)Ilcand,..a.pelam Gen (k),

{ ;'£. (k~-.lg)

Afisare 0;,e.l-se

{i'f (s[k-l]>l)(s[kJ=s[k-lj-1;Gen(k+l); }

s[kj-s[k-1]+1;Gen(k+l);

)

oint main ()

METODABACKmACKlNG

Pozitie

void Afisare ()lint i;if (s[lg-lJ==n)

{nrsol++;

for (i=O; i<lg; i++) fout«s[i)«' ';fout«endl; }

couc-c-cv-, , 19="; cin»n»lg;s[O)=n;Gen(l);

if (!nrsol) fout«"Nu exista solutii\n";fout.close();return 0;

Observam Ca algoritmul precedent genereaza siruri care nu se termina obligatoriu cun, iar noi testam aceasta cortditie abia Ia final. Daca valoarea s lk l va creste/scadea preamulto nu mai exista sanse ca pe ultima pozitie in vector sa obtinem valoarea n, orieumam genera valorile s[k+l], s[k+2], ...• s[lg-IJ.

Pentru a determina cea mai mica vaIoare care poate fi plasata pe pozijia k, presupunemca de la pozitia k+ 1 pana la pozipa 19-1 valorile vor fi in ordine strict crescatoare,

Valoare minima I j? I I ~_..., i I

Observam ca suma dintre valoarea minima §i pozipe este constanta (n+lg-l).Deducem astfel ca cea mai mica valoare care poate fi plasatii pe pozitia k este n-lg+1 +k(cu conditia ca n-lg+l+k>O).

r"I!

PROGRAMAREA iN LlMBAJUL-C/C++·::FENTRU LICEU

#include <fstream.h>#define NMax 11

int s [NMax] ;int n, 19;l.ong nrsol;ofstream fout("sir.out 1' ) ;

void Afisare () ;

84

'j:

!~

"

\l[';l

r~

Observati ca '.si in .acestprogram ;am,;utilizatJtehnica·:¥.3.riabilei,~lobale:l'entru..a:nu

calcula da necare -pasvaloareatotala .a snonedelor-dejaaelectate• .am~:tinut aceastawaloare fn variabila-globala Bum. De.fiecaredata cand'Selectam.monede.:tlintr-un-saculet..adaugam valoarea .Ior la Sum, .apoi .apelam recursivfunctia ~Plata. .care-selecteaza Incontinuare .monede-dinceilald saculeti pentru -plata'Sumei. :Candrevenimdin apelul-recursiv, nrebuie .sa.restauram valoarea-variabilei globale Sum -(deci trebuiesa.scadem.dinSum valoareamonedelor .selectate .Ia pasul precedent .din -saculetul k,:pentru .a -putea.adauga .ulterior, -daca-estecazul, valoarea .corespunzatoare tmonedelor -selectate..dinsaculetul k la pasul .urmator).

Observati, -deasemenea, caam.optimizatprogramul : -daca la-unmoment dat valoarea-monedelordeja.selectate depaseste suma s caretrebuieplatita, -nu continuamgenerarea,

Se citesc de la tastatura numerele naturale n §i 19 (o-cn, 19.::ao). Sa se afiseze -toatesirurile de 19 numere strict pozitive, siruri cu proprietatea ca .incep §i .se termina cu n ,iar intre doua elemente consecutive ale sirului diferenta este exact 1. Dad fiU existanicio solutie, se va afisa un mesaj. De exemplu, pentru n=2 §i 19=5.-se vor.afisa solutiile (nuneaparat in accasta ordine) :

23432;23232;23212;21232;21212

Soliqie

Vom construi soludile Intr-un vector s ell 19 eomponente. in functia main () vominitializa prima componenta a vectorului eu n {s [0 J»n), pentru a ne asigura ca strultncepe eu n,

Pentru a construi toate sirurile care incep eu n §i respecta proprietatile din enunt vom.utiliza 0 functie recursiva Gen (). Cand apelam functia Gen (k), pozitiile 0, 1, ...• k-1din vectorul s sunt deja ocupate §i trebuie sa plasam elemente pe pozitiile k , k+1 .....19-1. Vom oeupa mai intai. pozitia k , apoi vom apela reeursiv functia de generare pentrua construi sirul in continuare (Gen (k+1»).

Pentru a ne asigura ca diferenta dintre oricare doua elemente consecutive din §ir esteexact 1, pe pozitia k pot fi plasate eel mult doua valori: s[k-1]-1 (doar dacas [k -1 l.>1, pentru ca in sir pot fi plasate valori strict pozitive) sau s (k-1 ] +1 .

Atunci cand vectorul s este complet, vom afisa solutia objinuta, testand in prealabilca. pe ultima pozitie in vector se afla valoarea n (s [lg-l] ==n).

-'

--,/

! '

~

! !Generarede numere

87

x cifra i

//numarul este complet

METODA RACKTRACKING

i++)

//cifra i apare in n?I/adaug la sfarsitul .lui/Igenerez in continuareIisterg cifra adaugata

do

(c[x%lOl=l;x/-lO; I

whi1.e (x.);

void Gen (int k)

Ilcand apelam Gen(k), am fixat in numar k cifrefint iiif (k-~lg)

fout«x«endl;,e1.se

-for C'i=O; i<10;

if (c[i])(x=x*10+i;Gen'(k+l) ;x/=10;}

ccu t c-cv n , 19="; cin»n»lg;Determina_Cifre(n);Gen(O);

fout.close() ;zeturn 0;

::int c[lO];.:int n , .lg;

~ns~qned ~ong X;ofstream fout ("sir.out");void Determina_Cifre(int);

void Deterrnina_Cifre(int x)

,int main ()

sfiir§itul 'DumaruIuix, -pe rand, .:fiecare «lintre cifrele numanuui .n, apoi vom epelam-recursiv-Gen (k+ 1) penrru :a..coinpletanumarul-solupe.

~include <fstream.h>

Exercitiu

Modificati programul precedent astfel incat sa genereze toate numerele formate din 19cifre ale numarului n care au cifrele in ordine crescatoare, De exemplu, pentru n=216 §i19=2, se vor afisa numerele: 11,12,16,22,26. 66.

1I

Bacalaureat special, 2001

am fixatin numar k cifre//numaruleste complet

''PROGRAMAREA~iN L1MBAJUL ,C/C++,PENTRULICEU

{~f (s[k-!]>l && s[k-l]-l>=n-lg+l+k)(s[k]~s[k-ll-l;

Gen(k+l); }

if (s[k-!]+l<=n+lg-!-k)(s[k]~s{k-l]+l;

Gen(k+l);}

PozitieValoare maxima

·&6

r--r

,- j

,

" Observamca suma .dintre valoarea maxima.:§i .pozitie este constanra (n+lg-J.).i .Deducem ca valoarea maxima care poate fi-plasata pe pozitia k este n+lg-_l-k~I Functia de -:generare optimizata este : .

voi.d Gen (int k)//cand apelam Gen(k),( if (k~~lg)

Afisare();.e.Lee

L •!'.

n

.' 'Pentru .a-determina .cea -mai mare -valoarecare poate -fl plasata'pe rpozitia k,presu­''Punemd. -de Ja 'pozitia k+1 l'iinli Ja -pozitia 19-1. valorile worfi in 'online strict«lescrescatoare ::

"

r-"i Se citesc de la tastatura numerele naturale n §i k (0<n<10000 si 0<lg<10). reprezentate; ,! in baza 10. Sa se afiseze in ordine crescatoare toate numerele naturale de 19 eifre eul.,1 proprietatea ca sunt formate numai cu eifre ale numarului n .

De exemplu, pentru n=216 §i 19=2, se vor afisa numerele: 11, 12, 16, 21, 22, 26,n 61, 62, 66.

n~

n~.. ~-Exercitiu

n:Modificati programul precedent astfel tncat sa genereze toate sirurile de lungime 19.'.j' care incep eu n §i se termina eu n, diferenta dintre oricare doua valori consecutive fiind

eel mult D.

" SolutieI ! ,I ,

i" j in primul rand, vern consrrui veetorul earaeteristie al multimli eifrelor numarului n.Soluriile vor fi generate in variabila x , de tip unsigned long (pentru ea numarul de

r-'! eifre este mai mie dedit 10. Pentru a genera toate solutiile vom utiliza functia recursivai Gen () . Cand apelam Gen (k), in numarul x au fost adaugate k eifre; .adaugam lal j

!

r

1'--1: i,~

89METODA BACKTRACKiNG

'Void Ci tire ()

{ifstream f("comis.in");.i.nt L, j;

float d;f»n;

:while (! f .eof ()

/* de pe fiecare linie citesc daua crase intre care existalegatura directa, precum si distanta dintre ele */

ff»i»j»d;A[i] [j]~A[j] [iJ~d;

f.close (); }

float Infinite) //intoarce un numar sUficient de mare{float 5=0;

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

for (int j=l; j<=n; j++) S+=A[iJ [jJ;return 5+1;

voi.d Afisare ()

{ if (LgMin==Inf) cou t c cvtcn exista solutii \n";else

(cOut«"Traseul cel mai scurt are lungimea ";cout« setprecision(10) « LgMin « endl;cout«"Traseul este ";

for (int i=1; i<=n; i++) cout«TMin[i]«', ';cout«TMin[l]«endl;

#include <iomanip.h>#include <fstream.h>~define NMaxOrase 20

£loat A [NMaxOrase] [NMaxOrase];int n;

int T[NMaxOraseJ, TMin[NMaxOraseJ, v[NMaxOrase];£loat Lg, LgMin, Inf;

Conditii interne

I. 'T[iJ E{l. 2 •...• 'n} \tiE{I. 2 •....• nj'(traseul conjine cele n erase).2. -r r i i -a (comis"voiajorulpleaca din orasul r),

.3. A[T[i)] [T[i+~J]=l. 'l7'iE{l. 2 •....• n-~}-(intre.doua erase -vizitate'succesiv-trebuie sa existe Iegarura directa)

4. "T[i]-;t:T[jJ,-'di-;t:j ;i. jE{-I, 2. "', 'n}-(comis-voiajorulnutrecedemaimulteori-prin .acelasi Or3§);

5. A [1] [T [n] ] ~l (trebuiesa existe Iegarura directli Intreora§ulde plecare ~i ultimul·ora~vizitat).

fiI

l/I!,

3

PROGRAMAREA iN I.:.IMBAJULC/C+ + PENTRU L1CEU

1

5Pentru acest exemplu, programulva .afisa :Traseul eel mai scurt are lungimea 815.00Traseul.este 1, 3, 4, 2, 5, 1

Reprezentarea informatiilor

Vom reprezenta harta regiunii printr-o matrice patranca A. eu nxn componente, avandsemnificatia cit A [ i] [j] are valoarea 0 daca irure orasele i ~i j nu exista legaturadireetii, respeetiv valoarea distantei dintre orasele L si j, daca .existii. legaturli directii.

Traseul, mai exact ordinea in care comis-voiajorul vizireeza cele n erase, it vomreline Intr-un vector T, en n componente.

Pentru a nu trece de mai multe on prin acelasi eras, vom mai utiliza un vector v ; cun eomponente, in care pentru fiecare oras vom reline daca a fost sau nu vizitat: v [i I =1,daca orasul i a fost vizitat, §i o , in caz contrar.

Cand obtinem un traseu-solutie, nu it afisam, ci it eomparlim cu traseul de lungimeminima obtinut pana la momentul respectiv. Prin urmare, vom utiliza TMin. un vector elin componente, in care retinem un traseu de lungime minima. §i 0 variabila globalaLgMin, unde retinem lungimea acestui traseu.

Pentru a optimiza functia de generare a traseelor vom utiliza 0 variabila globala Lq ,

in care retinem lungimea traseului curent. Astfel, nu va mai fi nevoie sa calculam lafiecare pas lungimea traseului eurent: cand ne deplasam in alt oras, adunam distanjapana la orasul respectiv la Lg. Cand eliminam un oras de pe traseu, scadem distanja panala acesta din Lg. Daca la un moment dat Lg>LgMin. nu mai continuam generarea acestuitraseu, deoarece lungimea lui a depasit deja lungimea celui mai scurt traseu nbtinut panala momentul respectiv.

Comis-voiajor

Un comis-voiajor-plecadin,oIa§ul.in,care Iocuieste {sa-l notam 1) .sa-prezinto produseleunei firme .intoate .cele .norasedin .regiunea -:sa.:Elarela dispozitie :harta regiunii, 'Pecare .sunt -marcate .legaturile -directe.dintre-orase .§i distantele .dintre.acestea. .Scrieriunprogram care 'sa .determine un .traseucat mai .scurt, astfel fncet.comis-voiajorul zitviziteze toate orasele.dinregtune.: sa nu treaca de mai multe ori prinacelasioras.si sase-mroarca in orasul In care, locuieste.

De exemplu,sa presupunem ca ,e:rlStiin=5 erase, numerotate deila 1 ta s ..sapresupunem ca harta regiunii indica urmatoarele .legaturi directe :

2_f

125

88

, 1

UMedii

Se stie ca media la 0 materie unde se dii teza se calculeaza dupa formula urmatoare, under Nt reprezinta nota la teza, iar Mn media notelor la oral. Se §tie. de asemenea, ca un elevL_~poate avea la oral minimum 3 §i maximum 10 note.

. Nt+3xMnmedda ,c.:..:..:...:..:...=

r 4!LJ Cerintd

~ In aceste conditii, daca doi elevi au aceeasi medie ~i aceeasi nota la teza, sa se determineI '; toate combmatiile distincte de note pe care Ie pot avea acestia.\;

Date de intrarer; Fisierul de intrare medii. in coniine pe prima linie, separate printr-un spatiu, media ~i

l ,nota la teza.

'91:METODA &CK1'RACKlNG

'medii.in :medii 4out Comentarii5.625 3 4_' • Bxista mai multe combinajli de note

2 3 4 7 7 9 10 10 care furnizeaza aceeasi medie, doua.. . dintre acestea flind cele indicate .5 6 6-9 Mn~(5+6+6+9)/4=26/4=6.50

... Media_calculatil = (3+3*6.50) /4=

22.50/4~5.625

Date de iesire

Exemplu

Se genereaza in vectorul n toate combinatiile de minimum trei ~i maximum zece note.Dupa fieeare nota adaugata se calculeaza media si, in cazul in care aceasta coincide cumedia datil, se afiseaza solutia.

Olimpiada Municipala de Informatica, Iasi, 2003

Conditii interne

1. n [i] e{l, 2, ... , 10}, V'ie{l. 2 •...• 10};

2. n{O]=1;3. n[i]=n[i+ll. V'ie{O. 1 •...• 9}.

SOIUJie

fDaca,existii'solupe. fi§ieruI.de Iesire medd.L; outcontinepefiecare Iinie cate o combinatiede note. .acestea-fiind separate .prin. cateun'spapu.nacii nu exista solutie, in fisierul deiesire se va scrie mesajul NU.

Restrtqii

.. ~::;;Nt~10_;

• l~media::;;l 0 ;.• Media se da in fislerulde .intrare cu .trei zecimale exacte,

Avand in vedere ca se cer toate combinatiile de note care furnizeaza aceeasi medie,rezulta ca problema se rezolva prin tehniea de programare Backtracking.

Reprezentarea informatiilor

Notele la oral care partlcipa Ia calcularea mediei se retin in ordine crescaroere intr-untablou n. Deoarece cea mai mica nota este nota 1 ~i notele se retin in ordine crescatoare,vom initializa prima valoare a aeestui tablou (n [ 0J) cu 1. urmand ca notele careparticipa efectiv la calcularea mediei sa fie retinute in continuare (n [1]. . ..• n [1 0J).

1I

//traseul £stecomplet/Ipoate ,reveni in orasul ~

//construiescin continuare traseul

i=2; i<=n; i++)/ /verific -dace -se poet e deplasa in orasul i

(A[i][T[k-1]] && !v[i])(T[kj~i; v[i]~l, Lg+~A[i] [T[k-1j],

~f (Lg<=LgMin) ConstrTraseu(k+l);v[i]~O; Lg-~A[i] [T[k-1]];)

'PROGRAMAREA-iN LIMBAJUL-C/C++ '"PENTRU LlCEU

if

.i.nt main ()

Ci tire () ;T[l]=v[l]=l; LgMin=Inf=Infinit();

ConstrTraseu(2);Afisare ();

return 0;

vo~d 'ConstrTraseu(int k)l*cand .ape.Lam -constrTraseU (k) -r 'sunt:fixate 'petraseu or-ase.Le

'T[1], 'T[2],~~-, "T[k-ll '*/{ if (k-l==n)

if (A [~l [T [n] ] )

if (Lg+A[l] {"T[n]]<LgMin}{ flam obtinut ~n traseu nai' scurt

':for (int i=1; i-<=n; i++) "TMin[i]=T[i];

LgMin~Lg+A[1] [T [n] ]; }

ce1se;

;Ell.se;

el.se

for (i.nt

nU

r!t ....;

i

I<JO

rl i

nI i,, ,

rL~

rt...i

nL,~

r-1

Lj

r 1u

93<MErODA1l,4CKTRACKING

-smed.La , .,&nt);

I lnuam gasit -ni.cL a .s o.Lut Le n [0]=1

I lea .s a v p Lec de La nota 1

Ilpune noteleineepand ·eu primal1NU\nn);

...·-%f %f",

ealeuleaza (1) ;

:if (!GASTT) .:fprintf(g,fe!ose(f); fe!ose(g);

£seanf(£,GASIT=O;

Reprezentarea informatiilor

Vom reprezenta un joe dedomino -retinand intr-un vector J valorile Jnscrise pe fiecarepiesa din joe.

o solujie va fi reprezemata Intr-un vector L, in care retinem in ordine indicii pieselordill joe ee tormeaza un Iant,

Solatia optima (eel mai lung Ian! care se poate construi eu piese din joe) 0 vom retineIntr-un vector LMax. in care vom memora, in ordine, indicii pieselor care constiruie uneel mai lung Iant. Cand obtinem in L 0 solutie maximala (care nu mai poate fi manta. unIant la care uu mai putem "lipi" nici 0 piesa), 0 vom compara cu lantul eel mai lungobtinut paM .la rnomentul respectiv si, daca Iantul din L este mai lung, Il vom rerine inLMax.

Deoarece in Ian; nu putem utiliza aceeasi piesa de mai multe oric vom utiliza unvector ue, ell n eomponente (uz [i] =1 daca piesa ell indicele i a fost folositii in IanjulL §i 0, in caz contrar).

.return 0;

Conditii interne

1. L [i) E {1, 2•... , n}, 'ifi E {1, 2, ... , n} (lantul este format din indict ai pieselor dinjoe).

2. L[i)*L[j), 'ifi'¢:j; i, jE{1,2 •...• n}(nusepoatefolosiopiesademaimulteori).

3. J['L[iJ) .ultim=J[L[i+1J] .prim, \fie{l. 2, ...• n-l} (pentru oricare douapiese consecutive pe Ian], a doua valoare inscrisa pe prima dintre piese coincide cu .cea de a doua valoare tnscrisa pe piesa urmatoare).

Sa.seafi§eze eel mai lung lant ce se poateconstruidin cele n piese. ale unui joe dedomino, '§tiind ca fiecare piesa .are Jnscrise in ordine doua numere din multimea {I, 2.3, 4•.5. 6}, jar .douapiese se pot plasa pe Ian; In-pozitii consecutive daca §i nwnai dacaprimuI numar lnscris pe cea de a doua piesa coincide cu eel de.al doilea numar inscrispeprima pjesa.

De exemplu.rpenrru n=6piese, care au inserisenumerele 4 2,1 2.4 4,1 3.2 5,6 5, programul va .afisa :

Cel mai lung lant este format din piesele 3 1 2 4

Domino

//suma notelor/ /media notelor//media calculata

Ilam gasit solutie

n[i]);

afiseaza (k) ;caleuleaza(k+l);n[k]=O;

n[k]=i; //pun nota i

if (media calculata(k)==media)//daca media corespunde

//afiseazaI/treci 1a nota urmatoareIIanu1eaza ultima nota

i.nt main ()f=fopen ("medii. in", "r");g=fopen("medii.out", "w+");

return me;

}

-return 0;

'PROGRAMAREAiN UMBAJUL C/C++PENTRU LlCEU

£~oat media_calculata(int k)

int i;fl.oat s , ron, mc;if (k>2) flare rost sa calculez daar daca am minimum 3 note

{ s~O;

£or (i=l; i<=k; i++) s+=n[i];

mn=s/k;mc=(nt+3.0*mn)/4.0;

void;afiseaza(int k)

int i.;£or (i=l.i<-k; i++)

fprintf(g, V%d V,fprintf (g, "\n");

GASIT=l;

*inc!ude ~<stdio~h>

. -FILE .,*£, '*.g;

:£~oatmedia, :nt;.:i.ntn [12], ;GASIT;

- )l void ca.LcuLeaaa (int k)

i {int i;~. if (k<11) / /daca nu am pus toate no t.e Le (maximum 10 a LcL)

\ {I '0< ,.-",.-", '.-'0' ,••,;;,"" ••,•• "••••• ,••"".

IIi

I,Iii

92

l'ROGRAMAREA -iN UMBAJULCIC++ l'ENTRU nCEU

~include <fstream.h>~define .NrMaxDomino 100

'95METODA:BACKTRACKING.

L [1 ]=i; 'Uz'[i];=l;

ConstrLant (2) ;

Uz [iJ=O; }

Afi"sare () ';

xeturnO.

Scam

Restrictii oi precizdri

Date de intrare

Scneti un program care sa determine efortul minim necesar pentru a urea pe 0 scaraconstruita conform restrictiilorproblemei, precum §i 0 modalitate de a construi seara ceva fi urcata cu efort minim.

cerinta

Ion '§i-a .construit '0 vilape .frumosul varf'al ..unui munte. Aeum prolecreaza oscaraspeciala, pe.care vaurcade .la.sosea-pana.la vila. Diferenta.de nivel dintre sosea §i vilaeste H (deciaceasta trebuie sa fie lnaItimea.totala a scarii), Scara va:avea N trepte, toatede aceeasi Jalime"dar de iniil\imi distincte dona cate dona.

Ion.a sesizat ca efortul pe care il depune pentru.a urea 0 treapta este egal cu inaItimeatreptei. Dar daca el urea .x 'trepte .deodata, .eforrul depus este egal cumedia -arirmetica ainaItimilor .acestor x trepte pe care Ie urea deodata plus un efort de valoare constanta p

(necesar pentru a-sf Jua avant).Fiiudun tip atletic, Ion poate urea mai mnlte trepte deodata, dar suma lnii1limilor

treptelor urcate deodata nu trebuie sa depaseasca 0 valoare maxima M. .

Flsierul de Iesire scara. out va contine :- pe prima linie efortul minim. necesar (cu doua zecimale cu rotunjire);- pecea de a doua linie N numere naturale nenule, care reprezinta inaItimile celor N

trepte ale scarii (in ordinea de la sosea catre vila), separate prin care un spatiu,

Date de iesire

Fisierul de intrare s cer a . in va contine pe prima linie patru numere naturale separateprin cate un spatiu, H N M P (cu semnificatiile din enunt).

• O<H::::;;75

• O<N::::;;a• O<M<14• O:$p::::;;10• Pentru datele de test, problema are intotdeauna solutie.• Daca exisra mai multe solutii (rnodalitati de a construi seara astfel Incat sa obtineti

efortul minim dorit), yeti afisa prima solutie in ordine Iexicograflca.

1

lipeste"

/fintoarce piesa

LMax[i]=L[i];}

I/nu am mai utilizat piesa i

JIL[k-l» .ulUm)

de domino//incerc sa prelungesc lantul

Ilam obtinut 0 solutie maximala

Ileompar lantul eurent eu eel maxim

(J[il.ultim

Iint aux=J[i] .prim;Jlil .prim=J[i) .ultim; J[iJ .ultim=aux;}

(J[il.prim == J[L[k-11) .ultim){ Ilpiesa i "se

L[k)=i; Uz[i]=1; Se_poate=1;

ConstrLant(k+1);Uz[il~O; }

.if

}

( !Se_Poate)if (k-1 > LgMax)

{LgMax=k-1;for (i=1; i<=LgMax; i++)

if

void ConstrLant(int k)//lantul contine k-l piese

lint Se_Poate=O;£or (int i=1; i<=n; i++)

if (!Uz[i])

(i.f

void Afisare (){cout«"Cel mai lung .lanteste format din piesele ";

-for (int i=1; i<=LgMax; i++)

cQut«LMax [i] «' ';}

i.nt main ()Ci tire () ;for (int i=1; i<=n; i++)

{ Ilpot Lncepe lantul eu oriee piesa

"Void Citire (){ifstream fin ("domino.in''');

£in»n;:for (int i=l; i<=n; i++) fin»J[i] .prim»J[i] .ultim;

fin. close (); }

3truCt piesa { int prim, ultim; } J[NrMaxDomino];/Ipentru .:fiecarepiesa retin -ce.Le doua -numer e inscrise

:intn, "LgMax;..:i.ntL(NrMaxDomino] ,LMax [NrMaxDomino], .uz [NrMaxDomino];

!LJ

n

r'

'l i

rl J

"Il ,

"l !

D

nlJ

~

94

,....,,:l..,

r-t

l j

nI ,

u

r"lI••

L _J

rLJ

Ii

Deducem din acest rationament ca efortul minim necesar pentru a urea treptele 1-, 2•... ,i se calculeaza astfel :

'. Spunem .cavectoml X=(Xl'X2• -_~~ • .:xk) -preceda dn .ordine-Jexicografica wectorul~y=(yl' Y2' _ •• , Yk)-daca :existlii;;:::l .:astfellncat Xj=,Yp::pentru orice j <i§i".xi<}\_

.. Daca a.doua zecimala.a .efortului minim:este 0 -sau.chiar.ambele zecimale.sunt 0.,mu.este nccesar sa Ie~ti. Deci, in e:xemplu s-ar fipututscrie efortul minim 9sau 9_. O.

,-1

I'~

97METODA 'BACKTRACKING

void Ci tire ()

(ifstream fin(InFile);

fin»H»N»M»p;

fin. close ();

}

.int main ()

{Citire ();

efmin=(doub~e)H*N+1;

Gen(1);

Afisare () ;

.return 0;

-void Ci tire () ;

"Void Gen (int) ;

'Void Afisare () ;

~oub~e efort ();

j:nt -s o.L [NMax], solmin[NMax], uz[HMaxl, htot;4oub1e ef[NMax1, efmin;

//ef[i]=efortUl minim eu care urc primele i trepte din sol:.i..nt N, H, p, M;

'fI:inelude -cf.s t.z-eemvh>

4inelude -<iomanip.h>

·'=II=define TnFile 'v.s caza , Lrr"itdefine OutFile "ts caz-acout;'..

~de£ine NMax 101~define :HMax 101

-e.f [i]=minfe:f [i-~ ]+501. [.1J.,

.:min{ef [j ]+J:l+ Ls o.l, [j+11+so1 [j+2] +.~ _.+sol [i) ) / (i-j l ,

j=i-2 ,i-'::3~_~ .daea. f-aoL~j+1.] +801 [j+2]+. 4 .+sol [i] ) :::M}

void Afisare (){i.nt i;

ofstream fout(OutFile);

fout«setprecision(2)«efmin«endl;

for (i=l; i<N; i++)

fout«solmin [i]«' ';

fout«solrnin[NJ«end1;

fout.close();}

Olimpiada Judeteana de Informatica, 2005

scara.out9.00

1 4 2 3

-PROGRAMAREA iN LIMBAIUL CfC++PENTRU LlCEU

scara.in104 5 2

Reprezentarea informatiilor

1. Vectorul in care generam solutiile :sol,CU n componente, cu-semniticatia disol {i1 este in3lpmea treptei i.

2. Solutia care necesita efort minim 0 vom retine ta vectorul solmin.3. Pentru a verifica daca toate inalPmile sunt distincte 'vom construi vectorul uz ell M

componentec vectorul caracteristic al inaltimilor (nn putem folosi inaItimi .mai -marldecat M): uz (il =1. daca inaltimea i a fost utilizata, ~i 0, in cazcontrar.

4. htot= surna inalPmilor treptelor pana la un moment dat.5. efmin = efortul consumat pentru solmin.

6. Pentru a caleula efortul minim necesar la fiecare pas vom utiliza un vector e f eu ncomponente, cu semnificatia ca e f [i ] reprezinta efortul minim necesar pentru a ureaprimele L trepte din solatia mcmorata in vectorul sol.

Condqii inteme

1. sol [i) e f a , 2, ...• M}, V ie{1, 2•..:' N};2. s o Ll d l *- 501[j). V i*-j L, je{1,2, ... , N};3. 501[1]+5[2)+ ... +501[N1=H.

Treptele 1. 2, ...• L se pot urea ell efort minim.astfel :

- urcam en efort minim treptele 1, 2 •...• L-1 §i apoi urcam separat treapta i (efortulneeesar In acest eaz este ef [i-1] +501 [i]);urcam en efort minim treptele 1. 2, ... , j , apoi urcam deodata treptele j + 1. j +2, ... ,d , daca este posibil, adica daca suma lnaltimilor aeestor trepte nu depaseste M(sol [j +11 +501 [j+2] + ... +501 l Ll )91); efortuldepus este ef [j J+p+ (501 [j +1] +

501[j+2]+ ... +50l[i])/{i-j). Treapta j poate fi aleasa In toate modurileposibile (j = i - 2, i - 3, ...), varianta convenabila fiind cea care minimizeaza efortuldepus.

Solutie

96

Exemplu

Fiaierul de intrare statie. in contine :

Date de intrare

Fisierul de iesire statie. out va contine :

,-,',:;j-':itIV,

"p,

':l

',j}.•

L!.il';;J

itit

f'

~!j',

r;,:i'o

'99·METODA JJACKTRACKING

Semnificatie

c - numarul de earnere dintr-un simulator;s - numarul de persoane ;Mi -. masa persoanei i.

Semnificafie

Cdez reprezinta eoeficientul de dezechilibrareininim alsimulatorului.

statie.in

c SM1 M2 ••• Ms

StoJie

unde'Me i este masa camerei i (calculata prin insumarea maselor persoanelordin camerarespectiva), iar MA -este .masa medie .a .camerelor (calculata prininsumarea maselortuturor persoanelor .din camere §i .impartirea sumei Ja numarul de eamere). La unexperiment de simulare participa s .persoanev numerotate de Ja 1 la s.

inlaboratoareleunei statiispatiale.existaun simulator centrifugal care coniine C camere,-numerotatede Ja lla c.1ntr-o camcrapot Incapea 0, 1 .sau 2 persoane. Coefieientul de~dezechilibrare ,a .unui .simulator -se calculeaza .astfel :,

cdez~i:lMc,-MAI,.,

Scrieti un program care .sa determine coeficientul dedezechilibrare minim ce se poateobtine prin repartizarea eelor s persoane in eamerele simuIatorului.

Cerinpi

statie.out

Cdez

Date de iesire

Restriqii

• 1 :::;; c ::;: 5• 1 :::;; S s 2C• 1 ;5; Mi :::;; 1000, i=l, 2, ... , S-e Coeficientul de dezechilibrare Cdez va fi afisat eu trei zecimale.

~

}

ef[k]=x;}

xeturn ef [N] ;

/* care ar £1 e£ortul minim daca as puneinaltimea treptei k=i? */sol{k]=i: htot+=i: uz[i]=l;Gen(k+l):uz[i]=O; htot--i;

'PROGRAMAREA'~LIMBAJUL C/C++-"PENTRULICEU

void Gen (int k)

{int i;

doub1.e Xi

if (k==N+l)

{

if (htot==H)

(x-efort();if (x<efmin && efmin-x>O.OOl)

{e£min=x;~or (i=l; i<=N; i++) solmin[i]=sol[i];

.el.se

£or (i=l; i<=H && htot+i<=H && i<=M; i++)if (!uz[i])

{

<ioub1.e efort (){int k, j;

doub1.e X, __sum;

-£or (k=l; k<=N; ·,k++)

{xes o.L [kl'+ef[k--l]:

/-1< ure -cu ve f oz-t; -mt.ndm -prdme.Ie k-J. -t r-ep t e 51 apei ure

treaptak -de Li.rie.Lt.zime i "* /sum-sol [kl;

':for (j=2; k-j>-O; j++)

{/* aiz-c vdeoda t.a -j trepte k, k-.l, ••. ,k-j+l, .dacesurna inaltimilor~or este '<-M;in sum calculez .s uma inal timilor* /

sum+=sol[k-j+l];if (sum>M) break;if (sum/j+p+ef[k-j]<x)

x=sum/j+ef (k-j ]-+p:

i~

,!

98

;:

~, ,,,,

n

,....,I

,....,, ,

f""

l,....I

~,

,....I,

i",!,, ,

,....,Il J

#include <stdio.h>#define Infinit 99999

SoliqieDeoarece se cere determinarea unei repartizari optime a celor s _persoane in camere §ipentru ca dimensiunile datelor nu sunt mari, vom apIiea 0 metoda de tip Backtracking.tncercand sa repartizam persoanele in camerele care maiau locuri disponibile. 0 camera:este caracterizata prin numarul de persoane repartizate la un moment dat in acea camera§i de greutatile persoanelor respective. in momentul in care toate cele s persoane au fostrepartizate in camere, se calculeaza coeficientul de dezechilibrare a stajiei si, in cazul incare a fost determinat un coeficient mai bun, i1retinem,

i, ,....

101

Ilcalculam coef de dezechilihru

Iidaca e mai bunII il retinem

/Iinitializeaza eu 0 toate camerele

Iln~marul de persoaneIlpersoana 1Ilpersoana 2

Iidaca le-am repartizat pe toate

i++) Ilgreutatile persoanelor

", &(pers[i]»;lise calculeaza si suma greutatilor

temp=calc_Cdez();if (temp<best_Cdez)

best_Cdez=temp;

£or (i=O; i<nr_pers;{fscanf(inp, It%dmedie+=pers[i];

}

fclose (inp) ;

'METODA BACKTRACKING

~ong -ca1c_Cdez (voi.d) ·llcalcul-eaza coef. del-deae chd.Lf.bru{~ong Cdez=O;:.:int i,j;

':for (i=O; i-<nr.....:cam; i++)·Cdez+=abs ( (nr_cam~-(cam (i-] .cpe.rs [O]+cam[i] •pers (1] ) ) -medd e) ;::return (Cdez) ;

voi.d calcul(int k)~ong temp;--oint i,j;if (k==nr_pers)

'Void ci tire (void)( ~nt i;

FILE *inp=fopen("statie.in","r");fscanf(inp, It%d %d", &nr_cam, &nr_pers);medie ~ 0;

~or (i=O; i<S; i++)

{ cam[i] .nr=O;cam[i]~pers[O]=O;

cam [i J. pers [1] =0;

.campion, 2004

Bxplicaiieo .solutie .este : persoanele 1 -,'.§i 8suntplasate in camera 1 ;l'ersoa­Dele 2 :§i7 sunt -plasate .tn -camera2; persoanele 3 si 6 sunt plasate incamera ,3 ;persoanele 4 ~§i 5 sootplasate in camera 4; persoana 9este plasata in camera 5.Coeficientul dedezechilibrare este11. 600.

s t.at.Levout;

11.600

Explicatieo .solutie .este : .persoanele 1 :~i :2 ,..unt :plasateincamera 1:.;. rpersoana 3este -plasata mcamera"2.

Coeficientul .de.dezechilibrare .este '1. 000.

;PROGRAMAREA-iNLIMBAJUL C/C++ :PENTRU LlCEU

'at.a t.Lec-out;

1.000

5 91 2 3 5 7 11 13 17 19

Exemplul2.s t.at.Lec Ln

statie.in

.2 363 8

100

Exemplul.T

~ong pers[10];camera cam[S], best_cam[S];

or_cam, nr_pers;best_Cdez~Infinit,

abs (J.ong x)

(x<O) return -x;

carn[j] .pers[cam[j}.nr]=pers[k] ;llpun .pe r s . k aici

cam[j).nr++; Iinurnar inca 0 persoanacalcul(k+1); Iitrec la persoana urmatoarecam[j) .nr--; Ilrevin, scad numarul de persoane

cam[j].pers[cam(jJ.nr]=O;llgreutatea 1a loc pe 0

typedefstruct{

~ong nr,pers[2];camera;

int~onq

~ong

{ if

Iistructura unei camere

Iinurnarul de persoaneIlcele (maximum) 2 persoane (greutatile)

medie;

-e.Lee

for (j=O; j<nr_cam;

if (cam[j] .nr<2){

Iinu i-am repartizat pe totij++)llparcurg toate camerele si

Iidaca in camera j mai e loc

; :W

~

return x;

Labirint

i£ (EFinal(x,y» Ilpozitia ~,y este un punet £inalPreluerare_$olutie();~~se //continuam cautarea~or (i=Oii<NrDireetiii i++)/ /ma deplasez -aucce s.Lv :pe .directiile posibile de cm.Ls caz-e±£ (Nevizitat(x+dx[i],y+dy[i]u)

/Inu .am maitreeut prin .a ceas t;e pozitieBkt_Plan(x+dx[i], y+dy[i])i

102r-' -, .: If";,l 1

r,,,

r::l ...•

PROGRAMAREA1N'LlMBAJUL ·C/C++:IFENTRU L'lCEU

lliVo:i:ci afi"sare(vo.id)

~"FJ:LE ..,Jrg-;

'g=fopen'C"-statie.out"'., '''w'n}-;

£printfc(g, '''%5~3f\n'', ('(£J.oat) {best-"::Cdez)J I ({:f~oat)nr_carn) };

tfc.Lcs e (g); )

..int main (vo.id)

citire ()i

calcul{O);.afisare () ;:return 0;

'METODA-:BACKTRACKING 103

i 3. Backtracking in 'Plan( j

Solutia nr. 2*111*111*1*01*1*

Solutia nr. 1*111*111

Prograntul va afi~a:

Reprezentarea informatiilor

Labirintul este reprezentat ca 0 matrice L cu nxm elemente. Elementele labirintului suntinitial 0 (semnificiind culoar) §i 1 (semnificiind perete). Pentru ca soricelul sa nu treecade mai multe ori prin aceeasi pozitie, existand riscul de a intra in bucla, vom marca inlabirint pozitiile prin care trece sorlcelul cu 2.

*1**1*1*

Intr-un labirint, reprezentat ca o matrice r, eu n linii .§i m coloane,cu eomponente 0 sau1 (1 semnificiind perete, 0 - culoar), se gaseste 0 bucatli de br1lnzli. pe pozitia (xb,yb) §iun soricel pe pozuia (xs .ys). Afi§ali toate posibilitatile soricelului de a ajunge la branza,stiind ca el se poate deplasa numai- pe culoar, iar directfile posibile de miscare sunt N,NE, E, SE, S, SV, V, NV.

De exemplu, pentru un labirint cu 4 linii §i 4. coloane de forma .urmatoare, in caresoricelul se gaseste pe pozitia (1,1), jar br1lnzape pozitia (4,4).

011 1o 1 1 1

o 1 0 01 0 1 0

IIexp10ram pozitia curenta

X, int y)coordonat~le pozitiei curente

Exp1orare(x,y);

void Bkt_P1an(intIlx, y reprezinta{

Invarianta elementara aplicam metoda Backtracking pentrurezolvarea problemelor inr; care solutia era reprezentata ca vector. Putemgeneraliza ideea cautarii ell revenire siI : pentru probleme in care cautarea se face .inplan". Pentrunoi, planul va fi reprezentat

! ca un tablou bidimensional._ Pentru a intui modul de functionare a metodei Backtracking in plan sa ne Imaginami ! explorarea unei pesteri. Speologul porneste de Ia intrarea inpestera §i trebuie sit explorezeII in mod sistematic toate culoarele pesterii. Ce tnseamna ..,inmod sistematic"? In primul

rand, i~i stabileste 0 ordine pentru toate directiile posibilede miscare (de exemplu, N,n NE, E, SE, S, SV, V, NV) §i Intotdeauna diad se gaseste Intr-un punct din care are malj : multe culoare de explorer, alege directiile de deplasare in ordinea prestabilita, In alL.; doilea rand, speologul va piasa marcaje pe culoarele pe care le-a explorat, pentru ca nu

cumva sa se rataceasca §i sa parcurga de mai multe ori acelasi culoar (ceea ce ar conducen la detenninarea eronata a lungimii pesterii).t! in .ce consta explorarea? Speologul exploreaza un culoar pana cand rntalnesre 0t_,

'intersectie sau pana cand culoarul se mfunda. Daca aajuns la 0 intersectie, exploreazasuccesiv toate culoarele care pornesc din intersectia respectiva, in ordinea prestabilita ar directiilor, Cand un culoar se tnfunda, revine Ia intersectia precedenta §i alege un alt

LJ culoar,de pe urmatoarea direcjie (daca exists ;daca nu exista, revine la intersectiaprecedentli s.a.m.d.).

F" Sa descriem intr-o forma mai generala aceasta metoda.I, Vorn nota prin NrDirectii 0 constanta care reprezinta numarul de direcjii del.-.J deplasare, iar dx, respectiv dy sunt doi vectori constanti ce reprezinta deplasarile

relative pe directiile ox, respectiv Oy, urmand in ordine cele NrDirectii defl deplasare.

::1fi,i ;

fi

Pentru a OU verifica permanent daca soricelul nu a ajuns cumva la marginea labi­rintului, bordam labirintul cuperete (doua linii §idouacoloane cu valoarea 1).

Pentru :a-determina pozitiile in -care -:sepoate .deplasa soricelul, -vom -utiliza .dolwectoriv nx [ 8] ::§i, Dy[8J • -:pe .care :ii4nitiaJ:izam. 'ell -deplasarile -pe linie, .respectiv pecoloana pentru toatecele opt .directii posibile de -mi~care.

Conditii interne

Din pozitia (x,y) soricelul sepoate deplasa pe directia dd x, deci in pozitia(x+Dx Ldd r l , y+Dy [dir]) daca si numai daca L [x+Dx [dirl ] {y-t-Dx(dirJ ] =0 (aceastapozitie reprezinta un culoar prin care soricelul nu a moo trecut).

.J! 1,\.t: I"1,: i

If:t~!:. 1rr, !i! I

l,]i~

Kjili;

~1)~

.105MEIDDA.BA.CKTRACKING

.:i.-f (L[i] [j]==2) -fout«,'*';~l:se· fout«L [i] [j] ;

-£out«end1; }

~o±dCauta(int x, .:i.nt y}

L[x] [y]=2; //marchezpozitiax, yi£ (x==xb && y==yb) Afisare();

.ej.ee

~or (int dir=O; dir<8; dir++)if (!L[x+Dx[dir]] [y+Dy[dir]]) //culoar nevizitat

Cauta(x+Dx[dir], y+Dy[dir]);L[xj[yj-O;1*1a intoarcere, sterg marcajul, pentru aputea exp10ra

aeest culoar si in alta varianta*/

int main ()Citire(j; Bordare();Cauta (xs, ys);if (!NrSol) fout«"Nu exista solutii! \n";fout.close ();:return 0;

Fotografie

Exercitiu

Executati programul pas cu pas §i urmariti valorile variabilelor globale §i locale.

Fctografia.alb-negru a unui obiect este reprezentata sub forma unei matriee eu n Iinii ~im coloane ale carei elemente sunt 0 sau 1. Elementele egale eu 1 reprezinta punctele eeapartin unui obiect. Doua elemente de valoare 1 fae parte din acelasi obiect daca suntadiaeente pe liniesau pe coloana, Se cere sa se determine numarul obiectelor dinfotografie,

De exemplu, pentru matricea eu 3 linii si 6 coloane:

f'"IV N :NE

L [x-1.] [y...,1.J :L[x"';~J [y] L[x":'J.] ,[y+l]

v E

.L [x] [y"';l] L[xl [y+l1

sv s "'S

L[x+1.] [y-l] L[x+l] [y] L[x+l] [y+l]

"PROGRAMAREAiN LIMBAJUL C/C+ +~ENTRU LlCEU

*include <fstream.h>~define DimMax 20int Dx[8J={-1,-1,O,1,1,1,O,-1};int Dy[B]={O,l, 1,1,O,-1,-1,-1};int L[DimMax] [DimMax];int n, m, xs, ys, xb, yb, NrSol;ofstream fout("1abirint.out");vo.id Ci tire (){ifstream f("labirint.in");f»n»m»xs»ys»xb»yb;for (.int i=1; i<=n; i++)

for (.int j=l; j<=m; j++) f»L[i] [j J;f. close () ; }

voi.d Bordare ()

104

I

//bordam labirintul eu cate un peretefor (i.nt i=O; i<=n+l; i++)//perete 1a stanga si 1a dreapta

L[ij [OJ-L[ij [m+1j-1;for (i=O; i<=m+l; i++) //perete sus si jos

L[O] [ij-L[n+1J [i)-l;vo.id Afisare (){fout«"Solutia nr. "«++NrSo1«endl;for (.int i=1; i<=n; i++)

{for (int j=1; j<=m; j++)

1 0 0 0 0 0o 1 0 0 1 10 1 0 o 1 0

programul va afisa :

Nr. obiecte=3

r:: : :SoluJiet. .:

Pentru .a .numara -obiectele din fotografie vom parcurge -matricea .care reprezmta :foto-r- ;grafia, .cautand -un .elemenr .cu valoarea :J., -deci .:care ,aparPne-llilui.obiect. :Vommumaxaj : 'noul .obiect-depistat, apoi vom ,.,;§tergcf·-obiectuldinfotografie, .cojorandu-l dn culoareaLJ.:de.fond (valoarea u 'in,matrice). Pentru.a.,."§terge"',ml.obiect-vom·folosi·funcp.aI'ecuriiva

Sterge obd.e ct; (x, y ).care an cazuI -ctnd punetulde .coordonate (xcy) -apartine',obiec­"tului (a[x] [y] -~), 'iI~terge (a [xl [y]~O), "Poi .se .apeleaza :reeursiv functia pentru'[ "teate punctele .adiacente cu (x ,:y).(pe Hnie-sau pe .coloana). . -

j Pentru.a nu 'testa.daca in timpul.cautarii amdepasit marginilefotografiei, -ambordat-matricea- -reprezentdnd fotografia eu care 0 -Iinie :§i o coloana sus. jos, .la "Stanga '§i .la

"dreapta, inipalizate eu valoarea 0 (am,;inrlimat" fotografia)., .

i.

l ; Observatie

,....,Acest tip de algoritm, prin care plecand -de .Iaun 'element sunt ..,.,:atinse" succesiv toate'i ieIementeIe care an 0 Iegatura (directa san indirecta) cu elementul -respectiv, poartal :numelede algoritm de fill (umplere).

l'refixul maximal obtinut va fi: elefa.

107METODA BACKTRACKING

eel mai lung prefix

int Dx[8]={-I,-1,0,1,1,1,0,-1};int Dy(8]=(0,1, 1,1,0,-1,-1,-1};char s[200];int Lg, LgMax, n, m;char C[DimMax] [DimMax];

Soliqie

Vom utiliza functia recursiva Cauta (x, vi . care verifica daca urmatoarea litera -dincuvant (indicata de variabiia global. Lg, ee retine lungimea prefixului eurent) se afia .saunu pe pozitia (x,y) in matricea C. jn caz afirmativ. am moo gasit 0 litera in rnatrice, decilungimea prefixuIui curent creste ~i contmuam cautarea in pozitiile adiacente pozniei(x,y). Altfel, am obtinut un prefix maximal ~i comparam lungimea lui eu lungimea celuimai lung prefix deterrninat l'linli la momentul enrent (LgMax).

Pentru a nu verifiea permanent daca prin deplasari succesive .nu am depasit Iungimeacuvantului sau limiteIe indicilor din matrice, vom borda matricea cu spajii §i vom marcasfarsitul cuvantului prin caracterul " . ".

De .aceasta data, nu trebuie sa marcam Iiterele din matrice pe care Ie-am utilizatpentru construirea prefixujui din doua motive:

- putem utiliza aceeasi litera de maimulteori ;- nu exista riscul de a apela recursiv functia Cauta.la infinit (san mai exact pana se

umple stiva), deoareee la fieeare apel marim Lg, lungimea prefixului eurent, ~i dupastrlen (s) pasi vom ajunge la ., ;", marcajul de sfar~it de cuvant,

Fie C0 matrice cu n Iiniisi m.coloane care .contine numai ·litere..Sasedetermine 'cef moolung prefix al unui cuvant -dats , ·care 'Sa :se gaseasca in matricea c, -astfel jncat oricaredoua litere -succesive .ale 'prefixului sase afle .in matrice .pe pozitii adiacenie .(pe Iinie,eoloana sau diagonala). Nu .se va :face.distinctie intre Iiterele mari C§i cele anici,

De exemplu, pentru cuvsnrul s- 'elefantel ':~i matricea:

eleanghan rttndeelienaeatt

#include <fstream.h>#include <ctype.h>#include <string.h>#define DimMax 30Ildimensiunea maxima a labirintului

PROGRAMAREA·'iN LlMBAJUL ''C/C+ + 'PENTRU LlCEU

int main ()Ci tire () ;for (int i=l; i<=n; i++)

for (int j=l; j<=m; j++)if (a[i] [j]) Ilam depistat un obiect

{NrObiecte++;sterge_Obiect(i, j);}

cout«"Nr. obiecte = " « NrObiecte « endl;return 0;

voi.d Cit ire ()(ifstream finC"foto.in");fin»n»m;for (int i=l; i<=n; i++)

for (int j=l; j<=m; j++) fin»a fi] [j];fin. close () ; }

void Sterge_Obiect (int x , .int y){ i.f (a [x] [yJ)

{ a l x l [y] =0; Ilsterg acest element de imagineIlcautarea continua in cele 4 directii posibile

for (int dir=O; dir<4'; dir++)Sterge_Obiect(x+Dx[dir], y+Dy(dir]);}

#include <fstream.h>'#define DimMax 50int Dx[4]={-I, 0, 1, OJ, Dy[4]={ 0, 1, O,':"l};int a [DimMax] [DimMax], m, n, NrObiecte;

'106

rIL

r;, 'LJ

!I ,

r:! ', ,

~,

Albina

Pe un gazon de forma dreptunghiulara au fest plantate pe fiecare dintre cele n randuricare m fire de flori de diferite specii. 0 albina, Incantata de coloritul si de mireasmaflorilor, va inccrca sa polenizeze cat mai muIte dintre acestea. Albina se afla initial infloarea cu numarul k din randul r lji la fiecare pas poate zbura din fIoarea in care se aflain una dintre cele patru flori vecine acesteia, situate pe cele patru directii N, E, S, V.Diversitatea tipurilor de flori face ea inflorescentele aeestora sa se afle la diferite inaItimi

fata de sol, fapt ce va tngreuna zborul albinei. Din acest motiv, pentru a-si conservaenergia, albina va putea zbura la fiecare pas cel mult hI unitAti in sus sau eel mult h2unitiiti in jos.

Date .de intrare

109

Concursul National de Soft ..Grigore Moisil", Lugoj, 2003

MEfODA£ACKTRACKING

albina.out6

Este 0 problema de Backtracking in plan, in care apar cateva elemente in plus: condi­tionarea deplasarii aIbinei in raport ell inaltimileflorilor ~i determinarea suprafeteidreptunghiulare de arie maxima.

Restrictii # preciziiri

Pisierul de iesire albina.out va contine pe prima linie unsingur numar natural,reprezentand aria celei maimari suprafete eu fIori polenizate de albina.

Exemplu

albina.in4 41 32 11 2 1 154 4 2 123 2 5 121 7 3 10

Soltqie

Fi§ieruLde,intrare albina .d.n -va contine :

pe prima linie,num.erele n .lji m,''Separnte'-printr-un:spatiu, -reprczentand dimensiunile.gazonului ;

- -pe linia a dona, numerele k lji r-, .separate prtntr-un spatiuv reprezentand pozitiainitiala aalbinei ;pe cea .de-a treia linie, -numerele h L lji h2 ,:separate printr-un spatiu, reprezentanddiferentele de nivel pe care Ie poateaborda 'albina ;

- pe fiecare dintre ur.m1itoarele n linii, cate m numere naturale separate prin .spatii,reprezentiind inliItimile fIorilor.

Date de iesire

CunoscAnd ini'iltimea fiecarui fir de 'floare, -determinati aria .celei maimari .suprafete<!reptuDghiulare en floripolenizate de .aIbinli.

cerinJii

·1::;n,m:5:30;·1::;hl,h2.:s::20;• inaItimea fiecarui fir de floare este un numar natural din intervaluI [1, 100].

int main ()Bordare (); Ci tire () ;£or (int i=.I; i<=n; i'++)

for (int j=1; j<=m; j++) Cauta(i,j);

s[LgMax]=NULL;eout«"Prefixul maximal este " « s;return O;}

'PROGRAMAREA IN LIMBAJULC/C++ PENTRU LlCEU

-void Bordare (){/ /bordez .matrrdcea cuspatii£or (int i=O; i<=n+1: i++) e[i] [Ol=C[il [m+l]=' 1;

~£or (i=O: i<=m+l; i++) e{o] [i]=C[Ol [n+11=' ';

void Cauta{int i, int j){/*verific daca elementul de pe linia i, coloana j coincide

ell litera de pe pozitia Lg din cuvant; -*/if (tolower(C[i] [j])==tolower(s(Lg]» flam gasit 0 litera

{ Lg++: /llungimea prefixului curent creste'for (int k=O: k<8; k++) Cauta{i+Dx[k], j+Dy[k]):Lg--; } / /restaurez lungimea prefixului curent

el.se / /prefixul este maximal

if (Lg>LgMax) LgMax=Lg;/*am eomparat lu~gimea prefixului curent eu lungimea maximaobtinuta pana aeum si, daea este eazul, a retin*/

voi-d Ci'ti're ().{i:fstream:fin ('''prefix_in...·);~£in_getli:ne(5, ,si:zeof (5»; "fin»n»m; :fin. get ();

~or (~nt i=l:i<=n:i++){.£or :,(int -j=!; j<=m; j++)

:£in.get (C [i] [j]);

-fLn .•get-() ; }

fin. close () ; }

108

rc

;'pl<lnr::.1<l AM ARP.AiNLlMBAJUL CIC++ -PENTRU LICEU

Reprezeniarea dnformatiilorr-: ilnforrnatiile edespre jDlUtimile 'florilor se-retintntr-nn tablou -a, Acesta oeste bordat cu o\ II valoare mai maredecat iMlpmeamaxima a florilor, -pentru.a nu permite Iesirea .inafaraL.J campufui in:timpuLprocesului de .•,;polenizare"~ lnplus. -sefoloseste un tablou auxiliar i ,

fn care.sunt -marcatecu valoarea 1.:florile ee au:fost polenizate.Acest tablou ·este folositn §i -pentru -determinarea aonei -dreptunghiulare de.arie anaxima 'caiecontine numai 'floriI.: polenizate.

Conditii interne

111--METODAtBACKTRACKING

void bordare(void){ :inti, j;

'£or{i=O; i<=n+:l'; i-H) '.:alil10)=aT-i,J (m+~]=MAX;

'£or(j=O; j<=m+.1; j++) -a l Oj [j]=a[n+1] [jJ=MAX;

return Max;

int aria (void)

void depune (int .i., ,int j)

::inti_nou, j~nou, :1.;'t Ld l [j]=l;

~or (1=0; 1<4; 1++)

{ i_nou=i+dx[lJ; j~nou=j+dy[11;

.;if (t[i~nou] [j_nou]==O)

{i£ «a [i] [j] >=a [i~nouJ [j_nouJ) &&

(a (i] [j j...,.a [i._nou] [j_nou] <=1_j) )depune(i_nou,j_nou);

.if «a [i) [j ]<a [i_nou] [j_nou) &&

.(a[i--.:nou] [j_nou)-a[i] [j)<=1_s»depune(i_nou,j_nou);

.int i, j, k, 1, iI, j1;

.int Max=O,p;

for (i=1; i<=n; i++)£or(j=l; j<=rn; j++)

.if(t[il [j) Ilpentru fiecare f10are po1enizata£or(k=i; k<=n; k++) IIco1t stanga-sus

£or(l=j; l<=m; 1++) lIse cauta

.if(t[k] [1]) 110 alta f10are po1enizata

{ IIco1t dreapta-josIlin dreptunghiu1 determinat de aceste doua flori se faceIlprodusul e1emente1or (1 - po1enizata sau 0 - nul

p=l:£or(i1=i; i1<=k; i1++)

£or(j1=j; j1<=1; j1++)p*~t[il] [jl];.

if(p) Ildaca toate au fast 1

Ilam determinat un dreptunghi p1inif«k-i+l)*(I-j+1»Max)

Max=(k-i+1)*(1-j+1);

I/retin maximul aflat pana aCUffi

... ,m} ;

#inc1ude <stdio.h>#define MAX 1000

int dx[4]={-1, '0, 1, oi •int dy[4]={0, 1, 0, -l};

int t[32) [32], a[32] [32], n, m, iJ'rim, j_prim, 1_5, 1_j;

void ci tire (void)

int i, j;

FILE *f=fopen("a1bina.in", "r");

fscanf (f, n%d %d", &n, &m);

fscanf (f, lI%d %d", &i_prim, &j_prim);

fscanf(f,"%d %d", &1_5, &1_j);

for(i=l; i<=n; i++)

for(j=l; j<=m; j++) fscanf(f, "%d", &a[i] [j]);fc1ose(f);

r, ,

l ;

i

I 1. a[i][j]E{1,2, •.. ,100};:: 2. t[i] [j] E{O,l},'lfiE{l, 2, ... , n}, 'lfj E{l, 2,

3. 1::;; n , m::;; 30 ;I' ·4. 1'; hi, h2 $20.

Ll In primaetapli .se determine toate florile care pot fi polenizate plecand de .la floareainiJialll. Printr-un algoritm de tip fill sunt marcate in tabloul t toate florile care pot fin polenizate.

i: in etapaa dona -se.determinazona dreptunghiulara de arie maxima care contine doar~. --' flori polenizate - adica avand in tabloul t .doar valori egale ell 1. Pentru aceasta ser- parcurge tabloul t §i se determina, pe rand, care un elementnenul. Acesta va fi coltul din1 : stanga-sus al zonei dreptunghiulare testate. Pastrand coltul constant, se determina, peL.J rand, toate elementele nenule din tablou aflate la dreapta (indice 'de coloana mai -mare)

§i mai jos (indice de linie mai mare) decat colml respectiv. Fiecare element nenul detectat~ va constitui coltul din dreapta-jos al unei zone dreptungbiulare. Se verificli daca aceasta1 : zona contine numai elemente egale cu I, facandu-se produsul tuturor elementelor dinLj zona, §i, in caz afirmativ, se compara cu aria maxima detectata paua in acel moment,

retinandu-se eventual noua arie.

nI I

I "

r:

nI ;l __ j

,....,, ,, ,, ,, Il_ .•

I'

De exemplu, sa considcram tabla de joe din figura urmatoare :

Collapse

Collapse este un joe foarte popular. labia de joe este -reprezentata de 0 zona dreptungbiu­lara depe -ecran, zonafiind implirtitfi in celule, organizate in Nlinii ~i Mcoloane. Fiecarecelula poate contine 0 piesa rosie (identiflcataprin litera R). verde (identificataprin literav) sau albastra (identificata prin Iitera A).

Actionand -printr-un click 'pe 0 piesa, tot grupul de piese corespUIlZAtor acesteia -vadisparea.

Grupul unei piese este 'format din toate piesele eeau aceeasi culoare cuaceasta ~i lacare se poate ajunge deplasandu-nenumai pe piese de aceeasi culoare ell piesa respectiva.o deplasare se poate face in patru directii (sus, jos, stanga sau dreapta), Un grup trebuiesa contina cel putin doua piese.

Dupa ce grupul piesei asupra careia am actionat printr-un click a disparut, piesele de petabla se _prabUljesc". Prabusirease realizeazli executand, in ordine, urmatoarele douaoperatii :

1. Mai intai. toate piesele ramase "cad" (sunt deplasate In jos), pentru a umple golurilede pe coloane; ordinea pieselor pe coloane se pastreaza.

2. Daca 0 coloanii se goleste complet, ea va fi eliminata,deplasand celelalte coloanecatre stanga, cat este posibil; ordinea coloanelor se .piistreaza.

Apoi se elimina coloanele goale :

113:METODA .BACICmACKlNG

V R

V V A V

V V A V

V V A V V

V V A A A

.A V A V V A

A A A V V R

A A A V R R

A V R V

V A V

V V A

V V

V V A, V V

V V A A A

A A A V V A

A A A V V R

A V R R

V R

V V A V

V V A V

V V A V V

V V A A A

A V A V V A

A A A V V R

A A A V R R

Jocul se termina cand pe tabla de joe nu se mai pot forma grupuri de piese.

Apoipiesele se prabusesc. Mai intai"cad". pentru aumple -golurile pe coloane :

Daca executam am clic pe -piesa din -coltul-din :stanga.,sus~ -obtinem :

Vasile joaca acest joe de multi ani. Niciodata nu joaca la intamplare, intotdeaunafoloseste aceeasi strategie. La fiecare pas. 'Vasile face un click pe 0 piesa din eel maimare grup existent pe tabla de joe. Chiar daca exista mai muIte posibilitati de a alegepiesa, el va face click pe piesa situata pe cea mai din stanga linie. Si daca exista maimuite posibilitati de a alege 0 piesa pe cea mai din stanga linie, Vasile 0 va alegeintotdeauna pe eea situata eel mai jos.

R R A R V R V

R R R R V A V

V R R R V A R

V V R R R R R

V V R R A V V

V V R R A A A

A A A R V V A

A A A R V V R

A R R R V R R

.':PROGRAMAREAJN.LIMBAJUL C/C++ 'PENTRUllCEU

FILE "*g i

citire () ;

bordare ()-;

depune{i__~rim, j_prim);g=fopen l".albina. outrv , -"w");

fprintf(g, "'%d", aria(»;

fclose (g);

:return 0;

j.nt __main ()

112

I

l;S;N,M:::;SO

Date .deintrare

Date de iesire

115

//culoarea celulei//numarul grupului din care face parte celula

char cuI;int gr;

} ;

METODA:BACKTRACK/NG

#include<fstream.h>-#define DMax .52_#defineJnFil.e '''joc . .Ln'"4fdefine OutFile ~"joc_out"

#define. Dir -4

linmax=O; colmin=m+l;dim = ,prelucrare tabla();if (dim>1)

nrclic++;refa_tabla(linmax, colmin);

}

whi.J.e (dim>1);afisare();return 0;

voi.d' citire ()int i, j;ifstream fin(InFile);fin»n»m; fin.get();

int main ()int dim;ci tire () ;do

int dlIl={~l,O,l,O}i

int dc[]={O,-l,O,l}i

-void, ci tire () ;void afisare () ;int prelucrare_tabla();int det_grup(int , int , int char);void sterge_grup(i.nt , int , int );void refa tabla(i.nt , i.nt );

.struct poz{

I poz T[DMax] [DMax]; //tabla de jocint n, m, linmax, colmi~r nrclic;

.~ /* linmax. si colmin reprezinta coordonatele celulei din unulI dintre grupurile de dimensiune maxima, care se afla cel mai inIstanga-jos */

II!Il!

!

~.,

joe.out7

Olimpiada Nationala de Informatica, Galati. 2005

joe.in8 7

RRARVRVRRRRVAVVRRRVAR

VVRRAVV

VVRRAAA

AAARVVA

AAARVVR

ARRRVRR

joe.out3

'PROGRAMAREA 'iN L1MBAJUL~C/C++ PENTRU·LlCEU

joe.in3 4AVVR

AAVV

AVRR

Soltqie

Pentru determinarea/stergersa unui grup.se utilizeaza un algoritm defill.

Se repeta cat timp se mai pot forma grupuri ell eel putin dona elemente :I. Se determina grupurile de pe tabla. Pentru fiecare grup determinat se calculeaza ~i se

retine dimensiunea maxima, precum si elementul eel mai din stanga-jos ce apartineunui grup de dimensiune maxima.

2. Se sterge grupul de dimensiune maxima seleetat.3. Se compacteaza coloanele,4. Se eliminll coloanele goale.

Restrictii

Fisierul de -iesire j oc. out -va contine 0 singura linie pe .care va -n .scris numarul .declick-uri pe care le executa Vasile 'pam la. terminarea jocului,

114

Cerin!aScrieti an program care 'sa -simuleze jocul ai sa.determine ammarulde.click-uri pe careJe executa Vasile .pana 1a uerminareajocului.

Exemple

Fi§ieruldejntrare j DC .in.contine,peprimaJinie.douanumere:naturaleseparateprintr-unspatiu, N M,ce reprezinta numarul de Iinii.trespectiv numarul .de .coloane .de pe tabla dejoe. Urmeaza N linii, fiecare linie continand M.caractere dinmultimea {..R....... 'flv"......A"}.

i !lJ

r,

rI .l ;

r-t

II 'r.,

,

r-'

l]

rI ',•. .1

r-t

l i

r;I II 't, J

~, ,

I ILi

n\L ,J

, l

r

I'

n,,

·r~...------------~

METODA BACKTRACKING

for (i=l; i<=n; i++)for (j""l; j<=m; j++)

T(i] [j] .gr = 0;

117

i2--);

void afisare (){o f s t r-eam fout (OutFile) ;fout«nrclic«endl;fout. close () ;

void refa_tab1a(int lin,int col)int i, j, i2, j2;sterge_grup(T[lin] [col] .gr, lin, col);for (j=1; j<=rn; j++)

{ Ilprelucram coloana j£or (i=n; i>=I; i--)

if (T[i] [j] .eul==' I)

lilcaut mai sus un element coloratfor (i2=i-1; i2>=1 s s T[i2] [j] .eul==' ';~f (i2) Ilam gasit

{T[i][jJ~T[i2][j], T[i2][j].cul~' "

.e.Lee break;

}

Ileliminam coloanele goalefor (j=1; j<=m; j++)

if (T[n] [j] .eul == ' ') Ilcoloana j este vida{Ilcaut in dreapta 0 coloana nevida£or (j2=j+l; j2<=m && T[n) [j2].cul==' I; j2++);i.f (j2<=m) I lam gasit/Icopiez coloana j2 peste coloana j; sterg eoloana j2

for (i=l; i<=n: i++){T[i] [j]~T[i] [j2], T[i] [j2].cul~' ',}

.e.Lee break;

~oid 'sterge_grup(int ,grnum, int i, int j){±£ (T[i] [j] ..gr == gru"urn.&& T·[i] [j] .cul!=' ')

( T[i] [j].cul=' ':sterge_grup(grnum, i-1, j);sterge_grup(grnum, i, j-1);sterge_grup(grnurn, i+1, j);

sterge_grup(grnurn, i, j+l); I}

.:£or· (i=1; i<=n; i++){

:£or(j=1; j<=rn; j++){fin»T[.i] [j].cul;

£in.getO;Ilbordare£or (i=O: i<=n+1; i++)

T[i] [0] .gr=T[i] [rn+1] .gr=DMax*DMax+l:Ior (j=O; j<=m+l; j++)

T[O] [j] .gr=T[n+1J [j] .gr=DMax*DMax+l;fin. close () ;

dim = det_grup(grnum, i, j, T[i][j].cul);I/marcam grupul

if (dim > maxdim){rnaxdim = dim; linmax=i; colmin=j;elseif (dim==maxdim)

if (j<colmin) leolmin=j; linmax=i;}elseif (j==colmin)

if (i>linmax) linmax=i;grnum++;

PROGRAMAREA iNLIMBAJUL C/C++ PENTRU'LICEU

return maxdim;

int preIucrare_tabIa{)/* identifica toate grupurile si returneaza dimensiunea grupuluimaxim */

int maxdim = 0, dim, grnum=l, i, j;for (j=l; j<=m; j++)

for (i=n; i>=l ; i--)if (T[i] [j).gr == 0 s s T[i] [j] .cul!=' ')

Ilaeeasta celula nu apartine niei unui grup

int det_grup(int grnum, int i, int j, char ch)int sum=l, k;i.f (T[i](j].cul!= ch) return 0;

T(il [j] .gr = grnum;for (k=O; k<Dir; k++)

if (T[i+dl [k]] [j+dc [k]] .gr~~O)

sum+=det_grup(grnum, i+dl[k], j+dc[k], ch);return sum;

~~~

!iI

I~\1

II~~,~IJ!~'!

116

!

~.,

¥;

~'!t::Ci,:;

M~

t

~i:

.~

!il'I';lI"~

f,,\i'J~:

l ...'

i' 4. Considerajll rmale asupra metodei Backtracking

,-,5. Probleme propuse) ,I .L, .l . Urmariti pas cu pas execupa urmatorului program pentru n=4. Ce va afisa pe ecran

programul ?

119,MElODA .BACKTRACKING

Variant~ bacalaureat, 2000

2. Care,dintre .urmatoarele afirmatii sunt adevarate §i .care sunt false?a) Metoda Backtrackingse poate 'implementa numaicu ajutorul functiilor recursive,.b) Metoda Backtracking evilli generareatuturor -solujfilor ']losibile, -urmata.de veri­

ficarea conditiilor interne pentrufiecare .solutie posibila,c) lndiferent deproblema"aplicareametodeiBactracking conduceIa cei mai -eficienti

algoritmi.I

3. Prin metoda Backtrac/dngau fest 'generate toate posibilitatile dea aranjape un randpatru copii (Ana, Dan, Ion, Maria), .astfel Incat sa -nu tie plasati .doi -baiet'i unulIanga altul. Primele patru solutil generate sunt :Ana Dan Maria IonAna Ion Maria DanDan Ana Ion MariaDan Ana Maria Ion

Care va fi urmatoarea solutie generata ?

4. Secvenje binareSa se genereze, toate secventele binare de lungime m in care apar n de 1.

5. ColiereScrieti un program care sa vizualizeze in mod text toate colierele -de n (neN*)

margele albe, rosii, galbene, .verzi §i negre ce se pot construi respectand urmatoarele reguli :- nu plasam doua margele de aceeasi culoare in pozitii consecutive;- nuplasam margeje albe Jiingli margele galbene ~i nici margele verzi Jiingli margele

negre;- nu utllizam mai mult de n/2 margele rosii,

6. Numere cu suma cifrelor dataSa se afiseze toate numerele formate din cifre distincte cu proprietatea ca suma

cifrelor este s. Valoarea variabilei s se citeste de la tastatura. Solutiile vor fi afisate peeeran. De exemplu, pentru S~3, se afiseaza solutiile 102, 12, 120, 201, 21, 210, 3, 30.

Bacalaureat, 20007. Matrice

Fie ne Nv, n.:5:10. par. Sa se genereze toate matricele cu n linii si n coloane avandcomponente numere naturale intre 1 §i n, astfel incat oricare doua elemente vecine (peorizontala sau verticals) sa fie de paritati diferite, iar. elementele de peacee3§i linie,respectiv de pe aceea§i coloana sa fie distincte.

Solupile vor fi afi§ate in fi§ierul matrice .out, intre doua solutii consecutive fiindserisa 0 linie goala.

8. OperatonSe citesc de la tastaturaun numar natural n (O<n~lO) §i apoi n valori naturale aI'

a 2, ... , all" Afi§ati pe ecran toate posibilitiitile de a intercala intre toate numerele aI' a 2,••. , an operatorii + §i - astfel Incat, evalua.nd expresia obtinutii de la stanga la dreapta,la fiecare pas rezultatul obtinut sa fie strict pozitiv. Fiecare solutie se va afi§a pe cate 0linie. De exemplu, pentru n=3 §i valorile a 1=3 , a

2=5 . a

J=2 , se vcr afi§a solupile:

3+5+23+5-2

c++)

PROGRAMAREA lNUMBAJULC/C++'PENTRU LICEU

#include <iostream.h>char x[30];

int n;void gen (.i.nt k)

{ if (k==n) cout«x«endl;el.se

for (char c='a'; c<'d';if (x[k-ll !=c)

(x[kJ=c;gen(k+1) ;

int main (){cin»n;x[OJ='a';gen (1); return O;}

118

i ':L~,i

~,n. ," 'I ,

i j

I !'i.~

A existat operioada in -evolutia .giindirii ;algoritmiee clnd metoda JJacktracking eranconsiderata .un -panaceu, 'Nu stim -sa sezolvam .o 'problema? Nu-i :nimic! .Aplicam nnI ': Backtracking! .Sigur ca aceasta metoda .are.avantajefndiscutabile..A§a-cum spuneam laL"~inceputuI -.capitolului,metoda -evita -generarea zuturor -solutiilor -posibile•.urmata-de

verificarea conditiilor problemei pentru :fiecare ;solutie :posibiHi.:{adica.sepoatesi .mair -rau).1n-plus, rezolvarea.Wleiprobleme prin Backtrackinggaranteaza obtinerea-solutiei.1 . Numai ca tnnpulde .executie .este foarte .mare, din cauza revenirilor -speciflce -metodei.l ~ Uneori,tirnpul.cte executie este atatde mare, incat, pentru-:dimensiunimari.ale datelor.-- .de intrare, este practic unposibila obtinerea unei solutii,i in conc1uzie, cand trebuie sa rezolvam o problema, Incercamv In primul rand, saI J elaborlim un .algoritm care nu se bazeazape Backtracking. Daca nu reusim sa elaboram

un astfel de aIgoritm san .acesta nu exlsta, .analizam datele -de intrare. Daca datele de".-. intrare au dimensiuni rezonabil de mici. astfel mcatun algoritm.Backtracking-safurnizeze! isolutii in timp utll, .abordam problema in aceasta maniera, Daca Insa datele de intrareau\ j dimensiuni mari, ceea ce 1n -practica este -inevitabil. 0 abordare Backtracking este

inacceptabila.n Principiul de baza poate fi rezumatastfel: decat un algoritm teoretic perfect. .darI [care sa nu furnizeze solutii in timpul disponibil, mai bine ,unalgoritm bun. care sa ofereLJsoluJii "aproape" optime In scurt ttmp, Un astfel de algoritm este denumit algoritm

euristic, Studiulalgoritmilor euristici este 0 problema ."fierbinte" la ora actuala inrinformatiea.Il,l

Bacalaureat, 2001

Bacalaureat special, 2002II. Rand.

Intr-o clasa de n elevi sunt f fete (n , feN*. f:::;;n). Fetele sunt numerotate de la 1la f, iar baiejii de la f + 1 la n , Sa se genereze toate posibilitatile de a forma un rand dinp elevi {pSn} astfel Incat sa nu existe doua fete asezate in rand una lang-a cealalta,respectiv doi baieti ·unullanga celalalt.

12. Generare de siruri crescatoareSa se genereze toate sirurile strict crescatoare formate din numere naturale' eu

proprietatea ca primul element din sir este n , iar uItimul element este n+k. Numerelenaturale n $i k (O<n<20, 0<k<16) sunt citite de la tastatura. Fiecare §ir generat va fiscris pe 0 linie, elementele nnni §ir fiind separate prin cate un spatiu.

De exemplll, pentru n=7 §i k=3. se vor afi~a (nu neaparat in aceastii ordine) §irurile:

7 8 9 107 8 10

7 9 107 10

t21METODA BACKTRACKING

14. Tombolii

La 0 tombola sunt n obiecte (numerotate de Iat la n}, care valoreaza vI' v2' ..• ,

respectiv vn lei. Premiul eel mare trebuie sa fie format din obiecte din categorii diferite,a carer valoare totala sa fie de exact s lei. Sa se determine in cate moduri se poatcconstitui premiul cel mare.

Datele se citesc din fisierul de intrare tombola. in, ee contine pe prima linie unnumar natural nenul n, reprezentand numarul de obieete. Pe cea de a doua linie se aflan numere naturale nenule separate prin catc un spatiu, reprezentand, in ordine, valorilecelor n -obiecte. Pe urmatoarea linie este serfs un numar natural k, reprezentand numarulde eategorii. Pe ultima linie este sunt scrtse n numere cuprinse Intre 1 ~i k , separate prinspatii (al i-lea numar de pe linie reprezinta categoria din care face parte obiectul i:,Numarul de variante va fi afisat pe ecran.

15. BardSe considera 0 bara de lungime n §i m repere de lungimi L 1, L z, ... , 'L

m• Din bara

trebuie taiate bucati de lungimea reperelor date, astfel Incat sa rezulte din fiecare repereel putin 0 bucata ~i pierderile sa fie nule, Scrieji un program care sa afiseze toateposibilitatile de mere a barei in conditiile enunjare.

16. BandaMisiunea unui robot este de a Ina obieete de pe 0 banda de asamblare, in ordinea in

care sunt produse, ~i de a Ie introduce in containere care sunt identice §i au capacitateagmax.

La fiecare moment de timp, numai dona eontainere sunt disponibile. Dupa ce ia unobiect de pe banda, robotul poate alege intre :

- a pIasa obiectul in unul dintre cele doua containere disponibile, daca este posibil(adica daca nn se dep3$e§te greutatea gmax) ;

- a lncbide unlll dintre cele doua containere $i a deschide unul nou, pentru a punein el obiectul.

13. Generare -de siruri .de cifre-Sase genereze toate sirurile formate din n cifre, flecare §ir generat avand urmatoarcje

proprietlip :- contine numai cifre din multimea {i , :2, 3, 4} ;-oricare .doua cifre .alaturate sunt fie ambele pare, fie ambele timpare.

I

Numarul natural n (3:::;;n~15) se citesrede la tasterura. "Ioate solutiile vor fi scriseunadupa alta, Cll spatii intre.ele, flecare.sir fiind scris faraspatii.intre cifrele ee-l formeaza.

De exemplu, -pentru n=3, se afiseeza (nuneaparat fnaceasta ordine) sirurile : 111 113131 133 311 313 331 333 222 224 242 244 422 424 442 444

Bacalaureat, august 2001

Atentie! Dupa ee a fost inchis nn container, acesta este sigilat ~i nu poate fi redeschis.Scrieti un program care sa determine numihul minim de containere necesar pentru a

transporta obiectele de pe banda de asamblare. daca se cunoa§te n, numa-rollor, greutatileacestora, 91 (i=l, ...• n), precll."ll §i eapacitatea gmax a unui container.

f(

PROGRAMAREA iNLIMBAJUL C/C++ PENTRU LICEU120

9. ExamenUn-studentprimeste la un examen n subiecte, numerotate.de.la 1 la n (1:>n:>2 0). Pentru

iiecaresubiect:sunt.cunoscute llunctajul care:se .obtine -rezolvand .subiectul .respectiv museacorda punctaje partiale), precum.§i.dificultateasubiectuIui. StudentuI vrea saoblinaeel putin un puncta] total p,.dar nupoatesa rezolve sUbiecte£udificuitatemaimaredecat D.

Determinati toatevariantele in care studentul poate ..obtine.am puncraj sarisfacator.Pisierulde intrare -exemen c Ln contine pe prima lillie 'trei numere naturale separate

prinspatii, n, P §i D. cusemnificatia din enunj. Pe cca.dc.a.douaIinie se afla nnumerenaturale separate prin .spatiiv reprezentand, in ordine, dificultatile subiectelor.Pe .ccadea 'trela 'Iinie se '-at1.a n -numere naturale separate prin .spatii, .reprezentand, in -ardine,punctajele subiectelor.

Fisierul de iesire examen . ou t va conune care 0 linie pentrufiecare varianta generata,Descrierea unei variante este constituita din numerele subiectelor rezolvate, separateprincare un spatiu. Daca nu exista nici 0 variantii satisfacatoare, fisierul de iesire va continepe prima linie mesajul MAr INVATA!.

10. Generarea unui sirSe citese de la tastatura dona numere naturale, a si b (O<a5:10, O<b:::;1000, 3*a5.b). Sa

se genereze eel mai lung sir care are ca prim element valoarea a, suma elementelor siruluieste egala cu b §i in care orice termen este cel putin dublul valorii termenului precedent.Sirul obtinut se va afisa pe un singur rand, cu spatii Intre elementele ee-l formeaza.

Daca exista mai muIte siruri cu acelasi numar maxim de elemente, se va .afisa unulsingur, oricare dintre acestea.

De exernplu, pentru a=4 ~i b=63 se va afisa orieare dintre urmatoarele siruri :

4 8 16 35

4 8 17 34

Se observa ca sirul 4 11 48 respecta conditiile din enunj, dar nu are numar maximde termeni.

~-=-_:,.::=-_·..:.;:~:-..z;,.:iN LIMBAJUL C/C++ :pENTRU LICEU

nRestrictiiL J ... "n::;25;

.• O<gmax:~:aOO;

n '. 0<g1::;100.

L~

n Olimpiada Municlpala de Informatica, Iasi, 2004

l ; 17. Puncte .• Fie n un numar natural (n:$;2 0) ~i pl' P2' •••• Pn - puncte in plan, avand coordonate

intregi. Sa se determine 0 modalitate de colorare a celor n puncte, folosind un numarn minim de culori, astfel incat oricare doua puncte situate la distant[ eel mult egala cu D

l . sa fie colorate diferit.

18. Concursr Cei N elevi, numerotati de la 1 la N, din tabara olimpicilor informaticieni de laL1 Costinesti doresc sa se intreaca tntr-un campionat pe nisip de tras la franghie. Pentru

.J aceasta, ei se impart in, P echipe, dar pentru ca .intrecerea sa fie cat mai echilibrata,echipele trebuie sa fie cat mai apropiate ca greutate. Greutatea unei echipe este data de

n surna greutatilor componentilor ei.I I.

L I CerinJdCunoscand greutaule 9 1, g2' •••• gN ale celor N elevi, sa se formeze cele P echipe astfel

nl

i incat acestea sa fie cat mai echilibrate, adica suma diferentelor de greutate dintre oricare. j doua eehipe sa. fie minima.

Date de intrareI Fisierul de intrare concurs. in va contine pe prima linie valorile N ~i r, separateLJ printr-un spatiu. Pe linia a doua se gasesc cele N greutati, separate prin cate un spatiu.

Date de iesireri ' F~;$ierul de iesire concurs. out va contine pe prima linie valoarea minima a sumeil' diferenjelor de greutate dintre oricare doua echipe. Urmatcarele p linii vor contine cele

123MEIODAdR4CKTRACKING

concurs.in concurs. out Explicatii7 3 24 Greutatea eehipei El este a 01. Greutatea11 20 30 39 50 61 70 127 echipei E2 este 89. Greurarea echipei E3

4 5 este 9l. Deci (E1-E2)+(E1-E3)+(E3-3 6 E2)=12+10+2~24 .

19. Problema bile!Un teren este reprezentat ea 0 matrice T eu n linii ;$i m coloane, elementele matricei

reprezentand cotele diferitelorportiuni de teren. In pozitia iniliala (xb.yb) se afla 0 bila.oStiind ca bila nu se poate deplasa decat mtr-o portiune de teren tnvecinata (pe directiileN, NE, E, SE, S, SV, V, NV) cu 0 cora strict inferioara pozitiei pe care se afla, scrietiun program care sa determine toate traseele pe care le poate urma hila pentru a iesi dinteren.

20.' Sarirura caluluiPe 0 tabla de sah de dimensiune n (n E N*) se afla plasat un cal in coltul din

stanga-sus. Afisaji toate posibilitatile calului de a parcurge toata tabla de sah fara a trecede doua orl prin aceeasi pozitie.

21. Explorarea LabirintuluiUn labirint este reprezentat ca un tablou bidimensional. Peretii labirintului sunt

marcati cu x, culoarele Iabirintului fiind marcate cu spatii. Problema este de a determinatoate punctele labirintului care pot fi vizitate incepand eu 0 pozitie inipala (de start)marcata prin caracterul *.

22. JoeExista ;$i jocuri care pot fi jucate de un singur jucator. Un astfel de joe este descris

mai jos.o tabla rectangulara de dimensiuni NxM este plfna cu litere mari ale alfabetului (A-Z) .

La inceputul joculul, in coltul din stanga-sus al tab!ei este plasata 0 piesa. In fiecaremoment, jucatorul poate muta aceesta piesa intr-o pozitte vecina (sus, dreapta, jos,stanga), en singura restricjie ca in pozitia respectiva sa nu existe 0 litera peste care plesaa mai trecut. Scopul jocului este de a mentine piesa injoc cat mai muIt posibil. Jocul seopreste cand piesa nu mai poate fi mutata tntr-o pozitie valida §i se opreste intr-o pozijiein care exista 0 litera peste care piesa a mai trecut.

Scrieji un program care determina numarul maxim de mutari pe care Ie poate facejucatorul,

pechipe. iieeare Jinie -contingnd indicii .membrilor uaeiechipe, .separati prin .cate un-gpatiu.

Restrictii.. 2::;;N:$;10;... 2::;P::;6;

'. P's"N;.• 40::;gi:$;99, ~::;i::;N;

.. .in :fiecare ·echipa trebuie .sa.existe eel putin .unelev.

Exemplu

banda. out

36 84 2 5 3 5 4

Exemplu

n banda.in. I

l J

::Date -de intrare'Prima dinie .a -fisierului-de intrare j oc .in -conune .doua valori intregi N .si M, separate-printr-un -singur -spanu, rreprezentand dimensinnile aablei .de joe. Urmlitoarele N linii.eontin fiecare cate x caractere 'reprezentand tabla.de joe.

Date .de iesire-P4;ierul .de Iesire j occ ou t .contine 0 singura linie pe care -se .ami nu.m3rulmaxim .dezmutaripe care .Ie poate face jucatorul,

Restrictii

l:$N. M530

.campion, 200323. Calul si Regele

Un cal §i un rege se afla pe 0 tabla de sah. Unele dintre campuri sunt arse, pozitiilelorfiind cunoscute. Calul TIU poate calca pe campuri.arse, iar orice miscare a calului peun nou camp, binelnteles nears. face ca acesta sa devina ars. Scrieti un program care sadetermine daca exista 0 succesiune de mutari prin care calul sa ajungil la rege §i sa revinain pozitia sa initiaHi, cu regele in spate.

24.Popularea acvariuluiDaca dorim sa cream un acvariu cu pesti exotici, trebuie sa cerem avizul unui expert

pentru a nu ajunge in situatia in care sa cumparam tipuri de pesti ce nu pot coexista in.acvariu.

Fiind date numarul maxim n de tipuri de pesti §i suma S care poate fi cheltuita pentruinvestitie, se cere sa se stabileasca numarul maxim de tipuri compatibile de pesti care sepot cumpara, Pentru acest numar, se cere suma maxima folosita (dar nu mai mult de s),stiind ca se cumpara care un singur peste din fiecare tip.

Scrieti un program care citeste din fisierul de intrare acv . in :

- de pe prima linie, s , soma de bani disponibila (SO;; 1000) ;- de pe a dona linie, n , numarul de specii (n;5;30);- de pe a treia linie, in ordine, pretul fiecarei specii de pesti ;

pe fiecare din urmatoarele linii se specifica care 0 pereche de speeii de pesti (separateprintr-un spatiu) care nu pot coexista in acvariu.

in fisierul acv . out vor fi afisate numarul maxim de specii ce pot fi cumparate, sumamaxima cheltuitii, preeum §i speciile cumparate in aceste condirii.

"PROGRAMARBA1NLIMBAJUL C/C++-PENTRU.l.JCEU

:j: ,, c..i

125MEfODkBACK1RACKING

Baraj, Pocsani, 1995

Jnltial; rama nu are sn si nu se poate deplasa tara SN. Daca nu este posibiHi cuIegereatuturor cantitatilor de SN, .se va afisa. mesajul Rama moare.

:25. lI.iima JacomiJ.

Se-da 0 .retea .rectangulara ,de -dimensiune mxn (O<m<101, O<n<101). In .anumitenoduri,alecarorcoordonate .se 'citesc din fisierul de .intrare, se afla substante nutritive(SN) in .cantitati precizate. OIfuna -se poatedeplasa orizontal sau -vertical, pornind>!lintr-un nod .ce.contine SN. ,Deplasarea-mtreidoua noduri:aIaturatepresupune -pierdereaunei amitati .de SN.1'recerea'printr-un nod .ce .contine su presupune casrigarea .intregiicantitatide .SN din 'nod. ·Sa se.stabileascaun mod ·'de plecare ~i un traseu de deplasare-astfel ineat :

rama :sa culeaga toate 'cantitatile de sn ;cantiiatea finalade.sn cii§tigatll de rama sa tie maxima.

joe. out6

joe.in

3 6HFDFFB

AJHGDHDGAGEH

joe.out

10joe.in

5 5IEFCJFHFKCFFALFHFGCFHMCHH

joe.out3

Exemple

joe.in

2 4

CAAB

ADCB

124

n! ,

nLJ

127

Ilam obtinut 0 solutie, 0 afisam

I/plasam .valoarea j pe pozi tia k

Ilgeneram in continuare

Ipozitiile 1, 2, ... , k-l deja

ELEMENTE DE COMBINATORICA

;int main (void)

cd tire () :-qenexer e (1) :

£out.. close(): return 0;

}

'Void generare (intk)

1* cand apelam generare(k)sunt ocupate *1

lint .j;

if (k==n+l)

afisare () :

'eJ.se~or (j=l; j<=L[k]; j++)

{E[kl~j;

generare(k+l):)

void afisare{void)

{int i:.

for (i=l: i<=n; i++) rout c-cz ri j c-c ' ','fout«endl;

void citire(void)

{Lrs t z-eam fin("pc.in"):fin»n;

for (int i=l; i<=n: i++) fin»L[i):fin. close ():

Observatie

in programul precedent am presupus, tara a restrange generalitatea, ca elementelemultimilor sunt numere naturale cuprinse Intre 1 §i Li' V'.i E { 1, 2•...• n}. Acest aspectnu reprezinta 0 restrictie, deoarece oriee multime eu L i elemente este in corespondentabijectiva eu multimea {1. 2•... , Li } . Plasand elementele multimii intr-un vector, asociempractic fiecarui element din multime un element at multimii {I. 2, ... , Li}' La afisareaunei solutii, in loe de a afisa elementul E [i 1, il afi§am pe eel plasat pe pozitia E [i J inveetorul corespunzator multimii L.

CAPITOLUL4

Elemente .de combinatoricli

#include <fstream.h>#define DMax 20

int n/ L[DMax], E(DMax);

ofstream fout (v pc . out"): I I fisierul de iesire

l j

r:l,r-,Il" Analiza combinatorici este 0 ramura a matematicii care studiaza -diferite posibilitati

de ordonare .sau de combinare a unor elemente. De exempluv cIn cate moduri 1'utem....... aranja patru litere diferite?" san ."cate posibilitati exista dea construi -0 echipa fermataI ! din cinei fete ~i trei baiep dintr-o clasa en 20 de fetesi 11 baiep?".~ J La matematica, am studiat cateva elemente de combinatorica (permutari, combinari,

aranjamente). In acest capitol vom descrie algoritmi recursivi de generare a unor elementer combinatorice, de numararc san de ordonare a unor configuratii,I '; !

LJ

Ii

li

nl I

Generarea produsului cartezian

nFie neN* Si A l • Az' ... , An n rnultimi ell L l• L 2, ••• , respectiv Ln elemente. Sase generezeL_, elementele produsului cartezian Al xA2x ••• xAn" -

__ Prin definitie produsul cartezian Al xA2x ••• xAn este multimea n-uplu-rilor (e l ,

I :e 2 , "', en) cu proprietatea ca eiEAp pentru V'iE{I, 2, ...• n}.LJ De exemplu, pentru n=3 §i L=(2, 3. 2). elementele produsului cartezian sunt :

(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,3,1), (1,3,2), (2,1,1), (2,1,2), (2,2,1), (2,2,2),n(2.3,1). (2.3,2). Observati ca produsul cartezian are L1*L2*... *Ln elemente.

I ISolutie

Vom reprezenta un element al produsului cartezian ca un vector E eu n elemente, undenE u: E{l, 2, ... , L,}.

i j Condifie internd

E[i] ef L, 2, ... , L[iJ}, ViE{I, 2, ... , n}

void citire(void):

!i I VO~d gene rare (i~t).;

1 I I 'vcdd afisare (voJ.d.) :\ I

Iti .~~~~~~~~-

Generarea'}lermutiirilor

1. La algebra, am demonstrat eli, pentru cazul in care domeniul Sicodomeniul unei functit au acelasinumar de elemente, bijectiv c> injectiv ¢::) surjectiv.

"Fie n eN*. Scrieti un program recursiv de -generare.a permutarilor.fie. ordin n.De exemplu,-penrru nea, programulwa "genera :1 2 3

1322 1 32313 1 2

321

w

129ELEMENTE DE COMBINAIDRIcA

i'f (!uz[i.]) .//daca .nu -ea t e utilizat deja in p(p[kl=·i; uz [il=l;

/*i este un candidat; deoarece nu esteimagineanici unui alt element fixat*/

GenPermutari(k+l); //apel recursivuZ[i]'=O;}

int main (){cout c cvn> "; cin»n;GenPermutari(l);fout. close (); :return 0; }

Observatii

Soliqie

a) Observam ca numarul de ordine al unei permutari este ega! eu numarul de permutaricare 0 preceda in ordine lexicografica,Sa consideram ca permutarea data este p=(p1' P2' •.. , po)· Aceasta permutare ineepeell PI' deci in ordine lexicografica va fi precedata de toate permutarile eare ineep eu

Numarul de ordine al unei permutarl

Fie neN*. Consideram toate permutarile de n elemente din multimea {I, 2, .,., n}, inordine Iexicografica. Prima permutare (permutarea identica) are numarul de ordine o.

a) Fiind data 0 permutare de n elemente din multimea {i , 2, ... , n}, sll se determinenumarul ei de ordine.

b) Fiind dat un numar k~n!, sa se determine permutarea eu numarul de ordine k ,

1. Pentru generarea permutiirilor am utilizat 0 tehnica interesanta. in loe sa verfficampentru fiecare.element i daca este sau TIU un candidatpentru pozitia k prin eompararealui i eu elementele deja fixate in vectorul p (p [1], P [2 ] , "', p [k-l ) ), am preferatsll optimizlim functia de generare, utiliziind 0 variabilll globalll suplimentarll - veetoruluz . Acesta reprezmta vectorul caraeteristie al multimii elementelor-imagine alefunctiei P '(uz [i] este 1 daca elementul i a mai fost folosit, adica reprezinta dejaimaginea unui element din multimea {1, 2, ... , k-1}, respeetiv n, daca i nu a maifost folosit), Ciind plasam-un candidat i pe pozitia k, aeesta reprezintli imaginea luik prin intermediul functiei, deci ua [i] va deveni 1. Cand revenim dintr-un apelrecursiv, pe pozitia k urmeaza sa plasam un alt candidat, deei i nu va mai fi imaginea

. lui k, prin unriare u z [i 1 trebuie sa redevina O.

2. Numarul permutarilor de ordin n se noteaza eu Po ~i este 1 x2 x ... xn=n! (n factorial).Prin definitie, O!~1.

-"

iesire

, .,

/ /fisierul de

i<=n: i++) fout«p[i]«'

PROGRAMAREAJN LIMBAJUL C/C++PENTRU L1CEU

void GenPermutari(int k)/*cand apelam functia Genpermutari eu parametrul k

pozitiile 1, 2"",

k-1 din vectorul p sunt fixate*/{1f (k-l==n) ,//solutia este eompleta

Afisare(); //prelucrarea solutiei consta in afisaree1se //continuam generarea

//determin candidatii pentru pozitia k

for (1nt i=1; i<=n; i++)

*include <fstream.h>

void Afisare ()

for (int i=l:fout«endl; }

Soliqie

Reprezentarea informaiiilorpermutarile de ordin n reprezinta toate posibilitiitile dea aranja elementele unei multimide n elemente. Definite riguros, permutilrile de ordin n sunt functii bijective de forma:p: {i , 2, .. " n}-+{l, 2, ... , n}. Reprezentam 0 .astfel de functie prmtr-un vector p cun componente avand semnificatia : p (i j este elementulasociat-piin intermediul functiei

p elementului i (\tie{l, 2, ... , n)).

Conduit interne1. p[i) Ell, 2, ... , n}, \tie{l, 2, "', n} (domeniul de valori este {i , 2, ... , n}).2. p l Ll sepl j l , \ti*j; i, jell, 2, "', n} (funetiaesteinjeetivll').

li n t n , p[40J, uz[40];

ofstream out ("perm.out") ;

I

·28

~

ii

~

,,

; :, ,b)

M

I

r-t

: i, I

r-<, ,

~.j

nl i

r, .

r-

J., 2, •••, p,-l. iExistli (p,-') ~ ( (n-l) ,!) .astfel.Je'PermutlirLLa=estea"eadauga. lOate permutarile .care lincep cu p, '§i .care 'Preced rpermutarea .Jatli.llliminam P,odiupermutare, Tenumerotlim",lementelel'ermutJirii 'Ii .objinemo permu­tare •de .dimensione n-l .Ia-care .aplicam.acelasi-rationament.

Solutie

131-ELEMENTEUE COMBINATORICA

:for (1=1.-; .i<=n-;i++) ··cout-«P.li]«' I;

cout«endl;:xeturn 0;

Observati din modul de reprezentare a 'informatiilor Si din formularea condijlilorinterne ca singura diferenta dintre generarea permutarilor §oi generarea aranjamentelorconsta in dimensiunea vectorului-solutie. Prin urmare, descriem numai functia recursivade generare a aranjamentelor :

void GenAranjamente(int k){/*cand ape lam functia GenAranjamente cu parametrul k,

pozitii1e 1, 2, "., k-1 din vectorul f sunt fixate*/if (k-1==m) //numaru1 de elemente din submultime este m

Afisare () ;el.se / /continuam genera rea

Reprezentarea informatiilor

Reprezentam 0 functie printr-un vector f. en mcomponente, f [i J este elementul asociatprin intermediul functiei f elementului i (V'i e (1 , 2 , ..., m) ).

Conditii interne

1. f[il E{l, 2, ... , n}, 'o'iE{l. 2, "', m} (domeniul de valori este {l, 2 •...• n)).2. f [i] *f [j] , 'o'i*j; L, j E {l, 2, ...• m} (functia este injectiva).

Aranjamentele de n elemente luate cate m reprezinta toate submultimile ordonate de m

clemente ale unei multimi cu n elemente. Definite riguros, aranjamentele de n elementeluate care m sunt functiile injective'de forma:

f' {i , 2, ... , ml-*{l. 2 •. ". n}

Fie n eN* Si me N, :mSn..Scrieti 1lD. program .recursiv .care sA genereze .aranjamentele den elemente Iuate cate m.

De exemplu, pentru n=3 si m=2. programul va genera:1 21 32 1

2 3

3 1

3 2

;Genernrea aranjamentelor

IPROGRAMAREA.iN 11MBAJUL C/C++ vpENTRULICEU

~nt main (){int i, j;cout«u n= "; cin»n;cout«"k= ";cin»k;for (fact[0]=1, i=1; i<=n; i++) fact(i]=i*fact[i-1];

for (i=1; i<=n; i++){p[i]=k/£act[n-i]+1;k-=(p[i]-1)*fact[n-i] ;

for (i=n-1; i>=1; i--)for (j=i+1; j<=n; j++)

~f (p[j]>-p[i]) p[j]++;

#include <iostream.h>int n , p[40];

~ong ~nt fact[40];~ong k;

Fie k numarul de ordine al unei permutari de dimensiune n. Toate permutarile carelncep ell x voravea numarul de ordine mai mare decat (x-I) * (n-I) !. Deci putemcalcula P1=k! (n-!) ! +1. Pentru a calcula P2' scadem din k numarul de permutaricare incep cu p 1 §i reducem problema la a determina primul element at unei permutaride dimensiune n-l. La sfarsit, renumerotam elementele permutarii,

)

.fi"nclude -cdcat.z-eam-fi>

.:int .n , F [40];

~ong~nt ract[40];~ong-nr;

int main()

{..int i, j;

cout«"n= ": cin»n:cout«"permutarea: u: £or (i=1; i<=n; i++) c Lncc-p l Ll s

fact[l]=l:£or (i=2: i<=n: i++) fact[i]=i*factli-l]:

£or (i=1; i<=n; i++){nr+=(p[i]-l)*fact[n-i];-for (j=i+l: j<=n: j++)

if (p[j J>p[i]) p[j] --;)

cout«nr«endl:return 0:

130

~

, I

i I1 ,

!I, '

: I

rI ,..'...

i I

.~

,-,

Soliqie

Combinarile de n elemente Iuate cate mreprezinta toate submultimile de melemente aleunei multimi ell nelemente. Observati ca, spre deosebire de aranjamente, ordineaelementelor din suhrnultime nu conteaza. Din acest motiv, pentru a nu genera de maimulte ori aceeasi submultime (de exemplu, 1 2 §i 2 1). vom stabili 0 ordine convenabilapentru elementele submultimii - ordinea crescatoare.

.PieneN*§i meN, ~n. Scrieti un program recursivcare sa genereze combinarile de n

elemente luate cate m.De exemplu, pentru n=4 ~i m=2, programul va genera:

1 21 31 4

2 32 4

3 4

Reprezentarea informatiilor

Reprezentiim 0 submultime printr-un vector C care contine cele m elementeale sub­

multimii, ordonate crescator.

Conditii interneJ. c j Lj e{l. 2•... , n}, 'v'ie{l. 2•...• m} (elementeleapartinmultimii {L, 2•...• nj}.2. C[il<C[i+ll. 'v'ie{l. 2 •...• m-c.} (elementelesuntordonatecrescator).

Conform celei de a doua conditii interne, pe pozitia k putem pIasa doar elemente maimarl decat elementul plasat pe pozitia k-1 (c [k-1J). Deci valoarea minima care poatefi plasatli pe pozitia k este C [k-1 ] +1. Pentru ca aceasta formula sa fie valabila pentruonce pozitie k (inclusiv pentru k=l) vom considera C [OJ =0.

L

. ,

133

Ilfisierul de iesire

n!

m!x(n-m) !C;

El.EMENTE DE COMBINAlORlcA

#inelude <fstream.h>int fit rot e[40];ofstream fout("comb.out");

Observatie

int main ()(cout«"n= Of; cin»n; cout«"m= "; cin»m;GenCombinari(l);fout. close (); return 0; }

void GenCombinari(int k){/*eand apelam funetia GenCombinari eu parametrul k

pozi tiile 1, 2, ... , k-l din vectorul c s un t; fixate* Iif (k-l==m) Iisolutia este completa

Afisare{); Ilprelucrarea solutiei consta in afisaree~se I/continuam generarea£or (int t=c[k-lJ+l; i<=n-m+k; i++)

fc[k]=i;GenCombinari (k+l);} I lapel recursiv

C~=C~_l+C~~;, C~=C~=l

voi.d Afisare ()-for (int i=l; i<=m; i++) .rou t c-cc j Lj c-c ' I;

fout«endl;}

Numarul de combinari de n elemente luate cite m este :

in, plus, numarul de combinari de n elemente Iuate cate m satisface relatia derecurenta :

Deoarece odupli C [ kJ .trebuie -plasate mca m-k .elemente mai marl .decat C [k ] , sa·determinlim-valoarea.maxnna care -poate Ii -plasatli-pe-pozitia k.

••• ? ••• n-2

.••. k •.• m-2 m

Valoareamaxi.m.a care poatefi -plasata pepoztna m.este n, -pe-pozitia m-l este n-cLs.a.m.d. Observam ca .daca pozitia scade cu 1, '§i valoarea maxima care poate fi plasatape pozitia respectiva scade .cuI.Prinurmare, .diferenta dintre pozitie §i valoarea maximacare poate fi plasatape pozitia .respectiva este constanta (m-n). Deducem ca valoareamaxima care poatefiplasata pe pozitia keste n-m+ k , Prin urmare, multimea candidajilorpentru pozitia k este {C[k-1J+1, ... , n-m+k}.

A"- n!n-~

m!

-.PROGRAMAREA'iN LlMBAJUL-C/C++ PENTRU L1CEU

~or (int i=~; i<=n; i++):i"f (f u a [i] )

{:f [,kJ=i; .ua [.iT=~;

GenAranjamente(k+l);uz[i]=O;}

NumamI .de :aranjamente .de n elemente luate cate meste :

Observatie

Generarea comblnarflor

'132

,

! I

1'",

, "

, "Numarul de ordine alDnci;£OmbinarIr-t! :FienEN*~i.mEN,'~n ..Sa consideram combinarilede n-elemente.luate.catem.dnordineLJexicografica. :Primaeombinare:are mumarul-de 'online _0.

'3.) .Datlifiind °submultimede 'In elementea rnultimii ,{ 1, '2, _", n}, determinatinumarulri ei .de ·Qrdine. De exemplu.rpentru n=7lji m=4 ,:combinarea {1,,3,:5, 7 }"'2Ie numarull ] ne ordine 1-4.l 'b) 'Oat fiiud kun numar natural, .determmati combinareacu numarul de -ordine k ,

nj I Deducem ca pentru determinarea numarului de ordine, pentru primul element din1. "combinare trebuie adunate toate comb (n-j, 3) =comb (n-j, m-1) en 1::;;j <c [1] , deci

pentru care valoarea j preceda strict valoarea c r11 .il In mod analog, -pentru detenninarea numarului de 'submultimi care incep cu donaI !elemente fixate, observam ea exista comb (5,2) submultimi eu 4 elemente care ineep cu, ,j 1 2. eele 5 valori luate in considerare fiind 3, 4. 5. 6, 7 lji asa mai departe, .deci pentru

al doilea element al combinarii trebuie adunate toate comb (n-j, 2) =comb (n-j, m-2) ,neu c I1 ] +l::;;j<c [2] (pentru care valoarea j preceda strict valoarea c [2 ]).1 j Raponamentul continua in mod analog pentru celelalte elemente ale combinarfi.

135ELEMENTE DE COMBINATORICiI.

:for (j=c[i-l]+l; .j<c[i]; -j++)nrord+=comb (n-j, -m-i);

/* numarulde combinari care au fixateprimele ielemente este comb(n~j,m-i)

cout«nrord«endl;.%'eturn 0;

-unsigned long n r , c [10], n , m, nrord, k;int main (){ int i, j;

cout«"n, m= "; cin»n»m;cout«"Numar de ordine="; cin»nrord;if (nrord>comb(n,m)

{cout«"EROAREJ"; return 0; }cout«nrord«" ";

for (i=1; i<=rn; i++) / /determin cifra i{

j=c(i-1]+1;

/* incep determinarea de la valoarea imediaturmatOare valorii anterior determinate */

Wh1~e (nr+comb(n-j, m-i) <=nrord)/* cat timp numaru1 de combinari anterior

determinate + cea CUrenta nu a depasitnumarul de ordine dat */

(nr+=comb(n-j,m-i);//adaug la cele determinate cea curentaj++; } //si trec 1a urmatoarea

b) Pentrudeterminarea elementelor combinarii vom observa urmatoarele :- exista comb (n-j ,m-i) .submultimi en m elemente care.au :fixate primele i

elemente, en c[i-1}+1::;;j<c[il;- initial, c[OJ~O.

Pentru a determina combinarea al carei numar de ordine este dat vomcontorizacombinarile al carer numar de ordine nu-l -depaseste pe eel .dat. Pentruaceasta vomdetermina pentru fiecare pozitie i numarul de combinari cu primele i valori fixate care.impreuna cu cele detenninateanterior (initial 0), nu depasesc numarul de ordine dat ljiIe vom adauga la un contor nr. in momentul in care, pentru 0 anumita valoare a lui j,numarul de combinari adaugate la cele determinate anterior dep~eljtenumarul de ordinedat, Inseamna ca am determinat elementul j cautat in pozitia respectiva. Se trece apoi ladeterminarea urmatoarei valori, cautarea incepand de la valoarea j imediat superioaracelei determinate anterior.

Functia Comb () de calcul este aceeasi din programul precedent san poate fi imple­mentata iterativ.

#include <fstream.h>#inc1ude <stdlib.h>

I

PROGRAMAREA IN LIMBAJULCIC++ ',PENTRU LlCEU

if (m>n) %eturn 0;if ((m==O) I I (n==O) I I (n==m» %eturn 1;return comb(n-1, m)+ comb (n-1, m-1);

i.nt main ()tint i, j;cout«"n, m ="; cin»n»m;for (i=1; i<=m; i++) cin»c[i];for (i=1; i<=m; i++)//pentru fie care element al combinarii

1* numar cate combinari Lncep ell. valoristrict mai mici ca e1ementul respectiv */

#include <iostream.h>uns~gned ~ong c[20], n, m, nrord;uns~gned ~ong comb(uns~gned long n, uns~gne~ long m){

1r-:.34i'-

ni .'.,,

:.SoluJie! :a) Pentru determinareaformulei vom considera cazul particular n=7 , m=4lji vom observa'.J urmatoarele :

- exista comb (6, 3) -submultimi cn 4 elemente care incep en I, cele svaloriluateinconsiderare 1iind 2. 3. 4. S. 6, 7;exista comb (S, 3) submultimi eu 4 elemente care incep en 2. cele 5 valori luatein considerare fiind 3. 4. 5. 6. 7;

- exista comb ( 4 , 3) submulthni eu 4 elemente .care incep cu 3, cele 4 'valorl Iuatein considerare fiind 4, 5. 6, 7;exista comb (3, 3) submultimi CU 4 elemente care incep cu 4 .cele 3 valori luatein considerare fiind 5. 6. 7.

ri :

iJ

nl[j,

nr-t,

,...,, 'I ,: _J

ni

Partipile unei multtml

Pie n eN*. .Scrteti un program -recursiv caresa genereze toate partitiilemultimii {1,2, ... , n}.

137

~oid GenPartitie(int k)

{l*cand -apeLam GenPartitie{k), in -ve ctior-uLvp -pe -p.rdmeLe k-eL

pozitii ae afla 0 partitie a 1nultimii 1, 2, ._•. , k-r L£ormata din NC clase ~/

.:i.-£ (k-1==n) _Afisare (); //partitia este complet construita'_e~se

{//plasam elementul k in una tlintre clasele existente'for (int j=l; j<=nc; j++)

{P[k]-j;GenPartitie(k+1);}

//sau elementul k reprezinta 0 clasa separatanc++; /Imaresc numarul de claseP[kl=nc;GenPartitie(k+l);

nc--; } /Irestaurez numaz-uL de clase

ELEMENTEDECOMBINAWRIcA

int 'main () .{cout c-cvn« "; cin»n;GenParti tie (l) ;

fout.close(); return 0; }

Numarullui Stirling de speta a II-a

Numiirullui Stirling de speta a II-a este notal cu S (n, k) ~i reprezinta numarul de partitiiale unei muhimi eu n elemente in k elase. Nici ordinea claselor, niei ordinea elementelordintr-o clasa -nu conteaza.

Relatie de recurenja pentru numerelelui Stirling de speta a II-a

Bazandu-ne pe .algoritmul de generare a partijiilor unei multimi, prezentat anterior,putem deduce 0 relatie de recurenta pentrunumerele lui Stirling de speta a II-a. 0partitie a multimii {i , 2,. .. , n} in k clase se poate obtine :

- din orice partitie a multirnii {I, 2, ... , n-1} in k-1 elase la care se adauga 0 nouaclasa, fermata numai din elementul n ;

- din orice partitie a multimii {I, 2, ... ,' n-1} in k clase, inserand elementul n inoricare dintre cele k clase din aceasta partitie,

Obtinem relatia de recurenta :• S(n,k)=S{n-1,k-1)+k*S(n-1,k)• S(n,l)=S{n,n)=1.

elemente din multime

clase//numarul de//numarul de//partitia//numarul de partitii//fisierul de iesire

PROGRAMAREAIN LIMBAJUL' C/C++ PENTRU LICEU

c [ij=j; / /.am detectat -waLoaxee cautata 'oretin :sicou t c-cc [:i.l«, "; ./loa:fi:sez

cout«endli::return 0;

int nc;int P[30];

int NrP;

ofstream fout ("part. out") ;void Afisare ()

.I fout«"Partitia "«++NrP«": ";for (int j=l; j<=nc; j++)//afisez clasa nr. j

{fout«" r ";for (int i=l; i<=n; i++)

if (P[i]==j) f'ou t c-cLc-c ' I;

fout«I}'; }fout«endl; }

Reprezentarea informatiilorVom reprezenta 0. partitie printr-un vector p de dimensiune n, in care pentru fiecareelement din multimea {i , 2, ... , n} retin indicele c1asei din care face parte. Aceastiireprezentare asigura respectarea tuturor conditiilor din definitia partitiei.

#include <fstream.h>int n;

Definitie

Fie M 0 .multime nevida, S={Sl' 8 2, •. ', Sk} constituie 0. :partitiea multimii M.daca §inumai daca sunt indeplinite urmatoarele conditii :

1. 5,*0, V'ie{l, 2, ... , k} (clasele partitiei sunt nevide).2. 5,l>s;-0, V'i¢j; i, j Ell, 2, ... , k} (clasele partitiei sunt disjuncte),3. SlUS2U...USk=M (reuniunea claselor este egala eli intreaga multime),

De exemplu, pentru n=3, programul va afisa :

Partitia 1: {I 2 3}Partitia 2: {I 2} (3)Partitia 3: {I 3} {2}Partitia 4: {I} {2 3}Partitia 5: {I} {2} {3}

136

, 1

139

//fisierulde iesire

ELEMENTEDECOMBtNATORlCA

4finclude -<fstream.h>4fdefine DMax20:int n , m, f [DMax], _Tm [DMax] ,ofstreanf fout (" surj _. out") ;~o~d generare(~nt);

void afisare(void) ,.:int main (void)

cout«"n, m= "; cin»n»m,generare(O);fout.close(); xeturn 0; }

~o~d generare(int k)

/* cand apelam generare(k), elementele frO], f[I],f[k-I] sunt deja fixate */

(~nt j;

if (k==n)' afisare () ;-ef.ee / /continuam generarea£or (j=l; j<=m; j++)

(f[k]=j; //imaginea lui k va fi jIm[j]++; //numaram 0 noua aparitie a lui j in 1mgenerare (k+l) ;Im[j]--;}//restauram numarul de aparitii ale lui j

void afisare(void)lint i;

£or (i=l; i<=m; i++) //verific daca functia e surjectivaif (!lm£i]) return;

for (i=O; i<n; i++) fout«f[i]«' ';fout«endl;

Observatie

Numarul de functii surjective definite pe muljimea {i , 2 •... , n} eu valori in multimea{I. 2, ...• m} se noteaza cu Sj (nrm) §i este mt-a (n,m).

Orice functie surjectiva induce 0 partijie a multimii A in mclase, astfel: Ay={XEAIf (x) = y, YEB}. Existli m! posibilitati de a eticheta submuljimile partitiei, deciSj (n,m) =m!·S (n,m).

'domeniul functiei e.Daca Ja finalul ,generaruxm :are toate eomponentele nenule, atuncifuncpageneratli este surjectiva.

L' •S (n ,k) = - x}) -"I )k-r xc~ x r n

k! r~

PROGRAMAREAlN LIMBAJUL C1C+ ~~~~'..!rrcsu

Demonstratia -se poate face prin -inductie.matematica.

'8

rI !

i

i

Fie n, meN*, m::;;n. Scrieti un program care sa genereze toate functiile surjective definiter pe multimea {I, 2•... , n} ell valori in multimea {I, 2, ...• m}.l] Functia f :A->B se numeste surjectiva daca "'yEB. 3XEA. astfel incat f (x) =y. De

exemplu, pentru n=3 §i m=2, programul va genera:1 1 2 (adica f(l)=l, f(2)=1 Si f(3)=2)1 2 11 2 2

2 1 1212221

~

i : Generarea functiilor surjective~-j . .

Soliqie

n Reprezentam 0 funcjie printr-un vector f Cll n componente; f [ i) este elementul asociatLJ prin intermediul functiei f elementului i (\tiE{I, 2, "" n}).

Conditii interne,...,i ' 1. f l Ll E{l, 2, ''', m}, 'v'iE{l, 2, ... , n} (domeniul de valor! este {l, 2, ... , m]).I: 2. 'v'jE{l, 2, ... , m}, 3iE{1, 2, "', n} astfelinc~lf[il=j (functia este surjectiva).

n Numarul lui BellI1 .J

Numarul de partitii ale .unei multimi cu nelemente se noteaza B (n) §i se numestenumarul Iui Bell.I' Din definitia numerelor lui Stirling de speta a II-a, deducem ca :

B(n)=S(n,I)+S(n,2)+ ... +S(n,n); B(O)=1.

~

l

I Il J Exercitiun Pe baza -relatiei derecureni3. (demai -sus.zscrieti mn-program care -s~Ldetermine,numarul! i .de partitii .ale unei .multimi cu n -elemente;in k 'clase.L J .

ofOrmulii pentrunumerele lui Stifling .de speta .a II,(l

I Numerele lui .Srirling de speta.a Tl-a sunt descrise.de"formula:L j

! !

r-: . Pentru a testa eu usurinta daca functia este surjectiva vom utiliza un vector Ern cu mcomponente ; 1m[j] este numarul de aparitii ale lui j ca imagine a elementelor din

Reprezentarea informatiilor

Definitie

Partipileunui zmmar' natural

",

1i

-r,,....J

'-'

: :~

141.ELEMENTE DE COMBINA1ORlCA

~include <fstream.h>:int on, ValF,'p[50J;ofstream 'fout ("partnr. out") ;~oid Afisare(~nt ~g)

{ rcuc-ccnc 1,= I;

Ior Cint i=_l; i<lg; i++)£out«p[i]-«" + ·11;

fout«p flg] «endl; } I

void ConstrPart(~nt k)(//eandapelam, ConstrPart(k) am "fi-xat pel], p[2], ... , p[k-l]if (ValP==n) Afisare(k-l); Ilam obtinut 0 501utie

eel.se

£or (int i=p[k-l]; i<=n-ValP; i++){ plk]=i;

ValP+=i; IlmareseValP eu valoarea noului elementConstrFart(k+l); Ilapel reeursivValP-=i;}llrestaurez valoarea variabilei ValP

int main ()cout«"n= "; ein»n;p[O]=l; ConstrPart(l);fout.close(); %eturn 0;

Observatie

Notam CU P(n,k)numarul de partitii ale lui n in k parti. Numerele P(n,k) veriflcaurmatoarea relatie de Tecureni3- :

• P (n, 1) =P (n, n) =1;• P(n+k,k)=P(n,1)+P(n,2)+ ... +P(n,k).

Relatiile P (n, 1) =P (n, n)'=l sunt evidente. Sa conskleram multimea partitiilor numa­rului n in eel rnult k partl, al carer numar este P (n, 1) +P (n, 2) + ... +P (n, k) . Orlcepartitie a lui n in eel mult k plirli P" P" '''' p. (rn";k) poate fi pusa in corespondenjabijectiva cu 0 partitie a lui n+k in exact k parp: l+Pl' 1+P2' ...• l+Pm' I, I, ...• 1.astfel Incat surna contine exact k termeni.

,

Exercitiu

Pe baza relatiei de recurenta de mai SlIS. scrieti un program care sa determine numarulde partitiiale unui numar natura! dat,

i:f.

PROGRAMAREA iN LlMBAJUL C/C++ PENTRULICEU

Conditii interne

I. P Ii] e l i , 2, ... , n}, 'IIiE{l, 2, ... , k} (elemenlele partitiei sunr numere naturale

nenule, eel mult egale ell n).2. p[i]";p[i+1], 'IIiE{l, 2, "', k-1} (elemenlelepartilieisunt1nordinecresc~lOare).

3. p ]1 J +p [2] + ... +p I k] «n (suma elementelor partitiei trebuie s~ fie egala cu n),

Vom utiliza 0 variabila globala Val P in care vom redne permanent suma valorilorelementelor fixate in partitie. La adaugarea unui element in parritie, valoarea acestuia vafi adaugata la ValP. respectiv la eliminarea unui element din partitie, valoarea acestuiava fi scazuta din ValP.

Conform conditiei interne 2. candidatii pentru 0 pozitie k din partitie sunt numerelenaturale eel putin egale cu ultimul element plasat in partitie (p [k -1 ] ). Pentru ca aceastarelatie sa fie valabila pentru orice k (inclusiv pentru ke L), pe pozitia 0 vom piasa mitialvaloarea 1 (p 10] -1). Conform conditiei interne 3, candidatii pentru 0 pozitie k trebuiesa fie nurnere naturale care. adaugate la surna valorilor fixate deja in partipe, sa nudepaseasca pe n, deci trebuie sa fie eel mult egale cu n-valP. Utilizand aceste douaobservatii, deducem c~ multimea candidatilor posibili pentru pozitia k este {p Ik-1] , .. "

n-ValP}.

5=1+1+1+1+15=1+1+1+25=1+1+35=1+2+25=1+45=2+35-5

Vom reprezenta 0 partitie printr-un vector p ell maximum n componente, in care vornretine elementele partitiei, Pentru a nu genera de doua ori .aceeasi partitie (de exemplu,5=1+4 §i 5=4+1), convenim sa memoram in vectorul p elementele partitiei in ordinecrescatoare.

Numim partitie aunui numar natural nenul n unsistemcde,numere.naturale.nenule {Pl'

P2' ...• Pk} .astfel Incat Pl+P2+' . ·-+Pk=n.De exemplu, pentru n-5, programul va .afisa :

140

Fie :neN*.:5crieti .un program -care 'sa .afiseze .infi$ierul >tie -iesire partnr~ ou t toatel'artitiilenumaruIui .natural n .

-'

....,I 'I !I j 'Generare.de :paranteze

I !

l I voi.d Constructie (int k)Ilcand apelam Constructie(k), am fixat in sir k parantezen I {if (keeN) Iisirul de paranteze este complet

i i fout«s«endl;l.....J

al.se

n Fie -ne'N" mn numlir :par.·Sa -sescrie am program care :sa -genereze zoate.sirurile «ie nI ! -paranteze -rotnnde care :se mchid corect.," De,exemplu, pentru",-4, programubrl'i"eaza:

( 0 )~ 00IIj ReprezentareadnjormaJiilorr Vom nnemora un '§ir .de paranteze Intr-un vector s ell N componente care pot avea .doari ! valorile ; ("sau.,,) ".l _,l La fiecare -moment wom retine numarul total de -parantezedeschise (in -variabila

'global~ NO) §i numlirul total de paranteze Inchise (in variabila globala NI).

[] .Conditii internei tn final. ND=NI ,adicanumaruJ. total de paranteze inchise trebuie sa fie ega! ell

'" numarul total de paranteze descbise §i egal cu N /2 .Aceasta conditie nu este suficienta, Daca am considera numai .aeeasta conditie, §irul

ni) ( ( .ar rrebui sa fie corect, §i nu e. Pentru ca parantezele sa se inchida corect trebuie

,i ca in fiecare moment .numarul de paranteze descbise sa fie eel putin egal cu numarul deparanteze inchise. Pe.parcurs : NO"NI.

143IELEMENTE DE COMBINATORIC!\.

.:i.nt main (){cout-c ...·N= '.n; .cin»N;

Conatrr-uct.Le (0).;

fout. close, () ;return 0; }

Numararea '§irurllor

Numarul acestorsirurieste nenuldaca §i numai daca este mdeplinita conditia m=k.Numarul sirurilor care contin Iitera A de k ori, iar litera B .de m ori este :

Nr (k,m)'E: (m+k) ! I (m! x k ! ) =Comb (m+k, m)

Solupe

Sa sedeterminenumarulsirurilorformate din k litere A §i m litere Bcare au proprietatea :pentru orice l=i=m+k, .numarulde litere Bnu depaseste numarulde litere A in prefixul~iruluide lungime i.

unde cu Comb (n , m) .notam numarul de submultimi de m elemente ale unei multimi cu nelemente.

Dintre aceste siruri, vom .determina numarul §irurilorcare nu verifica proprietateaceruta,

Sa consideram s un §ir care contine litera A de k ori, litera B de m ori §i care nuverifica proprietatea ceruta. Exista in acest sir 0 pozitie 2p+l (P"o) aslfel tncatS [2p+11 =B, iarprefixui sirului s de lungime 2p contine p litere A §i p litere B. Vom.alege p minim cu aceastaproprietate §i transformam sirul 5 dupa cum urmeaza, Adaugampe prima pozitie 0 litera A. Se obtine .astfel un §ir format din m litere B §i k+l litere A,

iar prefixul de lungime 2p+2 alacestui sir contine un numar ega! de litere A §i B. Inprefixul de lungime 2p+2al sirului obtinut, schimbam litera A in litera B, iar litera B inlitera A. Prin aceasta transformare numarul total de litere A §i B nu se modifica, iar primalitera din sir esteacum B.

Prin aceste transformari asociem in mod biunivoc unui §ir care contine litera A de kori, litera B de mori §i care nu verifica proprietatea P un sir care contine litera A de k+ 1

ori, litera B de mori ~i care lncepe cu litera B. Adic~ numlirul §irurilor care contin literaA de k ori, litera B de m ori §i care nu verifica proprietatea Peste egal cu numarulsirurilor care contin litera A de k+ i. ori, Iitera B de m ori §i care incep cu litera B

(m-ck-t-L}.Suprimand prima litera din aceste siruri, objinem toate sirurile formate din m-l Iitere

B si k+l litere A. Numarul lor este Nr (k+l, m-l) =Cornb (m+k, rn-l) .Deci numarul sirurilor care contin litera A de k ori, litera B de rn ori §i satisfac

proprietatea ceruta este :

Cornb(m+k,rn)-Comb(rn+k,m-l)=Cornb(m+k,m)*(k-rn+l)/(k+l)

'PROGRAMAREA INLIMBAJUL C/C++PENTRU L1CEU

{ if (ND<N/2) /Ise mai pot deschide paranteze{s[k]=' (';ND++;constructie(k+l);NO--; )

if (NI<ND) lise poate inchide 0 paranteza{ s[k]=')'; NI++;

Constructie(k+l);NI--; }

#include <fstream.h>#define NMax 20

char s [NMax] ;..i.nt N, ND, NI;liND - numarul total de paranteze deschiseIINI - numarul total de paranteze inchiseofstream fout("sir.out");

1.42

ni .I :

r-i i

I "

r-t

I !

I ~

r

r:IL-l

"11L.J

I ,, '

lJ

I'i

Numarul.lui -Catalan

Daca in problema precedenta -yom avea k=m=n, .atunci .obtinem-problema parantezelor(sirurile -forrnate-din.n rperechi.de paranteze ronmde.care -seinchid corect).Numiiruhie-struri -formate .dia .n perechi -de paranteze 'ronmde -care ~seinchidcorectJienume§te

-numarul .lui Catalan-de ordin n si este :Catalan (n)=Comb(2n,n) I (n+l) ; Catalan{Ol=Catalan(~)=l

Observatie

Datorita modului .de -obtinere a -numerelor Catalan,prezentatin .solutia problemei-precedente,deducemun anod de calcul alnumerelor Catalan,bazat -pc triunghiulcombinarilor .al Iui Pascal. Catalan (n) se obtine din diferenta dintretermenul n -depelinia 2n a triunghiului lui Pascal ~i termenul din stanga sa :

Catalan (n) =Comb (2n,n)-Comb{2n,n-l)

Din formula care descrienumerele Catalan, putem deduce §i 0 relatie .de recurenta :

,-. Catalan (0)=1;• (n+2)Catalan(n+1)=(4n+2)Catalan(n),penttu n>O.

Conform formulei de mai sus. numerele lui Catalan constituie un §ir .de numerenaturalec pr'imii fermeni fiind: 1.1.2.5.14.42.132,429,1430.4862.16796,58786,208012,742900,2674440,9694845, ...

Numerele lui Catalan intervin in numeroase probleme de combinatorica. Amintimunele dintre cele mai cunoscute interpretari combinatorice ale numerelor lui Catalan.

1. Fie * 0 operatie binara neasociativa. In care moduri distincte poate fi parantezatliexpresia a 1 *a 2 * ... *an?Solutia acestei problerne a fost datil de matematieianul belgian Eugene CharlesCatalan. in 1838, §i este Catalan (n-1l.

2. Numlirul de posibilitati .de a trianguliza (partitiona ill triunghiuri) un poligon cu nvarfuri eu ajutorul a n- 3 diagonale care nu se intersecteaza (exceptand extremitatile)este Catalan (n-2).

3. Numarul de moduri in care 2n persoane asezate la 0 masa rotunda i§i pot strangemainile fua ca bratele lor sa se intersecteze este Catalan (n) .

4. Numarul de profiluri montane distincte care se pot desena ell ajutorul a n caractereI §i n caractere \. tara a cobori sub "nivelul marii" (linia orizontala care trece prinpunctulde plecare) este Catalan (n) •

5. Sa consideram0 tabla de sah de dimensiune (n+1) x (n +1) §i 0 piesa plasata initialIntr-un colt al tablei, Omutare consta in plasarea piesei in una dintre pozitiilealaturate (pe orizontalli sau verticals). Numarul de drumuri distincte de lungime 2npe care Ie poate striibate piesa din coltul initial in coltul opus, fua a interseetadiagonala principala. este Catalan (n) .

6. Numaml de permutliri ce se pot obpne ell ajutorul unei stive in care se introducsuccesiv numerele 1, 2, ... , n este Catalan"(n).

145ELEMENTE DE COMBINATORlcA

int n, m[NMax], s[NMax], uz[NMax], p;IJuz[i]=numarul curent de aparitii ale valorii i in sirul sofstream fout("permrep.out");

Fie n E N* §i un sir de n numere naturale ffi 1 • ffi 2 ••••• fin' Sa se genereze toate sirurile delungime p=m

1+ffi

2+ ... +rnn in care valoarea 1 sa apara de ffi 1 ori, valoarea 2 de ffi 2 brio ... ,

valoarea n sa apara de ron ori, Aceste siruri sunt denumite permutari cu repetitie.

Permutiiri eu repetitle

#include <fstream.h>#define NMax 20

Exercitiu

Scrieti un program care sa determine numarul lui Catalan de ordin n, pe baza formulelor'prezentate anterior, Observati eli pentruvalori mai mari ale lui n va fi necesara imple­mentarea operatiilor eu numere mari.

Soltqie

Vom utiliza un vector u z ell n componente, in care vom memora pentru fiecare valoareL (i = 1. 2•...• n) numarul de aparitii in sirul 5 construit pana la momentul curent. Vomgenera sirurile utilizand 0 functie recursiva gen (). ce are un singur parametru, k,indicand pozitia pana Ia care am generat sirul. La apelul gen (k) vom plasa pe pozitiak in sirul sorice valoare i = 1. 2, ... , n pentru care numarul curent de aparitii este maimie decat multiplicitatea. Dupa ce plasam valoarea i pe pozitia k, numarul curent deaparitii ale lui i in sirul s va creste. La revenirea dinapelul recurslv, restauram valoarealuiuz[i].

o<:Iltii-abordare recursiva

Slirevenimlaproblemaini\iaIli, problema parantezelor.(slideterminlimnumlirulde siruri-formate din n -perechi .de -paranteze.care -se-inchid corect).

Analizilnd 'Problema pentru -neL, 'obtinem-o -soluue, () ,l'entru n~2 -obtinemdouasolatii, () () '~i «(»).. .

Observam.ca orice-sir format din n -perechi .deparanteze care se i;nchidcorect -incepeell paranteza .deschisa ,§i exista 0 1'aranteza.inchisa .ce eorespunde .acestei parantezedeschise.

Deci sirul poate fi partitionat in doua secvenje sub forma: (XlY,_unde x este un sir.de k pereehi de paranteze care .se inchid corect•.iar Y este .un sir de n- k-1 perechi deparanteze ce'se Inchid corect (o-cc-cn). Deducem astfel urmatoarea formula de recurenta :

Catalan(n)=Catalan(O)*Catalan(n-l)+ Catalan (1) *Catalan(n-2)+Cata­lan(2)*Catalan(n-3)+ ... + Catalan{n-1)*Catalan(0)

PROGRAMAREA iNLIMBAJUL C/C++ :PENTRU LlCEU144

nNumarul lui Stirling de speta II. I

nObservatie . v •• • _ •

Pentru n, rolf ffi2•...• ron datto numarul de srrun de .lungime p-m1+m2+... +mn m carevaloarea 1 apare de ffi1 ori, valoarea 2 de m2 ori, ... , valoarea n de mn ori este :n p!

L j m1!xm2!x ••• xmn!

Numarul lui Stirling de speta I se noteaza s(n, m) ~i reprezmta numarul de permutari ale

n elementelor {L, 2, ... , n} ce contin exact m cicluri.i: Secventa (cl' c 2 ' ••• , c k) se numeste cicIu in permutarea p daca p (c l ) =c2 'L ...•

p (c 2 ) =c 3 ' •••• p (C k_1) =c k ' P (c k ) =c 1 •

Numerele lui Stirling de speta I satisfac relatia de recurenta :n· s(n, m)=(n-l) Xs(n, m)+s(n-l, m-L).; pentru msn ;i j. 5 (n, m) =0, pentru n<m.

147ELEMENTE DE COMBINATORlC!\

Fie neN*. .Scrieti un program -recursiv de -generare apermutiirilor de ordin n .ce nucontin-puncte fixe. Numim -punct fixal permutarfi p un element i e {L, 2, ... , n}-astfelineat p [i]=i.

Scrieti un program care sa determine numarul de permutari de ordin n rnra puncteflxe, bazat pe aceasta formula.

Fie neN* ~i x-cy ; x, y e j t , 2, ... , n}. Scrieti un program recursiv de generare apermutarilor de ordin n care nu admit inversiunea (y, x) (adica x este intotdeauna plasatinaintea lui y).

void GenPermutari(int k)

I*cand apelam functia GenPermutari cu parametrul k

pozi tiile 1, 2, ... , k-l din vectorul p sunt fixate* I(if (k-l==n) Iisolutia este completa

Afisare(); Ilprelucrarea solutiei consta in afisare

e1se Ilcontinuam generarea'//determin candidatii pentru pozitia k

£or (int i=l; i<=n: i++)

if (!uz[iJ s s i!=k)

{p[kl=i: uz[i]=l:

/*i este un candidat r deoarece nu este

imaginea nici unui alt element fixat*/

GenPermutari (k+l): Ilapel recursivuz[i]=O:}

.ElementulnlJoate formasingur cel de-al m-lea ciclu.sau poate fi inserat in unul dintreciclurileformatecu celelallen -elemente (inn moduri posibile).

lnversiune

Aplicatii

Exercitiu

Demonstrati cii numarul de permutari de ordin n tara puncte fixe este :

n!'(l-..!:..+..!:.._..!:... +... +(-l)"JI! 2! 3! n!

l'ermutiirifiiiii -punctefixe

sotutieVommodifica functia degenerare a permutarilor impunand ~i conditia interna : p [ i ] :;i:i,

pentru lIie{l. 2 ..... n},

int main ()

{int i;

cout«"n="; cin»n;cout«"Multiplicitatile: ";for (i=l; i<=n; i++)

{cin»m[i]; p+=m[i];}

gen(l) ;

fout. close () ;return 0; )

'Void gem (.intk)/ /cand -apelam gen (k), -am fixat -e.LementieLe cs {J.] -r _ .• _" s[:k"':J.]

{:i..nt ,i;:if (k==p+J.) / /solutia -es t;e .ccmp.Le t.a

{£or (i=l; i<=p; i++)fout«s lLl c I I;

fout«endl; },e1.se /Icontinuamgenerarea£or (i=l; i<=n; i++)

if (uz[i]<rn[i])

/* numarulcurent de apari tii .a Le -valorii iestemai mic decat .multiplicitatea lui i -*j

{s[kl=i;

uz [i]++;

gen(k+l);uz[i]--; }

PROGRAMAREA.iN LIMBAJUL -C/C++ iPENTRU LICEU146

i i

L j

r

~,: !c ,

r:it ;

Ii, I

l !

I, ,, ,L"

~I ., .LJ

nc J

IiI IiJ

n_f

.campion, 2005

Soldati

Exercitiu

Determinati numarulde permutari de ordin n care nuadmit inversiunea (y, x),

149ELEMENTEDE COMBINAIDRIcA

.campton, 2003

Fie neN*. Scrieti un program care sa determine nusiarul de numere naturale de exact ncifre care nu contin nici un grup de trei cifre alaturate identice.

De exemplu, pentru n=4, solutia este 8829,

)

cout«ml[k]«endl;return 0; }

}

"for (j=2; j<=k; j++) ml[j]=m2[j];

for (j=2; j<=k; j++)m2[j 1=j *ml [j ] ;if (i-j+l<=O) continue;m2[j]+=(i-j+l)*ml[j-1];

Numere

ml[O]~ml[l)~m2[1]~1;

for (i=2; i<=n; i++)

~include <fstream.h>~define NMax 101int n, k;~ong int ml [NMaxl, m2 {NMax];

int main (){into s., . j;cout«"n, k= "; c i.nco-nc-c-ks

'Pentru .implementare, vom .utiliza .doi vectori, ml :§i .m2 ,In vectorulrnl vorn retinesolupile~delapasul precedent, iarin vectorul rn2 vom calculasolutiilede la pasul curent,Mai exact.Ja pasul L, rnl [j rreprezinta numarul de permutari de ordin i-I cu j secventemonotone, -iar in m2[j jse calculeazanumarul .de-permutari de ordin i cu j secventemonotone. Pentru valori marl ale lui n , este necesara implementarea operatiilor eunumere mario

.2,Inseramvaloarea n intr-o permutare de .ordin n-1 cecontine k-.1 .secvente monotone.jn acest-caz, waloarea ntrebuie $3.:genereze 0 znouasecventa mcnotona. Acest Iucruae reahzeaza daca n -este mseratin orieare dintre.celelalte n-k+ 1 pozitii (deci oricare-pozitieexceprand cele kdeJa punctull), «leoarece secventa monotona existenta va fi.•.rupta" dn.altedouasecvente, .mai mici. 'ExistA-M (n-d , k-1.) x (n-k+l )-posibilitati.Thtalizand, '. obtinem arrmatoarea relaue .de recurenta :'M(nrk)=kXM(n-lrk)+(n-k+~)XM(n-lrk-l~

i++)

(! uz [i])

if (i==y && uz [xl I [ i! =y)(p[k]=i; uz[i]=1;

GenPermutari(k+l);uz[i]=O; )

PROGRAMAREklN LIMBAJUL C/C++ :PENTRU UCEU

if

Un copil are n soldati de jucarie, avand inaItimi distincte, cuprinse intre 1 ~i n. Zi de zitcapilul aranjeaza cei n soldati in linie, -astfel tncat sa existe k secvente monotone inaranjare. 0 secventa monotona este un sir de soldati aflati pe pozitii consecutive, .astfelincat inaltimea· fiecarui soldat, mai putin primul din secventa, sa fie mai mare deditinaltimea soldatului aflat in stanga lui, secventa fiind maximala cu aceasta proprietate(adlca nu poate fi adaugat in secventa soldatul urmaror sau soldatul precedent Si ordineacrescaroare a tnaltimilor sa se pastreze).

De exernplu, pentru n=5,aranjarea 3 5 1 2 4 este fermata din doua secventemonotone. 3 5 Si 1 2 4 •

Scrieti un program care Sa determine, pentru n Si k date, numarul de araajariposibile. .

De exemplu, pentru n=3 ~i k=2, solutia este 4. Cele 4 aranjamente cu 2 secventemonotonesunt: 132,213.23 1§i3 1 2.

Solutie

Problema cere, de fapt, determinarea numarului de permutari de ordin n care contin ksecvente monotone crescatoare (sa not3.m M(n, k} acest numar). Pentru a obtine 0 astfelde secventa se poate proceda astfel :1. Inseram valoarea n. trur-o permutare de ordin n-1 ce contine k secvente monotone,

Pentru a pastra numarul de secvente monotone, acest lucru se poate realiza in kmoduri (valoarea n este plasata Ia sfarsitul oricareia dintre cele k secvente monotoneexistente). Exista astfel M (n-1, k) xk postbilltatt.

148

Soliqie

Vom -modifica programul.de-geaerare -a-permutarilor :adaugand.-o.conditie :internA -:supli­-menrara :valoarea y poate fiplasataJnvectorul p daca-simumai daca valoarea x-este-dejaplasata. .

~ -void GenPermutari (int k)

I(i:f (k-l==n) .Afisare();

. ,el.se

~or (inti=l;i<=n;

I,,!!

151

10r (i=2; i<=n: i++){aux=D;

D= (D+ID)'*9;

.ID=aux; )

cout«O+IO«endl:xeturn 0;

ELEMENTE DE COMBINATORIC!.

Vom numi varf 0 pozitie in care se gaseste 0 persoana mai in varsta plasata intre douapersoane mai tinere.

Sanotam cu N r (n , i) numarul de posibilitati de a aranja n persoane la masa. astfelincAtsa existe exact i vArfuri.

Solutia problemei va fi Nr (n, 0) +Nr (n,l) + ... +Nr (n, k).

In primul fand, sa observmn ca Nr (n, i) =0, pentru i>n/2.De asemenea, Nr (n, 0) =0 (pentru cli orice -aranjare contine cel putin un varf.

generat de persoana cea mai in varsta).Pentru a obpne 0 aranjare la masa a eelor n persoane avand exaet i vArfuri putem

proceda in unul dintre unnatoarele dona moduri :1. Adaugam persoana n la a aranjare a primelor n-1 persoane care contine i vArfuri. in

acest caz. persoana n trebuie sa fie 3.$ezata astfel iDcat sa nu genereze un nou varf.Acest lucm se realizeaza asezand persoana n langa nnw dintre vfufuri. Mai exact,daca pozipa j este un v3rt' (x

j_1<Xj<xj +) , atunci persoana n poate fi plasatii inainte

san dupa Xj . Se oblin astfel, 2*i*Nr (n-1, i) posibilitati de a construi 0 aranjare aprimelor n persoane en i varfuri.

Soliqie

Cu ocazia implinirii uneifrumoase varste, Vasile pregateste a masamare. la care ii invitape cei n .apropiati .ai saL· Masa este circulara, Invitatii stau de jur tmprejur, la distanteegale -unul.de .altul, singura problema este .aranjarea lor. Se stie ca cei batrani sunt maipretentiosi, mai pisalogi si mai 'influenti. Pentru a evita conflictele intre generatii ~i

supararea eelor batrani, Vasile vrea sa .aiba cat mai putini batrani asezati intre douapersoane mai tinere. E clar ca nu se pot evita complet astfel de situatii, doar daca Vasilear invitapersoane de aceeasi varsta:, ceea ce .nu este cazul. Invitatii lui Vasile au varstedistincte doua cate doua, astfel ca Vasile i-a numerotatde la 1 la n in ordinea strictcrescatoare a varstelor,

Scrieti un program care-sa determine numarul de posibilitati dearanjare a celor n

invitati, 'astfel incat sa existe eel mult k persoane mai in varsta asezate intre doi vecinimai tineri. Nu se considera diferite aranjarile obtinute prin permutiiri circulare san prinschimbarea sensului de parcurgere (deci 1 2 3 4 este aceeasi aranjare cu 2 3 4 1 Sicu 1 4 3 2).

De exemplu, pentru n=5 Si k=2, solutia este 12.

.campion, 2004

Aniversare

PROGRAMAREA iNLIMBAJUL C/C++ PENTRUUCEU

0=-:9; 10=0;

#include <iostream.h>i.nt main ()tint n, i:

10ng int 0, IO, aux;cout«"n="; cin»n:

Pentru valori mari ale lui n este necesara implementarea operatiilor ell numere mari.

Valorile de initializare sunt :". D ( 1 ) = 9 (pentru ca numarul nu poate incepe cu cifra 0) ;• I D (1 ) = a (pentru ca nu putem avea dona eifre identice).

Adaugand 0 cifra la sfarsitul unui numar eu n-l cifre ce nu 'contine nici un grup ~de

3 cifre identice §i care se termina cu dona cifre identice (acest lueru se poate realizain 9 moduri, pentru ca 1a sfarsitul numlirului exista 9 cifre care pot fi adaugate), inacest mod se obtin numai numere de n cifre care au ultimele doua cifre distincte.Se obtine .astfel urmatoarca relatie de recurenta :• ID(n)=D(n-1);• D(n)=g*ID(n-1)+9*O(n-1).

J50

nI..d!il

nII I I't _I I~

rLi

rI ILj

r! !

rIi

IiLJ 2.

1n una! Nr In) <Ld (n) +D In) •Revenind, -un numar ·de n cifre care nu contlne niciun grup .de 'trei cifre alaturatenidentice se poate obtine in unul dintre urmatoarele.dou~moduri : .

LJ 1. Adaugand 0 cifra la sfarsitul unui numar cu n-l.cifrece nu ccntine nici un grup detrei cifre identice §i care se termina cu dona cifre .distincte (acest Iucru -se poaterealiza in 10 moduri, pentru ca la sfarsitul numarului exista 10 cifre care pot fiadaugate). Una dintre cele 10 cifre adaugate este egala cu ultima cifra a numarului den-1 cifre de la care am plecat, deci ea va genera un numar eu n cifre in care ultimeledoua cifre sunt identice. Celelalte 9 cifre VOl' genera numere de n cifre in careultimele doua cifre sunt distincte.

"l ~

LJ

r1 '• ~ Solulie

:Samotam cu Nr (n) mumarnl rlenumere:tiaturalene>exact:ncifrecare mutContinmci am"""1: -grupde :trei .cifre -2li1turatelidentice.L i 'Un astfelde ammar se -poate .obtine .adaugand ,0cifrHa:s!'l\qitul amui numarcu n-l

• -cifre.caremu 'Continenici amgrup.de-trei cifreadentice. ;Prin:adAugareauneiasttel-de.cifre,Ja .sfarsitul noului numar -s-arputea formao gmpare.de-trei citre ddentice ,(daclUasfu§itulr: numaruluiIde n -1 .cifre-exista doua c1frejdentice:§iadaugam"o.cifra-egalacu 'aces tea).

l ,j Deci ~trebuie':sa-studiem,doua'tipuri -detnumere : -numere -pentru 'care .ultimele .douacifre -sunt ddenticesi .numere -pentru care ailtimele doua ·eifre sunt-distincte.

r- 'Sa -notam eu :! . Id (n) - .numarulde numere naturale de exact n eifrecenu contin nici ungrup de treiiJ cifre .alaturate .identice.veare au ultimele .doua cifre identice ;

D (n) - .numarul -de .numere naturale de -exact n cifrece nu contin nici un grupde treicifre .alaturate identice, care au ultimele doua cifre .distincte.

~---

Ture

Sa consioeram 0 tabla de sah mai speciala, cu n linii §i m coloane. Incate moduri pot fiasezate pe tabla k ture astfel tncat sa nu se atace ? Doua ture se ataca daca sunt plasatepe aceeasi linie sau pe aceeasi coloana.

2. Adiiugfun.persoana n -Ia 0 .aranjare,a:primelorn-1.;persoanecarecontine i -lv.3rfuri. In.acestcaz, _persoana n trebuie sii,generezeu.m:mouvarf, -decimu'P0ate'fi plasatamule2*( i--l) .pozipi-dinvecmatatea vArfurilor:existente. ':Seobpn3Stfel (n-l-2* (i-,'1.) )*

Nr (n-l, i-l) .posibtlitari de a construi io aranjarea pnmelor o persoane cu i 'VArfuri.

;;....;

153

11

4

1

3

6

2

3

4

11

1

ELEMENTE DE COMBINAIDRlCA

Observati ca pe linia i in triunghiul lui Pascal se gasesc combinarile de k elementeale multimii {i , 2, ''', I} {k variind de la 0 la L),

·Pentru a rezolvaproblema nu esre necesar sa retinem intr-o matrice triunghiul luiPascal in intregime, este suficient sa retinem la fiecare pas i numai linia curenta ~i ceaprecedenta,pe care 0 vom utiliza pentru determinarea liniei eurente.

Pentru valori mariale lui n §i meste necesara implementarea operatiilor pe numere mario

#include <fstream.h>int n, ffi, k ;uns~qned ~onq LNou[50l, LVechi[50);

.int main (){couti-ccvn , m, k= "i c Lncc-nco-mcc-k rint i, j, aux;uns'i.gned ~ong f=1, cmk;//calculam factorialulfor (i=l; i<=k; i++) f*=i;//calculam combinarileLNou[O)=LVechi[O]=l;.if (n<m)

{aux=ni n=m; m=aux;}for (i=1; i<=n; i++)

{for (j=1; j<=i; j++)LNou[j]=LVechi[j) ~ LVechi[j-1);

for (j=1; j<=i; j++)LVechi[j]=LNou[j];

.if (i==m)cmk=LNou [k) ;

cout«f*cmk*LNou(k] «endl;-return 0;

fl plasata1'e k-2 coloane (oricare dintre eele k coloane, exceptand coloanelepe care suntplasate tureledin prima, .respectiv.a doualinie selectata), $.a.m.d. Dedueem ca numarul.de posibilitiiti -dea aseza kture care sa nu se atace pe cele k2 pozitii este k l .

Prinurmare, numarultotalde posibilitati .este k! x Comb (n, k) xcomb (m, k) .Pentru .acalcula ·combinarile :::vom .utihza urmatoarea formula de recurenta :

Comb (n, k)=Comb (n-l,k) +Comb (n-l,k-1). .Fonnula·stii Ia bazaalgoritmului de calcul.al combinarilor cunoscut sub denumirea de

triunghiul lui Pascal, De exemplu, triunghiullui Pascal pentru neS este:1

1 1

i++) sum+=Nrl[i];i<=k;i=2;

cin»n»k;k= ";

sum;

'PROGRAMAREA -iN LIMBAJUL CtC++ PENTRU LlCEU

i<=n; i++)(j=l; j<=k; j++)Nr2[j]=Nrl[j]*2*j+Nrl[j-ll*(i+1-2*j);(j~l; j<~k; j++) Nrl[jJ~Nr2[j];for

Nrl (1) =1;for (i=4;

(for

return 0;

}

for (sum=Nrl[l],cout«sum«endl;

int main ()lint L, j,

cout«"n,

#include <iostream.h>10ng int Nrl[lOO), Nr2[lOO];

Soliqie

Pozltia unei ture este identificatii prin indicele liniei §i eel al coloanei pe care se afla turn.Cei k indici ai liniilor pe care se afla ture pot fi selectati in Comb (n , k) moduri. Cei k

indiei ai coloanelor pe care pot fi plasate ture pot fi selectati in Comb (m, k) moduri.In total, exista Comb (n, k) xComb (m, k) posibilitati,La intersectia acestor Comb (n, k) linii Cll cele Comb (In, k) coloane se afla k2 pozitii.

Tura de pe prima linie selecrara poate fiasezata pe oricare dintre cele k coloane selectate.'Iura de pe eea de a doua linie selectata poate fi asezata pe k-l coloane (oricare dintrecele k, mai putin cea pe care este plasata prima tura), Tura de pe cea de a treia linie poate

-TotalizAnd,.objinem.urmatoarea relape-de recurenta :Nr(n,i)=2*i'*Nr(n-l,i)+(n+l-Z*i)'*Nr(n-l,i-l)

Pentruimplementare, vom utilizadoivectori, Nrl--~i NrZ.Lapasul p• .in.Nrl lLl ise.afla numarul de aranjari ale p-l persoane ell i varfuri, jar in Nr2 l.Ll -se .calculeazanumarul .de aranjari .ale p persoane cu i varfuri.

Pentru valori mart.ale lui n , este necesara implementarea operatiilor pe numeremari.

152

~I;'nt n , k;

Ii

II~

I~!

Permutdri cu Jc inversiuni

i.nt main ()

{i.nt i, j;

P (n,k)= !p(n-l,k-x+l)

'"'

#include <iostream.h>int n, k;

10ng i.nt pl[40], p2(40];

.'J(!;~W~jl:Il!.\ ,:1

i{~~ ~I:,lfi!1flf i!!~f ~1111~: 'I~i 1 i •

:'11P/ ~11"~II' IIi :.G~:; ! ~l 'I,It,!~,!, •

li?~ff~I;:1ip.j, "'.

'1~'I':';j" '1Ili~'I.,~I: j,

l'i'I"ll'T<I'I "',, ,,',; Ii:f~'[ ' iliJil~ '~'

11~l:'~1:11}~~lrl' 'I','~' "I";'1 ~'" ""'fll' ,l1~;111!~1~

'1'1~"II'I'I'1,1'llt~li~~~,;ij:"[~S.illl!~1

!'~~i IJ~ : ,q ,liT1i~~~r,Ilnll:"l,I"Ifd'\I!~.~ ,Ilf,I,,,,,i~".~t!\i: :' " ";li~'IlI'1'11!~~:I\i~':{

Il ' I ' : ~ i ' ii I',."II'!II,,·,'ll!-'h"'li';'

l'~il,'~!~~

II"I:!:!I'I'"'f?~:11 ;,~I1

11'11:''''"1'P",I ~

~2'ii'i~':Ij­Ij~t~I~~~:ijl'1

! ; I' H r l : ]~ I~"11"11 I'~h ~b!\1'!til~W~:M)1t:i':r~'i('J,,~Wr:~~tl~)i'll,1,.o[J!,.""n~t~:{~{i·rNlu~:\~,~~;!f:iii;!QI 'l'il:~\la:!'ii((, '

1, :~1~1~),I ! i i ('jl :[,,; ,,.;

":"il:I!~~'il'/ilj:(iii::'·,11ii[tii~t~N~:f!'1!'ili't1fl'

1:11:1!'/;:,i:II'i:!>~;:i' :,:'

I"\'f'!i~.liJI

!;!ti1f:: ,

ISSELEMENTE DE COMBINAIDRlcA

cout«"n= .n; cin»n;cout«"k= 'n; cin»k;

:for (j=l;j<=i* (i-I) /2; j++) I

p2 [j ]=p2 [j -1] - (j -n>0?p1 [j-n] : 0) +p1 [j] ;£or (j=1; j<~i*(i-1)/2; j++) p1[jJ~p2[j];

)

cout«p2[k]«endl;%eturn 0; }

p1 [O]~p2 [O]~l;

£or (i=2; i<=n; i++)

Deci. 51=5-i*x i -j *xj+i *xj+j *xi=s- (i:-j) * (Xi -x j) .

Prin urmare. vom opera in permutarea identidi anumite inversiuni. pentru a obtinesuma dorita. Sa notam eu Inv (n) ansamblul de inversiuni in care. prin sehimbiirisueeesive de pozipe, elementul de pe prima pozitie ajunge pe pozitia n.

De exemplu. daea x=(I. 2•...• n). Ansamblul de inversiuni Inv (n) eonstii in:

2 1 3 n

2 3 1 n

Pentru a obtine surna maxima Srnax=1 *1+2*2+ ... -t-n e n , (Xl' X 2' ... , X n) trebuie sa fiepermutarea identica (1.2, .•.• n). Pentru a obtine suma minima Smin=1*n+2* (n-

1) + ...+n*l, (Xl' X 2' ...• Xn) trebuiesa fie permutarea eu nUIIl3.r maxim de inversiuni (n, ...•2. 1). Daca S>Smax sau s-csms.n, atunci problema nu are solutie,

Daca problema are solutie, se pleaca de la permutarea identica. Observam ca oriceinversiune micsoreaza valoarea sumei corespunzatoare permutarii. Sa notam eu S surnacorespunzatoare permutarii curente, iar eu S 1 suma corespunzatoare permutarii obtinuteprin intersehimbarea lui Xi eu x

j(eu i<j).

S=l *x l +2*x2+ i *x i + +j *x j+ .•. +n*xn

S1=1 *x1+2*x2+ i *xj+

+j *x i +... +n*xn

Soliqie

Baraj de selectie a lotului national, Bacau, 2001

Potrivire

Se considera doua numerenatura1e n (3';n';1000) ~i 8 (0<8';333834000). Determinatinumerele distincte x" x" ... , x, apartinand multimii {1, 2, .,., n}, astfel incat1*x

1+:i-tx2+ ...+n*xn=s. Daca nu exista solutie, se va afisa vaIoarea o.

De exemplu, pentru n~4 \~i 8=26 0 solutie posibila este (3, 2, 1, 4),penlru eli1*3+2*2+3*1+4*4=26.

Exercitiu

Serieti un program care sa genereze toate permutarile de ordin n ee au exact k inversiuni.

PROGRAMAREA iN LIMBAJUL C/C++ PENTRU UCEU

Deci, P (n, k) =P (n, k-1) -P (n-1, k-n) +P (n-1, k).Aceasta observatie conduce la redueerea complexitatii aIgoritmului eu un ordin demarime.Pentru valori mari ale lui n este necesara implementarea operatiilor pe numeremari.

Pentru a calcula solutia utilizand aceasta relatie de recurenta vom face doua observatiicare vor optimiza implementarea:1. Pentru a caleula numarul de permutari de ordln n eu k inversiuni este necesar sa

cunoastem numai numarul de permutart de ordin n-1 ell k-x-1 inversiuni (1:::;x:S;n).

Prin urmare, nu este necesara utilizarea unei matrice, sunt suficienti doi vectori. invectorul p1 vom reline valorile pentru pasul n-a , iar in vectorol p2 vom calculavalorile pentru pasul n.

2. Observam ca P (n,~) ~i P (n, k-1) se calculeaza din dona surne foarte asemanatoare :

P(n,k-1)=P(n-l,k-l)+P(n-l,k-2)+ ... +P{n-1,k-n+l)+P(n-l,k-n)

P(n,k)=P(n-l,k)+P(n-l,k-l)+ ... +P(n-l,k-n+2)+P(n-l,k-n+l)

SoluJieSa notam ell P (n, k)numaruI de perrnutari de ordin n care au .exact k inversiuni.Cazurile elementare sunt :

• P (n, 0) = 1 (permutarea identica) ;-. P (n, x) =0, pentru x<O san pentru xo-nx (n-l) /2.

o permutare de ordin n poate sa tnceapa eu orice valoare l's;x::;;n. Valoarea x plasatape prima pozitie asigura x-l inversiuni. Prin urmare, ultimele n-l elemente dinpermutare trebuie sa cantina k-x+l inversiuni.

Deducem formula de recurenta :

IS4

Fie n, keN*, k~nx (n-l) /2 . .Scrieti unprogram care sa determine numarul de permutari.de ordin n ·ce au exact k -inversiuni. Be -nume§te inversiune o pereche l::;;i<j::;;n,:astfeltacat Pi>P j ,

De exemplu, pentru n~3 ~i k~O solutio este 1 (permutareaidentica 1 2 3).Pentru n=4 §i k=2 exista 5 solutii.

n! !t._.J

r-:

Il j

L_j

r

nI

r',

nu

rI 'I I, ,L ,

r

I:

rL~

IiI IL j

i. ,

rI IL-l

IiU

nI

n! !

n--:..~;

#include <fstrearn.h>i.nt pllODl];

10ng Dr sn, Sf D;

157

q,p

ELEMENTE DE COMBINA1DRlCA

2Iwitch (D)

{case 1: Lnve r sea t.r jz j , .break:

case 2: inversez (1,·2); inversez (3, 4); -break;case 3: inversez(1,2); inversez(2,3); break:case -4: inversez (1,3); break;

·case 5: inversez(1,3);inversez(3,A);inverSez(4,2); .break;case 6: inv~rsez (1,2) ; inversez (2;'3) ; inversez (~, 4),. .break;case 7: inversez(I,2); .inversez(2,3); inversez(3,4);

invex:sez (1,2); break;caSe 8: i n versez(1,3); inversez(2,4); break;case 9: i nversez(1,4); break;

case lO:inversez(1,4); inversez(2,3); break;

£or (i=1: i<-sn; i++) cout«p[i]«" "; cout«endl;return 0;

Vizibil

Fi§ierul de intrare vizibil. in contine pe prima linie numerele naturale nseparate prin cate un spatiu,

Pentru un sir xl' x2 '" •••• xnspunem ca elementul xk este vizibil din stanga daca, pentruorice L, 15;i<k, avem Xl~Xk' Analog, spunem ca xkeste vizibil din dreapta daca, pentruorice.L, k<i:S;n, avem Xi<Xk(primul element se considera vizibil din stanga, iar ultimuldin dreapta),

Cerinui

Consideram permutarile multimii {I, 2•...• n}. Determinati cate dintre aceste permutari.au p elemente vizibile din stanga §i q elemente vizibile din dreapta.

Date de intrare

Date de iesire

Fi§ierul de iestre vizibil. out va contine pe prima linie numarul permut3.rilor careindeplinesc conditia din enunt, modulo 997.

vizibil.in IViZibil.out /EXPlicape

4 2 3 3 Permutarile ell dona elemente vizibile din stangaIi trei vizibile din dreapta sunt (1, 4,3,2), (2, 4,3,1), (3, 4, 2, 1).

OlimpiadaNationala de Informatica, Galati, 2005

Exemplu

Restrictii si preciziiri

• 2<n<lOl• O<p, q;S;:n

'PROGRAMAREA -iN LIMBAJUL C/C++ PENTRU LlCEU

Ii .Invershmlle1 (1, 2);

2 (1,2) ; (3,4) ;

3 (1,2) ; (2,31 ;

4 (l, 3);

5 (1,3) ; (3,4) ; (4,2) ;

6 (1,2) ; (2,3) ; (3, 4) ;

7 (1,2) ; (2,3) ; (3,4) ; (1,2) ;

8 (1,3) ; (2,4) ;

9 (1,4) ;

10 (1,4) ; (2,31

156

sn=n:whil.e (n>4)

{if (n* (n-1) /2<=D){ D-=n* (n-l) /2;

"for (i=1: i<n: i++) Lnver se a (i, i+l):

void inversez(int if int j){i.nt aux=p[i]; p[i]=p[j]; p[j]=au.x;int main (){int i;

cout«"n, S=": cin»n»S://construiesc permutarea identicafor (i=1: i<=n: i++) p[i]=i:

if ( S>n* (n+1) * (2*n+l) /6 11 S<n* (n:t-1) * (n+2) /6)//nu exista solutie

{cout«O«endl:return 0: }

D=n*(n+1)*(2*n+1)/6-S;

~2 3 4 _•• _.n L

Dupa efectuarea..ansamblului Inv (n) , avemo -scadere a sumci calculate eu:Dif (n) =1+2+..•.+n-l.

Sa -notam D=Smax- S.Trebuiesa operam inversiuni-Inpermutarea ddentica,pan3. cand..,...acoperim't-diferenta D.

Prin urmare, -cat timp n>4.'daca D>Dif (n) ,operamtoate inversiunilernv (n), Dscade.cu Dif (n) '§i ndevine n-l.

In final, -valoarea ramasa l'entru D este eel-mutt 10 Ii 'intentionam sa 0 obtinemdinpermutarea elementelor (1, 2, 3, 4). In functie de valoarea lui D, inversiunile ce trebuiesa fie operate sunt:

159

void Determinare_Combinari(){long C [NMax] ;irit i, j;

C[O]=Comb[O]=C[1]=1;

for (i=2; i<n; i++)for (j'=1; j<i; j++) Comb[jJ=(C[j]+C[j-1])%Mod;

Comb[iJ=l;for (j=1; j<=i; j++) C[j]=Comb[j]; }

void Afisare (){FILE * fout = fopen (OutFile, "W");

fprintf (fout, "%d\n"l rez);fclose (fout) ;

void Determinare_S(){int L, j;

s[1][1]=1;

£or (i=2; i<ni i++)s[i] [1]=(5[i-1] [1]*(i-1» % Mod;

for (i:2; i<n; i++)

£or (j=2; j<=i; j++)s[i] [j]=(s[i-1] [j-1]+(i-1)*s[i-1] [j])%Mod;

Elementele multimii x sunt denumite expresii corect parantezate.

ELEMENTE DE COMBINAlORICA

if (p==l)rez=s[n-l] [q-l];·elsej,.-£ {q==l} "rez=s[n-],] [p-l]:

,else

£or (k=p; k<=n-q+l; k++)rez= (rez+s [k-l'] [p-l] *s [n-k] [q-1] *Comb [k-1] ) %Mod;

.Afisare () ; I

:return 0; }

void Citire (){FILE * fin = fopen (InFil'e'l '''r") i

fscanf (.r.tn , "%d %d %d" I s n , &p, &q);

fclose(fin);

Expresii

Fie x multimea definita dupli urmatoarele reguii :- sirul vid apartine muljimii x ;- daca A ~i B apartin multimii x, atunci sirurile (A) ~i AB apartin multimii x.

PROGRAMAREA IN LIMBAJUL C/C++PENTRU LICEU

1009 s[NMax] [NMax):100q Comb[NMax], rez:void Citire(void):void Afisare(void):vo~d Determinare_Combinari{void):void Determinare_S(void):·int n , PI q:int main (void)(~nt k;Citire () ;Determinare_Combinari();Determinare_S();

, ,'"~58!,-

I J

n: !

r.

iI

,'Solutie

r4n primul rand, sli observam eli daca-inlocuim multimea {1,.2, ,00 0' n} cuoricemulume! cu n-elementedistincte~numarul de solutii ramane acelasi.l.J Vorn determinamaiintAinumarul.s al permutarilor multimii {I, 2, ... , -n] careaun,p

p elemente vizibile din .stanga,'1 Observam eli 0 .astfelde .permutarepoate fioblinutli plasand elementul 1 -pe prima, pozitie a unei permutari .a elementelor {2. 3, ... ,n} ell p-l elemente vizibile in stangai '(exista sn_l,p_l astfel ,de -permutari) san Inserand .elemenrul 1 pe pozitiile 2, -3••••• n ale

unei permutari a elementelor {2,3, ...• n} ell p elemente vizibilein stanga (exista Sn_l,p

rr'astfel de -permutari). Obtinem urmatoarea relatie de recurenja :I I\:- Sn.p=Sn_l,p_l+ (n-l) xSn_1,p;

• 5 n • n=1; 8 n,o=0; Sn,p=O, pentru p>n.

~ Evident sn,p .reprezinta §i numarul permutarilor multimii {I, -2, ~ ..• n} careaupI ! elemente vizibile din dreapta.1; Sa consideram 0 permutare eu p elemente vizibile din stanga §i q .elemente vizibile

din dreapta. Sa notam eu m pozitia elementului maxim (n} in permutare.n Elementul maxim este vizibil §i din stanga, §i din dreapta. Deci elementele de pel ~pozitiile 1. 2, ... , m-l trebuie sa formeze 0 permutare a unei multimi ell m-l'elemente,

dintre eare p-l vizibile din stanga, Elementele de pe pozitiile m+l, m+2 •...• n trebuie~sa formeze 0 pennutare a unei multimi ell n-m elemente, dintre care q-l vizibile din

ndreapta. Elementele din stanga pot fi alese in Comb(n-l/m-l) (combinari de n-1t .I elemente luate cate m-l) moduri.

Exista Comb(n-1,m-1)*Sm_l, p_l*sn_m,q_l permutari ell p elemente vizibile din,...,., stanga §i q elemente vizibile din dreapta, in care elementul n este pe pozitia m,i Numarul total de permutari cu p elemente vizibile din stanga §i q elemente vizibile, ; din clreapta se obtine insumand aceste valori pentru orice p~~n-q+1.

#include <stdio.h>#define NMax 101#define Mod 997#define InFile "vizibil. in"#define OutFile "vizibil.out"

ni I, ,

-., '

ni'

n

In total :

161

3

(1,2,3)

int main ()

{cout«"n, d= "; cin»n»d;cout«nr(n, d)«endl; :return 0; }

uns~gned ~on9nr(in~_n,. int d)tint i, _j,n!, d1, k.;

unsigned ~on9 s;f[OJ [OJ-1;

£or (1=2; i<=n;i+=2)£or (j=i/2; j>O; j--)

{f[iJ [jJ-£[i-2J [j-1J;

£or (n1=i-2; n1>=2; n1-=2)

{s=O;

.for (k=O; k<i::::j; k++) s+=£[i-n1] [k];

f[i] [jJ+=s*f{nl-2J [j-1);

£or (d1-j-1; d1>0; d1--)

f[iJ [j]+=fJ[nl-2] [d1-1J*f[i-n1] [jJ;

ELEMENTE DE COMBlNA1ORICX

}

:return £ [n] (d] ;

Nr. de ordineSubmultimea

Pentru a acorda corect §ieficient bonusul, Gigel trebuie sa implementeze doua operatii :1. datil fiind a submultime, sa determioe numarul ei de ordine ;2. dat fiind un numar de ordine, Sa determioe submultimea corespunzatoare.

Scrieti un program care Sa implementeze pentru Gigel cele doua operatii.

Date de intrare

Fisierul de intrare bonus. in contine :pe prima linie, numarul natural n ;

- pe a dona linie, un numar natural m, reprezentand numarul de operatii executate ;

Gigel este programator amator, dar Weo designer profesionist. Acum proiecteaza unmagazin virtual ·§i se confrunta eu 0 problema de programare. Pe site sunt prezentate nproduse, numerotate de la 1 la n , in cosul de cumpararuri virtual, un client poate alegeorice submultime de produse dintre cele n . tn functie de componenta cosului decumparaturi, Gigel trebuie Sa ofere un bonus.

Gigel a observat ca se pot forma din cele n produse 2"-1 submultimi distincte nevide.A ordonat submultimile lexicografic §i a asociat apoi ftecarei submultimi un numar deordine de la 1 la 2"-1.

De exemplu, pentru n=3 submultimile nevide in ordine lexicografica sunt :

Bonus

PROGRAMAREA iN LIMBAJUL C/C++ 'PENTRU LICEU

3. concatenand un sir de lungime n - n 1 (pentru orlce n 1 E {2. . .. , n - 2}) §i adancime dell un §ir de lungime nl-2 §i adancime strict mai mica decat d-l incadrat intreparanteze rotunde; numarul desolutii care se pot obtine in acest mod este:

Sa notam ell f(n,d) numarul de expresii coreet parantezate de lungime n §i adancime d.In primui rand, observam ca f(n,d) = 0 pentru orice n impar.

Daca n este par, 0::::2, putem construi un sir de lungime n si adancime din unul dintreunnatoarele moduri :1. incadrand intre paranteze rotunde un sir de lungime n-2 siadancime d-1 (acest lueru

se poate realiza in f(n-2,d-1) moduri);· '2. fncadrand intre paranteze rotunde un sir de lungime nl-2 (pentru orice n1e{2, ...•

n-2}) §i adancime d-1 (acest lucru se poate realiza in f (nl-2,d-1) moduri) §iconcatenandu-l cu un sir de lungime n-n1 §i adancime k (pentru orice Jc.::;;d);numarul de solutii ee se pot obtine in aeest mod este :

Soliqie

. {O daca expresia E este vidaD(E)= l+D(A) . daca expresiaE=(A)undeAeX

max{D (A),D (Bn .-dacli expresia E =ABunde A, BE x

Scrieti un program care sa .determine .numarul de expresiicorect parantezate delungime n ~i adancime d (1::::;;n~39, O<d<20).

De exemplu, pentru 0=6 ~i d=2 solutia este 3. Celetrei expresii corect parantezate delungime 6 §i .adancime 2 sunt : «() () , ,() ( () §i ( t ) () ) •

Olimpiada.de Informatica.a Tarilor Baltice, 1999

e-a d-l

2:: 2::f (nl-2,d1-1)xf (n -n1,d)nl~2dl~1

n-2 d

2:: (f (nl-2,d -l)x 2::f (n -n1 ,k»nl~2 k~O

n~ d

f(n,d)~f(n-2,d-1)+ 2::(f(nl-2,d-1)X ll(n-n1,k) )+nl~2 k~O

n-2 d-l

2:: 2:: f (nl-2,d1-1)x£ (n-n1,d»,,1~2 dl_l

160

De exemplu, '§irurile () ( () ) () ,§i r o ( () ) )sunt -expresii.corect parantezate., Sirurile «()) «() §i () «() nu suntcorect parantezate.

Fie z 0 expresie.corect -parantezatii. Lungimea.expresiei E -este .egala eu mumarul de

-parantezedin aceasta expresie. Adancimea'expresieiE-(notata D(E» este definitadupacum .urmeaza :

I #include <£stream.h>

'. ~nsigned ~on9 £(38J [19];

J.nt fi, d;

n Date .de iesire

i. J Fisierulde desire bonu s •out va contine m linii, cate una pentru fiecare operatiedinfisierul de intrare. Pe fiecare Iinie va fi scris rezultatulunei operatii, inordinea in care

~ operatiile apar in fisierul de mtrare. Daca operatia este de tip I, in fisierul de iesire va! : fi afisat numlirulde ordine al .submultimii specificate in operatie, Daca operatia este deL.l tip 2, in fisierul de ie§ire vorfiafi§ateelementelesubmultimii cu numarul de ordine

specificat, separateprin spatii, :in ordine crescatoare.

Aceasta este 0 problema de ordonare a unor configuratii : se considers toate submultimile.--, multimii {1, 2, "" n} in ordine lexicograficli ~i se cere Sa determinJim numarul deIl I ordine al unei submultimi date,respectiv submultimea cn numarul de ordine dat.

I Vom citi fisierul de intrare §i pentru fiecare operatie din fisierul de intrare vom apelafunctia care realizeaza operatia respectlva : detsubm () determina submultimea cu

n numarul de ordine dat, iar detnr () determina numarul de ordine at unei submultimi1 ! date.L. .....; ,Submultimile vor fi reprezentateprin vector ca:racteristie (un vector s ell n eompo-

nente 0 sau 1; s [i I ~1, daca i aparPue 'submulpmii, ~i 0, altfel).II Pentru a determina numRrul de ordine atunei submultimi, analizlm elementele carelJ apartin submulpmii.

,

I Restrictiij

• 1.:s::n.:s::30~ . l,;m,;10001 ', ,, ,

L, Exemple

n bonus.in

1 , 3: 1 3

2

n 3I 1 1l.J 223

2

r 7: I\ ... j

oSoliqie

pentru fiecare <>peratieurmea2ain .fisiercate ,doua linii ;pe prima liniedintreceledoua estescristipul operatiei (1 .sau 2) ;dacli 'tipul operatiei este 1, atunci pe ceade.a .doua linie este -scris ammarul-de .elemente -din.submultimev-urmat .de .elementele.submultimii, separate -prin spatii ; .dacatipuloperatieieste 2, pe cea de .a.doua linie-va fi scris un numlir,de<>rdine(adichm numar natural cuprins.intre ~§i 2"-l),

:;1,

IIIi::::

iii"

!'!

,Ii'H

:Ii

iii,

:'!';l::i

,\'.'

ii::I~

ii!'"

i'.'i[;1'Ii

i:,;'1\

""1.1~" -IIt-i:,

I~!,'~jf~1!"I

'IiItl,ip':lili!!.!i'i;J,!['I'!ii!:

!J1"

1:i1[i~~,jt;'f!l1\':1;iJI

'I~!!!,iiii.~!~I

~~:r:i

:jiif'I"!'

':'1

1

\1,:; '

',l:

163ELEMENTEDE COMBINATORlCA

void detsubm(void);~ong detnr(void);

#include <stdio.h>.fI:define InFile "bonus. in"*define OutFile "bonus.out"#define NMax 35

int main (){long- int m, i, j;.i.nt tip, a;

fincofopen (InFile, "r"); fout=fopen (OutFile, "w");

fscanf(fin, "%d" , &n); fscanf{fin, l1%ld" , &m);for (j=l; j<=m; j++)

(

fscanf(fin,"%d",&tip);for (i=O; i<=n; i++) s[i]=O;:if (tip-~1)

{

fscanf (fin, U%d", &x);

for (i=O; i<x; i++){fscanf(fin, "%d", &a); s[a)=l;}

nr=detnr () ;fprintf(fout, U%ld\n l1

, nr);}

FI~E *fin, *fout;·int,.n, X;

ints [NMax] ;

l.ong i.nt nr;

Bxista 2" submultimi .alemultimii {I, 2, _.", n} (inclusiv .multimea vida). Dintre.acestea, jumatate continper , jumlitatenu'continpe 1.

Deci.sdaca .e ri J~O .(adicli. :1mu'apartlne -submultimii), atune! mumarul de ordinealsubmultimii va creste cu .2n

-1 (deoarece -submultimeanoastra .se ,gase~te -In eea ,de a

doua jumatatej.caltfel va .ereste cu 1 (pozitia curentli).ElintinliID pe 1 ~hi,man 2"-'submultimicdintre care jumatate contin -pe 2, jumatate nu contin pe 2, Mal exact, lapasulpas (pas = 1,2, ... , n)"daciLs [pas }~o"atuncinumlirul deordineal submultimii-va.creste eu ~n-pas, .aItfelva.creste eu 1.

Pentru .a .determina submultimea, atunei cand este eunoseut numarul ei de ordine,-vomrationa Intr-un mod analogv Daca numaruldeordine.al submultimii estemai maredeeat2 n- pas (unde pas -variazli .de la 1 la n}, .atunci elementul pas nu apartinesubmultimii (§i pentru a analiza mai departe scadem din numarul de ordine al submultimiipe 2"-P.'), altfel apartine submultimii (deci s [pas} -1 ~i scadem 1 din numarul deordineal submultimii).

]'>3

')j

Olimpiada Municipalli de Informatica, Jast, 2004

bonus.out1 2 36

3

PROGRAMAREAIN UMBAJUL C/C++ PENTRU UCEU162

nI ', IlJ

t ij

:"1, II J

"i !

~! i1'.;

1:::

Probleme propuse

2. Generare de numereSe cere determinarea tuturor numerclor formate din cifre aflate 'In ordine strict

crescatoare, cifre alese dintr-o. multime eu k cifre distinete date. De exemplu, pentru

Bacalaureat,2003

Bacalaureat,'.august2003

Slmulars'bacalaureat.2004

d) 4924

5. Lista de cuvlnteSe citestede la tastatura un cuvant c, cuvant format din n litere .

• d x • di lexi aft x man (n';;15).Presu.punan ca. sunt generate m or me cxicogr ca (ordinea de diel· "). 1 di . , I' di uI . ' ronar toatecuvmtee lsunctecesepot.lonnacuexactn itere m m timea{A D M oj· .

·ft • d x aftx . ' , , ,saseseneun program care ven ea aca C se <1 sau nu pnntre cuvintels gener te . A

afirmativ, afiseaza al catelea este In listli. a ~l, III cazSe va afisa -pe ecran mesajul NU daca c nu se afla printre cuvintele gen te D •

. '1· fiseaza mesaiul era.acacse afla pnntre cuvmte e generate, se a seaza mesaju DA, urmat pe ran'dul x d' urmator, enumarul cerut.

De exempluv pentru c=ADA se vor afisa pe ecran Iiniile :DA5Se observa eli sirul citit are trei litere. Succesiunea de cuvinte fOrmat . I·

. . { }. fl ' di I . e cu trei rteredin multimea A, D, M. 0 , cuvmte a ate m or me eXlcografica este· AA' . A, MD,AAM, AAO, -ADA, ADD, ADM, ADO, AMA, AMD, AMM, AMO, AOA A

D . fl~ A • 1 de cuvi ,OD, AOM,AOO, DAA, DAD, DAM etc. eCI ADA se a .a m srru e cuvmte §i este a1 cincilea.

Bacalaureat august 20026. Numarul de ordine alunui element al produsului canezian '

F~e neN* §i AI' A2, ,.•• ' An ~ multimi cu Ll' L2, .•. , respectiv Ln

elemente. Saconsideram elementele prudusului cartezian Al xA 2x ••. XA in ord,'ne lexi fi •

A • n cogra lea,primul element avand numarul de ordine o.

a) Dat fiind keN*, 16L 1xL2,x ... xLn • sa.se determine al k-lea element a1 d uluiI di I' fiX pro us Ulcartezian A

1xA2 x... xAn n or me exicogra led.

4. Generare,de'numerecu cifredateCineva doreste sa obtina §i sa prelucreze toate numerele formate din trei 'fie di

• x· di , el Cl m.sirul 2. 9, 4§11e genereaza exact m or mea: 222, 229, 224, 292. 299, 294, 242,249,244,922,929",924,992, 999. 99.4.~94~, 949, ~44, 422. 429, 424, 492, 499,494,. ~ 42, 449, 444. Daca doreste sa obtina pnn acelasi procedeu numerele formatedin4 cifre, -atunci dupa numarul 4944 'va urma :a) 4422 b) 4949 e) 9222

3. SportiviSe eere determinarea tuturor modalitatilor distincte -de ,~ezare in Ihn ..

. .. d . P bl te liival tli e a nsportrviaflatI lao festivitate e premiere. ' ro ema es ec en eu generarea .. .

a) submultimilor uneimultimi eu n obiecte c) partitiilor unei multimi de n obiecteb) aranjamentelorde nobieete luate cate .i d) pennutlirilor de n obiecte

·ELEMENTE·DE COMBINATORIC;'165

.cifre alese -din .multimea {I, 5.·2} -seobtin numerelen , 2, J. 2' 5 a sdi )·Pr bl hival tli '" 25 125 (nu:neapmatin aceastaor me. 0 ema -esteec en cu generarea , '

.a) submultimilornevide ale unei mulpmie) pennUtlirilor de k bi. d bi I te .. djparti iil 0 iecteb).aranJamentelor, e1.0·o iectetua cate k . partiti oruneimullimi

~1.

!:'PROGRAMAREA.iNLIMBAJUL C/C++PENTRU UCEU

~ong .de t.nz- (voj.d)

{~ong nro=O, gasit=O::i.nt pas:

£or <'(pas=l; pas<=n .&& gasi t<x: pas,++)if (!s[pas]) nro+=ll«n-pas:

>e~se

{nro++: gasit++:}.return nro;

eJ.se{fscanf (fin, '''%ld'', .&nr);

:detsubm () ;

£or(i=l; ~<=n;i++)

j,:£ (s [i]) -fprintf {-fout,'"-%d U,i)-j

fprintf (fout,."\n ft ) ; }

IcYose(fin): fclose(fout)::return 0; }

Bacalaureat special. 2004

void detsubm(void){i-nt pas=O;

whi.~e (nr)

{

pas++:,

if (nr<=11«n-pas){s[pas]=l: nr--;}el.se{nr-=11«n-pas:}

1. Gilte submultimi ?Un elev genereaza submultimile multimii {I, 2, 5, 6, 9}. Cate submultimi care

contin elementul 2 _lji nu contin elementul 6 a generat?aj s b)6 e)16 d)7

164

b) Dat fiindunelement al produsului cartezianA1XA2)(~.~XAn~,'Sa aedetermine mrmarulsao de ordine,

11.Submuttimi cu suma elementelor limitatdFie n, meN*. m.$n. Scrieti un program care, sa afiseze toate submultimile de m

elemente ale multimii {I, 2•...• n}, astfel meat suma elementelor din orice submultimesa nu depaseasca 0 valoare data VMax.

10. Permutdri fara piurate

Fie neN*. Scrieji un program recursiv de generare a permutarilor de ordin n, pentrucare punctele de coordonate (i, p {L) ) ~i (j, p (j») nu constituie colturile opuse ale unuipatrat, vs. j e{l, 2, ...• n}.

9. Permutdri cu secvenja fixata

Fie n, x, yeN*. l~x<y.$n. Scrieti un program recursiv de generare a permutarilorde ordin n pentru care valorile x , x-l-I •...• y sunt plasate in pozitii consecutive.Determinati 0 formula pentru numarul de solutii.

i:,i'''III,',~:

~'i':w:

:~d~,

:,,'.,;',

ii,'

:::!,'

rI·:!~

I'F'

~'I

I!W

'j'::i:'.

Mii

~1:!~1!:

~;:I~;~i\li:

:~!iirij'i.~ ,II

11

:]~i:~i,''I~!:~':(c;

167ELEMENTE TIE COMBINAIDRIcA

16. Compunere de permutariFie n un numar natural nenul, n$;l 0o. Care permutari de ordin n au proprietatea

pop=e (unde e reprezinta permutarea identica, iar operatia a -reprezintli compunereafunctiilor) ?

Date de ·ie§ire

Prima linie a fi§ierului de ie§ire hotel. out va contine numarul de modalitiiti.Stiind di 0 culoare este codificatii printr-un numar natural nenul mai mie san ega! ell

k. in fisier se va serie pe ~ate 0 linie (incepand cu a doua) eodul unei perso~e §i euloarea

17. Gradul unei permutariFie I1 un numar natural nenul §i p 0 permurare de dimensiune n. Se numeste grad al

permutariip eel maimic numar 'natural x cu proprietatea.ca pX=e (prin pX tntelegandpopop...op , p compus cu el insusi de x ori). Scrieti un program care sa determine gradulunei permutari date.

15. Numararea functiilor. surjectiveFie n §i s doua numere naturale. Sa se determine numarul de funcjii surjective

f:{1,2, •.•• n} ..... (-1.O.1} cuproprielatea: If(l} 1+lf(2) !+ .•• +If(n) l e s .De exemplu, pentru n=5 §i 5=3 exista 60 de solutii.

18. Hotellnrr-un hotel exista n angajati in Departamentul administrativ. Patronul hotelului

hotara§te sa schimbe costumele personalului din acest departament astfel tncar angajajiicare lucreaza la etaje diferite sa fie imbracati in haine colorate diferit, iar cei carelucreaza la acelasi etaj sa fie imbracati in haine colorate la fel. Angajatii au asociat uncod unie (un numar natural de maximum patru cifre).

Sa se determine 0 modalitate dealegere a culorilor costumelor care sa respecteconditiile de mai sus. precum §i numarul de modalitati.

Date de intrare

Fisierul de intrare hotel. in are urmatoarea structura : e-pe prima linie se afla doua numere natur~e. n §i k. separate printr-un spatin (k estenumarul de culori) ;

- pe fiecare dintre urm~toarele n linii se afl~ cate dou~ numere naturale separateprintr-un spaliu, primul fiind codul, iar al doilea, etajul asociat angajatului.

14. Cutii'Sa consideram p cutii, -numerotatede Ja "11a p,'~§i n obiecte, 'numerctate.de la t Ia n ,

.Scrieti un 'program -care::a.) sadetermine in catc moduri distincte pot fi plasate cele n obiecte in cele.p cutii, -astfel

incat:in cutia 1 saseafle ffi1obiecte, in cutia 2 sase afle ec obiecte•... , iar in cutiap:sa fie plasate rnp obiecte (m1+m2+ ...+rnp=n);'

b) ·S~ genereze toate modalitatile dearanjare a celor n obiecte in cele p cutii, respectandconditia de la punctul a.

Bacalaureat, iunie 1999

PROGRAMAREA __iN LlMBAJUL C/C++.PENTRU LICEU1<;6

8. Dlferenlli intre veciniSe citeste de latastatura un numar natural n (n:>2 0) ~i un numar natural v. Scrieli un

program care afiseaza toate numerele de la 1 la n in toate modurile posibile, astfel incAtintre oricare doua numere afisate in pozitiiinvecinatediferenta in modul sa fie maimaredecat valoarea data v , Datele de ie§iresevorscrie in fi§ierul.iesire. dat. In cazul inearenu exista solutie, in fisierul de ieslrese va scrie Nu -exds t.a solutie. De exemplu,daca n=4 §i v=l, rezuItatuI din fisierul de 'iesire va fi :

2 4 1 3

3 1 4 2

7. CuvinteFie n eN*. 'Sa consideram toate .cuvintele de Jungime n-care pot.:fi -'formate.cu :litere

mici ale alfabetului, in ordine Jexicografica.·a) Dat fiind keN*, sase determineal x-lea cuvant m ordine Iexicografica,b) Dat fiind un cuvant,sa,-sedeterminenumhu!san'de.online.

12. Echipe

Intr-o clasa de n elevi sunt f fete (n, feN*. f.$n). Fetele sunt numerotate de la 1la f. iar baietii de la f+l Ia n . Afi§ap toate echipele care se pot consntui din p elevi,dintre care m fete (P. ffieN*, rn:5:p.$n. m.$f).

13. Partilit cu parIi prime distincte

Fie neN*. Scrieti un program care sa afi§eze.toate posibilitlitile de a-I serle pe n casuma de numere prime distincte. De exemplu. pentru n=10. se va afi§a:

10=2+3+510=3+7

r

r

iiIL..,

i j

r1

t. __:

i !

L 1

r1

i! ;

i :

r: i, ,

1 J

r-:,i

r::,L :

r,,

L:

Ii

L..•

r1

l..i

,, ~

r,

,,,~

"iii

1"1I ,I ,

rrlil~~I

r"'l

~~i!I_T\ 1\

~'.1!;1'\ 'ii )~

169

/\/\/ \ /\/\/\

+-++-- +-+-+-

ELEMENTE'DE COMBINATORIc}.

/\/\/ \

++-+--

/\/ \/\++--+-

24. CulmiLui Gigel Ii place sa se joace cu numerele. De data .asta, el se joaca numai eu

numerele +1 ~i -1. EI pune pe hartie, unuI dupa altul, n numere +1 §i n numere -1. darare grija ca, oricum ar aduna numere consecutive pornind de la primul numar pus pehartie, sa nu ob\inli. 0 suma negativa, Apoi, Gigel figureazli numarul +1 prin /, iarnumarul -1 prin \ §i obtine niste desene interesante. Astfel, penlru n-3, configuratiilecorecte ~i desenele pe care Ie obtine Gigel arata in felul urmator :

/\/ \

/ \+++---

21..Permutari cu YOcicluri .Fie n, --meN*-. .Scrieti un-program'recursiv degenerare a permutarilor de ordin n care

contin -exactm ·cicluri.De-exemplu.cpermutarea (5,.2,7,3, 4, ~,6) contine .doua cicluri ::un ciclu -de Jungime 1: 2;.un ciclu de lungime 6: .i , 5, 4, ,3, '7, 6 .

Pentru n=4 ·,§i m=2 programulva 'genera:

1231 3 22132313 1 23 2 1

(+ - +1; - - -1)

Barajde selectle a lotului national de informatica, Constanta, 2000

23. DescompuneriFie numerele naturale nenule n , k §i x (n:::;;350). Numim k-descompunere a lui n un

sir strict crescator de k -numere naturale nenule, a carer suma este n. Dintre toatek-descompunerile lui n, sa sedetennine in cate apare x .

De exemplu, pentru 'n=12, k=3 §i x=2, solutia este 3. Cele trei s-descompunert alelui 12 care il contin pe 2 sunt 1+2+9; 2+3+7; 12=2+4+6.

Baraj de selecjie a lotului, Bacau, 2001

22. ParanteziiriSe considera ~irurile formate .din n (n:::;;30) perechide -paranteze rotunde care se

inchid corect, in' ordine Iexicografica, stiind ca " (" este mai mica decat ") ",Dandu-se un sir de paranteze, se cere sa se determine nUII1aruI lui -de ordine, stiind

ca prima configuratie « ( : . . ( () ) ... ) » are numarul de online 1.

~~.

'.

.campion, 2q05

Olimpiada Nationala de Informatica, Braila, 2002

hotel.out60l23 135 2430 113 3

hotel.outo

PROGRAMAREA iNUMBAJULC/C++'PENTRU J.;1CEU

hotel.in4 5123 235 1430 213 0

168

hotel.in5 212 113 014 110 211 0

19. CombinareSe dan M numere naturale ell ·valori cuprinse intrc 0 si 127. Dintre ele, se selecteaza

N numere. Numerele selectate formeaza 0 N-combinare. Dona n-combinari difera fntreele daca lji numai daca intr-una dintre ele exista un numar care apare de mai multe oridecat in cealalta,

Scrieti un program care calculeaza catc N-combinari exista pentru cele Mnumeredate.

De exemplu, pentru M=6 §i N=2 si eele M numerei 1 1 2 2 3, solutia este 5.

costumului, valori'separateprincate -unspanu.Drdinea.descrierern f1§ierulde desire -vafi aceeasicu -cea .din 'fisierul zle mtrare.

Restrictii si preciriiri• -l;S;n;S;1000

• 'Numarul deetaje din hoteleste .cel mult:200 .(lS}C;200).··.Daca exista mai multe .solutii.cseva .afisa una singura... Daca nu exista solutii, dn fisier se -va.scrie o singura .Iinie .care -va contine o.

Exemple

20. CinemaUn grup de n prieteni se due la cinema. Ei si-au cumparat bilete pe randul 17,

persoana i avand loeul eu numarul i. Ajungand dupa inceputul filmuluiv.ei se 3.§:az3. laIntamplare pe randul 17. Fiecare dintre cei n prieteni considers ca loeul de pe biletul saueste eel mai bun, asa ca fieeare doreste sa ajunga pe loeul sau, Pentru a nu deranja restulspeetatorilor ei se horarasc ca in fiecare minut, mai multe perechi de persoane sa-stschimbe locurile intre ele. La fieeare minut, numarul de schimbari de locuri poate fioricat de mare, tnsa 0 persoana nu poate participa decat la 0 singura astfel de schimbare,Aflati numarul minim de minute necesare pentru ea fiecare persoana sa ajunga pe loeulsau, precum ~i perechile de persoane care i~i schimba locurile la fiecare minut.

~:,

RestrictielS'k::;;n:~::a00

Evident, configuratia :/\

/ \\/

++---+nueste corecta.rdeoarece la un moment ,dat .suma devine-l.

Gigel. observn faptul ca .aceste desene seamana ell niste .munti si, mai mult, observaca 'numarul-de -varfurl .ale .."IDunplor".difera : unii au un varf,alpiau .doua varfuri, iar.altii chiar trei. Un varf de munte are forma 1\.

Pentru valorile n ~i k date, determinati capdintre "muntii" corect formati cu n semneI §i n semne \ .au exact k verfuri.

Date de intrareFisierul de intrare culmi. Ln-contine pe prima linie valorile n §i k separate printr-unspatiu. .

Date de iesireFisterul de iesire culmi. out va contine pe prima linie numarul de munti corect formati,eare au exact k varfuri.

25. CarliUn raft al bibliotecii din Colegiul National "Radu Greceanu" contine mai multe cfuti

de informatica. Bibliotecarul acestei institutii are un mod special de eodificare a cartilorde pe acest raft. Mai exact, fiecare carte are asociat un numar natural i E {1, 2, ... , p}.Doua dirti identice au asociat acelasi numar natural. Fieeare numar din multimea{1, 2, ... , p} este asociat macar unei 'carti,

Cunoscand pentru fiecare numar i E { 1, 2, ... , p} care carti au asociat numarul L, seeere sa se determine numarul de modalitati distincte de asezare a cartilor pe raft, astfeltncat pentru oriee carte diferenta dintre numarul asociat ei si eel al cartii de dupa ea estemai mica sau egala eu un numar natural dat d.

Date de intrare

Fisierul carti. in contine pe prima linie numerele naturale p ~i d separate printr-unspatiu. Pe cea de a doua linie se afla p numere naturale n

1, n

2, ••• , n

peu semnificatia :

"n i este numarul de carti (identice) care au asociat numarul i, i E {I, 2, ... , p}".

t71

....

valoarea de pe pozitia i din b-siro11o1oo

i (in baza 2)o11011100101110

carti.out IEXPU~ie

1 Dlntre modalitlilile posibile de asezare, (1,1,1,2),(1,1,2,1), (1,2,1,1), (2,1,1,1), doar prima indeplinesteconditia problemei.

"Iabara de pregatire a lorului nattonal de informatica, Slatina, 2003

Explicatii privind obtinerea b-sir-ului :

i (in baza 10)o123456

carti.in

2 03 1

ELEMENTEDE COMBINAWRICA

Exemplu

Date .de iesire

:in fi§ierul carti. aut se :aflA,pe prima Iinie, numarul cerut de problema,

Restrictii

.. l-s-p:S:l5

'. OS'dS'15.• l:S;n

1, n

2, ~ •• , n

p:S25

26. B-§irSe da un numar natural N. Definim un b-sir de lungime N ca fiind sirul xc' xl'

X N_ 1 -.unde:

_ { 1, daca i are ~ numar impar de biti egali eu 1 10 reprezentare binara ;

Xi~ 0,.daca L are un numar par de biti egali cu 1 in reprezentare binara.

Deexemplu, pentru N=7 obtinem urmatorul b-sir de lungime 7: 0110100

Cerintd

Determinati numarul M de secvente palindromice de lungime eel putin 2, dintr-un b-sirde lungime N.

Date de intrare

Fisierul de intrare bsir. in contine pe prima linie numarul natural N.

Date de iesire

Fisierul de iesire bsir. out va contine M modulo 30103 (restul Impartirii lui M la30103).

PROGRAMAREA.i:N LIMBAJUL C/C++PENTRU .LICEU

'Iabara de pregatire a lotului national de informatica, Sibiu, 2005

culmi.out3

culmi.in3 2

Exemplu

170

nI .1 ,

rl. ...i

[ ;

r-!, ,l ,

r

rI ,L;

r::: .

rII I1.1

nI iI I

r1 Il I

r! Iej

:l1 1

~

I I

:I

r-

Restrictiisi precizari.. _2:S:N.:~::a·olB.;

.• .gecventa 'Xi' X i +1, -••. , .xj_1,X j 'se numeste palindromicadaca 'Xi=X j ' :Xi+1=Xj _1, ~~.

'PROGRAMA:REAIN LIMBAJULCIC++PENTRULICEU

Olimpiada Nationala .de Informatica;' Galati. 2005

1::J

~r 1'1lllrJ

11~1.1"1 :

1

II '

;'If'~I!ilflrj~!i I~~!' :111r'1'1"

I'!'i~ :1~ ,I I:~~i I~~~

~i~r:

I

li,1 :~!:, i!!!~lHt

i!'j:ill'j:1,1; 11:',

Programarea dinamica este 0 metoda de elaborare a algoritmilor ce se aplica in generalproblemelor pentru care se cere determinarea unui optim in urma adoptarii unor decizii.

Nu exista uncriteriu pe baza caruia sa identificam 0 problema pentru rezolvareacareia trebuie sa utilizam metoda progremarii dinamice, dar putem formula dona pro­prietati care sugereaza o solutie prin programare dinamica.

'. Substructurd optimaliiProblema data poate fi descompusa in subprobleme §i solutia optima a problemei

depinde de solutiile optimeale snbproblemelor sale.Acest criteriu nu indica neaparar 0 solutie prin programare dinamica, ar putea fi ~i un

indiciu c§. se poate aplica metoda Greedy sau metoda Divide et impera.

-e " Subprobleme superpozabileSubproblemele problemei date nu sunt 'mdependente, ci se suprapun.Deoarece subproblemele problemei date se suprapun, deducem ca 0 abordare prin

metoda Divide et impera ar fi dezastruoasa din punctul de vedere al timpului de executie(din cauza faptului ca problemele se suprapun se ajunge la rezolvarea repetata a aceleiasisubprobleme). Prin urmare, Yom rezolva subproblemele 0 singura, data, retinand rezulta­tele Imr-o structura de date suplimentara (de obicei un tablou).

Rezolvarea unei probleme prin programare dinamica presupune urmatorn pasi :

1. Se identified subproblemele problemei date.2. Se alege 0 structura de date capabila sa retina solutiile subproblemelor.3. Se caracterizeaza substructura optimala a problemei printr-o relatie de recurenja.4. Pentru a determina solatia optima, se rezolva relatia de recurenta in mod bottom-up

(se rezolva subproblemele in ordinea crcscatoare a dimensiunii lor).

1. Prezentare generaHi

CAPITOL1JL ~

Metoda programarii dinamice

'bsir_.out30

:bsir.in

21

bsir.out8

hsir. in

lO

Exemple

.72

Noi am rezolvat deja, tntr-o maniera intuitiva, cateva probleme foarte simple deprogramare dinamica :

I!

Restrictii

-e l:5~lDDDDD

• i s», '1:::;1000

CerinjiiScrieti un program care -sl deterinine numarul minim.de .secunde(din momentul in carea incepnt .descarcarea) dnpa care Vasile poate incepe Instalarea aplicatiei,

175

.campion, 2005

pachete.out2

pachete.in51 1

1 23 1

2 13 3

ME'IDDA PROGRAMARII DINAMICE

pachete.out7

pachete.in2 11 53 32 4

Exemple

Solutie

In primul rand sa observlim ca restricjiile problemei (1:50:5100000) snnt formnlatepentru utilizarea unui compilator ce permite alocarea unui spatiu de memorie mai marede 64 KB (de exemplu, gee sau g++).,

Date de. iesire

Fi§ierul de ie§irepachete. out va contine o singura linie pe care va -fi'scns 'numarulminim de secnnde (din momentul in care a incepnt descarcarea) dupa care Vasile poateincepe instaIarea aplicatiei.

ldentificarea subproblemelor

Se cere timpul minim (exprimat in secunde) dupa care poate incepe instalarea aplicatiei,timp calculat din momentul inceperii descarcarii primului pachet.

o subproblema a prohlemei date ar putea fi formulatii astfel: "determinati timpulminim dupa eare poate incepe instalarea aplicatiei, in ipoteza ca aplicatia este fermatanumai din pachetele i, i+1, ...• n-l (O:::;i<n), timp calculat din momentul inceperiidescarcarii pachetului i " .

Date .de .intrare

Fe prima linie .a fisierului de intrare pechet.e , in ,se afla. un numar natural n, repre­zentand -numarulde pachete. Pe urmatoarele n Iinii se aftl Informatiile despre pachete,in ordinea in care .acestea trebuie sa tie .descarcate. Pe linia k+1 ·se .afla doua numere-naturale, I ~lli D, .separate printr-unspatiu.cusemnificatia ~timpul deinstalare .apachetului k este I, iar timpu~ de descareare a pachetului k este D".

~:

1!

r-

_ ~ .~ ~'~ ............. iN LIMBAJUL CIC++PENTRU LICEU

,...,

r-i

c~ =C~ =1

C~ = Cn_~+C~:i,l £ k < n

r Tot in capitolul "Recursivitate" am analizat aceasta problema lli am observat ca 0i .ezolvare recursiva a relatiei de recurenja este meficienta, din cauza faptului ca sub­\_problemele se suprapun. Am rezolvat relatia de recurenja in mod bottom-up, folosind

meeanismul ilustrat de triunghiul lui Paseal.

rSuma 11U1Xima tn triunghii, j

La sectiunea de probleme propuse din eapitolul "MetodaDivide et impera" , am prezentatr1' rezolvare recursiva a aeestei probleme. Analiza acestei rezolvarl conduce Ia ideea ca! solutia recursiva este ineficienta, din eauza faptului ca subproblemele problemei date seL-suprapun. Abordarea iterativa prezentata ea solujie se bazeaza pe metoda programarii

dinamice. Complexitatea algoritrnului este de ordinul n2, unde n reprezintii numarul depinii din trinnghi.)! in cele ee urmeaza, vom exemplifica pas eu pas modul de rezolvare a problemelorl, 'prin metoda programarii dinamiee.

rPachete, '

L;Vasile descarca de pe Internet 0 aplicatie foarte interesanta. Apllcatia a fost imphtita inmai multe paehete, iar paehetele trebuie sa fie descarcate intr-o ordine fixata, Se cunoaste

r timpul de descarcare pentru fiecare pachet, precum lli timpul necesar instalarii fiecarui! i pachet (ambele valori fiind exprunate in secunde).

, Fiind nerabdator, Vasile vrea sa testeze aplicatia cat mai repede lli vrea sa tnceapainstalarea chiar inainte de a se fi terminat descarcarea tuturor pachetelor.

n Dar stie ca odata ce a inceput instalarea aplicatiei, aceasta nu mai poate fi tntrerupta, ! (va da eroare daca la momentul in care este necesara instalarea unui pachet acesta on este. . complet descarcat). .

l :2. Aplicajii

Date de intrare

Restrictii

• M;$;n;5;50000;• v

i':::;;100,V'1':::;;i':::;;N.

r ,i I

i iI ,W

""

"

( "!! '

i, I

'-'

1

I 1, .~

w

, 1I 'I ILJ

,I 'I I~

,.---~

,

, 1-, ,

i ;LJ

iu

r-lI i

--,I I, IU

179METODAPROGRAMARII DINAMICE

.Solutie

int s[Dim+lJ [4J;int v[Dim+l]; /* v[iJ=numarul de pasageri din vagonul i */int surn[Dim+lJ; /* sum[ij=v[1]+v[2J+ ... +v[iJ */..int M, n;

:Vom rezolva o problema mai generala, vom determina'numarul maxim.de pasageri ce potf transportati la destinajie cu k locomotive (incazul nosttu particular, k~3),

.Identlficarea subproblemelor

o -subproblema a problemei date se poate formula astfel :sli-se detertttine mumannmaxim de pasagerice pot -ft ·transportati din vagoanele 1, 2, _...• i folosind j cninllo,comotive.

#inelude <stdio.h>#define Dim 50000#define k 3

#define in_file "tren. in"#define out_file "tren.out"

Stabilirea structurilor de date

Observant ca in formularea unei subprobleme intervin doua variabile: numarul devagoane si numarul de minilocomotive.

Prin urmare, pentru a retine solutiile subproblemelor vom utiliza un tablou bidi­mensional S cu n linii §i k coloane : s l Ll [j J reprezinta numarul maxim de pasageri cepot fi transportati din vagoanele 1, 2, .,., i folosind j minilocomotive.

Evident, solupa problemei initiale va fi calculata in s en] [3J.

Determinarea relcqiei de recurenjd

Un numar maxim de pasageri transpcrtati se poate obtine transportand eu j locomotiveun numar maxim de pasageri din primele i -1 vagoane (5 [i -1] [j]) sau transportand ell

j -1 locomotive un numar maxim de pasageri din prlmele i-M vagoane (s [i-MJ [j -1 J),la care se adauga pasagerii aflati in vagoanele i-M+l, i-M+2, ...• i (cu i-M>O), care.vor fi transportati eu locomotiva j.

Sa noram-cu sum [i] numlitultotal de pasageri dinprimele i vagoane, \iie{l, 2, .,., n}.Se obtine astfel relatia de recurenja :

• s[O] [j]=O, j==1. x :• s[i1 (j]=sum[il, daca i::;;M; j=1. k ;

• s Lf l [j Jemax { s [i-l] [j], s [i-MJ [j -1] + (sum [i] -sum[i-M] ) l , daca i>M.

Rezolvarea relatiei de recurenpi

Spatiul de memorie necesar pentru memorarea datelor depaseste 64 KB. Pentru imple­mentare am utilizat compilatorul gee.

.campion, 2005

tren.out240

"PROGRAMAREA:!NllMBAJUL C/C++ PENTRU UCEU

[Vagon .i 2 3 4 5 6 7

INumlitde .pasageri 35 40 • 50 10 30 45 60

tren .in7

35 40 50 10 30 45 602

Daca minilocomotiva 1 :duce la destinatie vagoanele l-2~ :minilocomotiva 2 ducevagoanele 3-4, .iar miniloeomotiva 3 .duce vagoane1e 6-7, -numarultotalde pasageri ceajung la destinatie este 24 O. §:i e maxim -posibil.

Cerinpi

Scrieti un program care Sa determine numilrulmaxim de pasageri ce pot fi -transportapla destinajie cu cele 3 minilocomotive,

Date de iesire

Fisierul de Iestre tren . o u t va conthie 0 singura linie pe care va fi scris numarul maximde pasageri ce pot fi transportaji la destinatie cu trei minilocomotive.

Ftsierul de intrare tren. in contine pe prima linie un numar natural n , reprezentandnumarul de vagoane, Cea de a doua linie contine n numere naturale separate prin care unspatiu, v1 V 2 .,. V n' reprezentand numarul de pasageri din fiecare vagon. Cea de a treialinie contlne un numar natural M ce reprezinta numarul maxim de vagoane care pot fitrase de 0 minilocomotiva.

Exemplu

178

.ultimul -vagon.trasede .locornotiva 1 ,"§iprimulwagonpe care .locomotiva 2 mtennoneaza

.sa-I duca la ,destinlJ.lie.ln mod -analog, .secventa de vagoane ttasa de minilocomotiva2 -nu -trebuie :sa-fie -obligatoriu .adiacenta .cu .secventa .de .vagoane trasa -deamnilo­comotiva 3.

De-exemplu, c'Sa :presupunem eil rrenul are -n=7 vagoane.darominilocomotiva-poatetrage .cel mult M=2 vagoane, Sa consideram ca -numarulde pasageridin fiecare -vagoneste:

Date de intrare

Cerintd

Evaluare optimalii

':~

:;!

181

2° (3°4) =2°2=2Cost~c[3] [4j+c[2] [2j-5+1~6

Varianta optima este cea de a doua.

ExplicatieExpresia2°3°4 'se poate evalua in doua moduri:(2°3) °4=1°4=2cosr.ec j z j [3J+c[l] [4)~10+1~1l

'MEIODA PROGRAMARn DINAMICE

eva1.out

620 (304)

evaLin

4 3

2 3 41 1 4 2

3 2 1 41 4 1 22 1 3 21 1 1 1

1 1 10 1

10 20 5 5

20 5 5 5

Soltqie

Idemificarea subproblemelor

Pentru a evalua Xl°X2 ° ... °x~, In final va trebui sa cfectuam operatla °intre doua valori,deci vorn paranteza expresia astfel :

Exemplu

(Xl°X2 o ••• OX,) ° (Xk

+l 0... 0Xp)

unde k este 0 pozitie ce poate varia intre 1 si p-l.

Aceasta observatie se aplica ~i expresiilor dintre paranteze. Prin urmare, subpro­blemele problemei initiale constau In determinarea parantezarii optimale a expresiilor deforma Xi°Xi +l ° ... °Xp 1,:5;i~j~p.

Observam ca subproblemele nu sunt independente, De exemplu, evaluarea expresieiXi°Xi+l 0 ••• "x, ~i evaluarea expresiei X i+l °Xi+

20... °x

j+l' au ca subproblema comuna

evaluarea expresiei Xi+l ° ... °x j '

Stabilirea structurilor de date

Formularea 'unei subprobleme depinde de doua variabile (L ~I J, ce reprezinta extre­mitatile secventei care se evalueaza). Prin urmare, pentru a reline solujiile subpro­blemelor, vom utiliza 0 matrice M, cu p linii si p coloane, unde M[i 1 (j] reprezintacostul minim pentru evaluarea expresiei Xi°Xi+l ° ... °Xp 1,:5;i,:5;j,:5;p.

Evident, numarul minim de Inmultiri necesare pentru a calcula Xl°X 2 ° ... 0Xp esteM [11 [p].

Determinarea relcqiei de recurentd

Pentru ca evaluarea expresiei Xi°Xi

+1 0.. 'OXj

sa fie optimala, evaluarile expresiilor(Xi °X2 0... °x k ) ~i (X k+l 0 ••• °x j ·) trebuie sa fie, de asemenea, optimale. Demonstratiase poate face usor, prin reducere Ia absurd

Datede iesire

Fi~ierul de aesire -eve L, out va.contine pe prima;.Iinie un .numar naturalreprezentandcostulevaluarii .exprestei X1 0X 2

0.••• °X

p(minimposibil).Pecea de a ,doua linie vom

ilescriemodalitatea,optimade:evaluare-.a.expresiei Xl~x;O_•... °xp,-indicand prin paranteze.rotunde -ordinea .efectuarii .operatiilor,

int -mai.n (void)

lint L, j-;

FILE * -£in .= :£open (in_£ile, -"rt"'):

FILE * fout =fopen (out_file, "wt-lI) ; ;

fscanf(£in, ~%d", &n):£or (i=l; i<=n: i++)

{£scanf (fin,'~'%d", -.&v(i]);

sum[i]-sum[i-l]+v[i]:fscanf (fin. '''Id'', .&M);

£or (i=1; i<=M: i++)for (j=l; j<=k; j++) s[iJ [jl=sum[i];

£or (i-M+l: i<-n; i++)for (j=l; j<=k: j++)

{s[i] [j]-s[i-l] [j];

if (s[i] [j] < s[i-Ml [j'-l]+{sum[il-sum[i-M]»

sri] [j] = s[i-M] [j-!]+(surn[i]-sum[i-M});

fprintf (fout, "%d\n", s [n] [k]);

fcloseall():-return 0; }

PROGRAMAREA-iN LlMBAJUL C/C++PENTRU LICEU

Sa consideram A={al' a z•...• an} 0 multime ell n elemente peste care este definita 0operatie binara DOlata 0: AxA....:,.A. Pentru simplificare, vom considera, flir3. a restrangegeneralitatea, ca A={1, 2, ... , n}.

Operatia ° este specificataprintr-o rnatrice op , eu n linii ~i n coloane (op Li j [j J=i OJ).Operatia ° este necornutativa.

Efectuarea oncarei operatii are un cost. Costurile sunt retinute Intr-o matriee c ,c [i] [j J reprezentand costul efeetuarii operatiei i OJ, 'v'1~i, j~n.

Dandu-se p valori euprinse .intre 1 ~i n, xl' x2 ' ••• , xp' sa se determine costul minimpentru 'evaluarea expresiei Xl°X2 ° ... 0Xp'

Fisierul de intrare eva1. in contine pe prima linie nurnerele naturale n §i p, separateprintr-un spajiu. Pe eea de a doua linie se afla p numere cuprinse intre 1 ~i n, reprezentandvalorile xl' x 2 ' ••• , xp '

. Pe urmatoarcle n linii se afUi cate n numere naturale cuprinse intre 1 §i n, reprezentandmatricea op ,

Pe ultimele n linii se afla cate n numere naturale separate prin spajii, reprezentandmatricea costurilor c.

180

I

~

,...I

••

~: I( ;

I

r:

I

\ ;

n", ,

I ,

I

;;

l ~

i ,

ri, ,

r!

r

'"'

,...

",

182 .PROGRAMAREAlNliMBAJUL C/C++ PENTRU UCEU METODAPROGRAMARII DINAMICE 183

w

Deducem .astfel.urmlitoarea .relatie de recUTenlll :

"M[i] [il-O,'V'ie{1,2, '''. pi;• M[i] [j]~min{M[il [k]+M[k+ll [j]+c[s] [dl};

iSk<junde ell 5 mn'Ilotat(xi~X20 ._,.Oxk)~iar,cu e am notat (Xk+1o ••• -~Xj)'

Cum .interpretam-accasta .relatie de .recurenta? Pentrua .determina costuI -minimpentru evaluarea'expresieix,i°xi+l0... °Xj l .fixam pozltiade parantezare k·;m .toatemodurile posibile (intre i ~i j -1) '§ialegemvarianta care .ne conduce la minim. Pentruo pozttie k fixata, costul.parantezarii esteegal ell costuI minimpentru-evaluareaexpresiei(Xi °x

2...... °x

lt) , Ia careseadauga costul minimpentru evaluareaexpresiei (X k+1

o••• ox:!)

~i costul inmultirii celor dod valori obtinute ca rezultatal evaluarii parantezei din stiinga~i -al parantezei din dreapta.

.\Observam ca pentru rezolva relatia .de -recurenta trebuie sa retinem 'pentru fiecaresecventa si rezultatul .obtinut inurma-evaluiirii. -Pentru.aceasta vom utiliza 0 matricedenumita r-ez , rez [i] [j 1 =x

io~2o... °X

jin urma evaluarii optimale.

De ,asemenea.· observam ca numai jumatatea de deasupra diagonalei principale din Meste utilizata. Pentru a construi .sotutia optima este utila §i retinerea indicelui k, pentrucare se obtine minimul. Nu vom considera un .att tablou, ci-l vom retine pe pozitia.sirnetrica falllde diagonal. principal. (M [j I [i j ).

Rezolvarea relatiei de recurentaRezolvarea recursiva a relatiei de recurenta de mai sus este 'ineficienta, din cauza faptuluica subproblemele se suprapun (0 abordare recursiva ar conduce la rezolvarea aceleiasisubprobleme de mai multe ori). Prin urmare, vom rezolva relatia de recurenta in modbottom-up: deten:ninam. parantezarea optimala a expresiilor formate din doua valori,apoi din 3 valori, 4 valori, etc.

void Rezolvare ()int nr, i, j, k , kInin, min, Infinit=lOOOO;

for (i=1; i<=p; i++) rez(i] [i]=x[iJ;

£or (nr=2i nr<=p; nr++)Ilnr=numarul de valori din secventa

for (i=1; i<=p-nr+1;. i++)Iii - inceputu1 secventei de nr valori

{j=i+nr;"'l;Ilj - sfarsitul secventei de nr valori

for (k=i, min=Infinit; k<j; k++)Iidetermin minimul si pozitia sa

if (min> M[i) [k'l + M[k+1] [j] +c [rez [i] [k] I [rez [k+1] [j J ] )

[min = M[i] [k]'+ M[k+11 [j] +c[rez[il [k]] [rez[k+l] [j]);

krnin=k; }

M[i] (j]=min; M[j] [i)=kmin;rez(i) [j]=op(rez[ij [kmin] J [rez[kmin+l] [j]]; }

Reconstituirea .solutiei optime se face .foarteusorfn mo'd recursiv, utilizand infor­matiile retinute sub diagonalaprincipala inmatricea.x...lnacest scop.un.mncna main ().apelam Afi.-sare (l,p) .

void Afisare(~nt i, ~nt j){iia-fiseaza ·parantezarea -op t.LmaLa : a expresiei xi ... xj

.-j.-f (i==M[j] [i]) fout«x[i);

-e.Lee

(fout«"("; Afisare(i,M[j] [il,; fout«")";}

-fout«"o" ;

~f {j==M[j] (i]+1) fout«x[j];

.el.se

(fout«"{"; Afisare(M[j][i]+l,j); fout«")";}

Pietre

Un copil singur Ia p'iirinti a descoperit unjoc nou. Prin curtea casei sale trece un rau, nufoarte adanc §i nici foarte involburat. Pentru traversarea raului suntpuse in albic n pietre.CopiluI a seris pe flecare piatra un numar natural §i acum vrea sa determine 0 modalitate dea traverse raul astfel mcat sa faca un numar maxim de pasi, respectand urmatoarele reguli :1. la fiecare pas. piatra pe care calca sa aiba un numar eel putin egal cu piatra precedenta

(malul .de pe care pleaca este considerat piatra cu numarul 0);2. copilul merge numai inainte.

Cerinpi

Determinati un traseu de lungime maxima care sa respecte regulile de mai sus, in ipotezaea acest copil este un bun atlet §i la orice pas poate sari peste oricate pierre.

Date de intrare

Fisierul pietre. in contine pe prima linie un numar natural n care reprezinta numarulde pietre. Pe cea.de a dona linie se afla n numere naturale nenule, separate prin cate unspatiu, care reprezinta, In ordine, numerele scrise pe pietre.

Date de iesire

Fisierul de iesire pietre. out va continepe prima linie numarul maxim de pietre pecare paseste copilul, Pe cea de a doua linie vor fi scrise numerele de pe pietrele pe carea pasit, separate prin cate un spatiu.

Restrictie

0<n$;1000

I

J

~

, I

! i~

,1

Jr "\

!I..J

r 1~

: 1

~

r -,

'-"

:-;

,.

lil'l,'l'"I!I"Irl

!lifi

1

1'1!I, I:I,i' ,IIi ~ i'l I

lil~:!:li,IIII,; !Irl:'~\I-II

',IIIIII""II!,IIII~I~111111111,'11,:Ili!IIII!!III;II,II!I,,1111[i'li(:

1'1"'1'"",IIII.!!1

;1111~r:I~!;1i;'I"!I~"!1 ' 1 1' ~ \ ; ! 'I"I'I",I',I!lil!I,III,I'I:'1III

lllliI11;,,'

'I"!""'il:;,'l",i'I"","'!',Iii ',I,ll'"'!i!,I"

"1'''',1''!'I""i'd'II'11,,'!,II'IIii!I"""III'11~;1il!'!I,"!':"I"i",[II!liiil!,Ilil'I',I"':'~il"l" lilli' ~

11!11'!lil',i'h'i!"!!;,lli,:,'li'I "llr;,!,III !': !ii,i~

!!,'I'I'!I,!",III II!~lifJll~ '!I;I\,iii!lii!!!!I:!

''''1''11'-I: ',:1!ilii:!:!:1!:1[1!rII'!~!1II,!IIII,"I!:I"!'1

l'ill!!,I!,I'iI:II:!II'I

1:11,',11,:1"

11:1'1'1'11"1

185.

" '«max;

':ME1ODA PROGRAMAmI DINAMICE

//determin ~aximul din-vector~l 1j.nt :i, maxed.Ll l , poz'max=l;£or (i=2; .i<,:"n;i++)

:i.:f (max<l [i]) {max=l [i]; pozmax=i;£out«"Lungimea cel-qi ,mai .lungsubsir crescator:fout«"\nCel -mad cLunq subsir: \n"; I

:for (i=pozmax; i!=-l; i=poz[i]) fout«a[i]«' ';.

• 1~n:5;100;

• 1:5;GMax:5;300 ;

'. ci' 9 1:5;100. 'ViE{l, 2, ... , n}.

Cerinta

Sa se determine 0 modalitate optimala de umplere a rucsacului (castigu! total obtinut safie maxim}. Daca nu exista solutii, yeti afisa mesajul IMPOSIBIL.

Rucsac

RestricJii

Fisierul de iesire .ruc aac . out va contine pe prima linie un numar natural care reprezintacasrigul maxim.objinut. Pe cea de a doua linie vor fi scrise obiectele selectate pentru aobtine acest castig maxim, separate prin cate un spatiu. '

Fisierul de intrare rucsac . in coniine pe prima linie dona.numere naturale separate prinspatiu, n ~i ~Max. Pe cea de a doua Iinie se afla. n numere naturale separate prin spatii,care reprezinta greutatile eelor n obiecte. Pe cea de a treia linie se afla n numere naturale­separate prin spatii, reprezentand castigurile corespunzatoare celor n obiecte.

Date de intrare

Date de iesire

Sa consideram.acum ca acest copil nu este un sportiv prea grozav ~i ca el poate sari laun pas eel mult Mpietre (M cilit de pe ultima Iinie- a fisieruluide intrare). Modificatiprogramul astfel incat sa determine daca in aceste ccnditii copilul poate ajunge pecelalalt mal si.daca da, sa determine 0 solutie cu numar maxim de pasi.

Exercitiu

Un ·hot are un ruesac eu care poate cara 0 greutate maxima GM?l-x. El i~i poate umplerucsacul selectand obiecte dintre cele n pe-care Ie are Ia dispozitie, Grice obiect poate fi-pus Inrucsac numai in intregime.

Pentru fiecare obiect i eS,te cunoscuta greutatea 9 i ;?i castigul c 1 obtinut in unnaselectarii obiectului i. '

pietre..-out.63 61.0 3060 80

_____"-=:.:.-.:--=_o_:iN LIMBAJULClC++PENTRU l.JCEU

! '- "

r .Soiutieii, .l J Identificarea subproblemelor

VOID memora numerele serise pe cele n piette in vectorul a. Problema cere determinarear- celui mai lung subsir crescator.al sirului a. 0 subproblema a problemei date consta in a! : determina eel mai lung 's:ub§ir crescator ce incepe. ell ai' .'Vie{l, 2, ... , n}. 'Sub­1,.J problemele nu sunt independente: pentru .a determina eel mai lung .subsir crescator ce

incepe ell a i este necesar sa determinam cele mai lungi subsiruri crescatoare care incepr ell a p aiS:ap 'ltj e{i+l •...• n}.I,( .,J

int i" j;l[n]=l; poz(n]=-l;

for (i=n-l;' i>O; i--)

for (1[i]=1, poz[i]=-l, j=i+l; ~<=n; j++)

if (a[i] <= a[j] && 1[i]<1+1[j1)

(1[il~1+1[jl; poz[il~j; )

r Pentru a detennina solutia optirnli a problemei, detenninlim maximul din vectorul 1,i i apoi af'l§am solutia, incepand en pozitia maximului §i utilizand informaPile memorate in

vectorul paz:

r:, '

I j D' . i d x. etermmarea relatiei e recurentar Relatia de recurenta ce caracterizeaza substructura cptimala a problemei este :i' • 1[n]=1; poz[n]=-l;( J • 1[i]=max{1+1[j] I a[i]::;;~[j]};

j=i+1, ripo z [i] = indicele j pentru care se obtine maximul 1 [i] .

Stabilirea structurilor de .datePentru a retine solutiile subproblemelor vom 'considera doi vectori suplimentari, 1 ~i

r poz , fiecare cu cate n componente, avand semnificatiile :i ,J. 1 [i] = l~nginle3:: celui mai lung sub-Sir crescator care incepe eu a [i] ;

• po z [ i] =pozitia elementului ee urmeaza dupa a lL] • in eel mai lung subsir crescatorcare fneepe cu a Lr l , daca un astfel de element exista, sau -1. daca un astfel deelement fin exista." '

,.II ,LJ

ni ', ,, '

n.1 j Rezolvarea reiatiei de recurenpi

Rezolvlim relatia de recurenta in mod bottom-up :

. 184 'PRl: H iK A M A. K .......[1---------------------------....:.--------t i .

, 'Bxemplu~:pi.etre~in

I '11l 18 3 6 50 lO 8 1.00 30 60 4080

nObservatie

, t J.solutia -nu este unica. De exemplu, :~i 3' 6 8 :30 -40 80 este 0 solutie corecta,

Soliqie

ldentijicarea subproblemelor

Problema consta -in selectarea unor obiecte (indiferent in ce ordine), astfel fncat .suma'greutiiplor lor "sa fie egala ell GMax. iar castigu! obtinut sa fie-maxim.

o subproblema-a probiemei date consta in .selectarea ell castig maxim a .unorobiectepentru care suma greutatilor este s, S::;GMax.

Stabilirea structurilor de' date

Observam ca formularea unei subprobleme depinde de 0 singura variabila : S - greutateatotala, Prin urmare, 'pentru a retine solutiile subproblemelor, vom utiliza un vector CMax,ell GMax+l componente, avand semniflcatia : CMax [S] reprezinta casrigul maxim ce sepoate obtine prin selectarea unor obiecte ell greutatea totala s, O~S~GMax~

Deoareee este necesara si detenninarea solutiei optime, nu doar a castigului maxim,vom retine pentru fiecare greutate posibila S (O~S~GMax) multimea obiectelor seleetatepentru objinerea castigului maxim. multime reprezentata prin vector earaeteristic. Maiexact, vom utiliza 0 matriee u a cu GMax+llinii §i n coloane, cu semnificatia u z [S] [i] =1,daca am selectat obiectul i pentru a umple optimal un rucsac ell capacitatea s , sau 0, incaz contrar.

rucsac.in

PROGRAMAREA "iN LIMBAJUL C/C + -i-:PENTRU LICEU 187METODA 'PROGRAMAR!l DlNAMICE

vo:id Citire();vo~d Rezolvare();void Afisare () ;

int main (){Citire ();Rezolvare (.) ;Afisare () ;xeturn 0; }

void Ci tire ()(ifstream fin("rucsac.in");-int i, j;fi.n»n»GMax,·for (i=1; i<=n; i++) fin»g [i];for (i=l; i<=:r).; i++) fin»c[i];fin. close (); }

Vom rezolva.relatla de recurentain modbottom"",up, lncercand -sa wnplem optimal maltntAi 'un zucsac de capacitate 1, apoiz , _3, _.~, GMax.

#include -<fstream.h>#define NMax 101--#define MaxG 301'..int n , GMax;int c[NMaxJ, g[NMax];...int CMax[MaxGl, Uz [MaxG] [NMax] ;

1p~

Explictuieg[1]+g[21+g[4]~80+l0+10=100

Bxista .sialte variante {selecrarea obiec.,tului 5 sau 1'§i 3), dar castigul ar fi maimic.

rucsac.out291 2 4

7 lOa80 10 20 10 lOa 30 558 20 5 1 10 3020

186

Exemplu

Determinarea relatiei de recurenta

Pentru a umple un rucsae ell eapacitatea S vom selecta in final un obiect oareeare i, carehicape In rucsac (g [ i ) ss), obtmand astfel casugul c [i I. Restul rucsacului (decicapacitatea S-g [i]) trebuie sa tie umplut optimal (obtinand astfel castigul Cmax [S-g [i]]),

daca este posibil. Problema este ca nu putem seleeta acelasi obiect de mai multe ori, deciobiectul i pe care Il vom seleeta nu trebuie sa fie deja folosit pentru umplerea optimalaa capacitatii S-g[il (adica uz [S-g[i] ) [iJ=O).

Vom incerca toate obieetele i posibile §i, evident, vom alege acea valoare a lui ipentru care se obtine un castig maxim.

• CMax [0] =0;• CMax [5] =max{CMax [S-g [i] l +c l Ll }, daca g [iJ~S §i uz [S-g [i) ] [il =0.

i=l, n

void Rezolvare()tint S, k , i;

for (S=1; S<=GMax; S++) CMax[Sj-=-l;for (S=1; S<=GMax; S++)

for (i=l; i<=n; i++)if (g[i]<=S && CMax[S-g[i]] !=-1 && !Uz(S-g(i]] [ill

if (CMax[S]<c[iJ+CMax[S-g[iJ]){CMax [S] =c[ij +CMax [S-g [i]];for (k=1; k<?n; k++)

Oz[S] [k]=Oz[S-g[i]1 [k];

OZ[S][il=l;}

'-'

Rezolvarea relcqiei de recurenta

Initializam veetorul CMax eu valoarea -1. Daca CMax[S] va ramane -1, deducem caeste imposibil sa umplem un ruesac eu eapaeitatea s.

void Afisare (){ofstream fout ("rucsac.out");

:,'~

~

I : Se urmareste transformarea unui sir de caractere, ·denumit sursa,lntr-un alt sir del J caractere, denumit destinatie, folosind urmatoarele operatii permise : .

l Exercitiu

Modificati programulprecedent astfel Jncat, daca exista -mai multesolutii optime, ,sai' furnizeze solutia ell numar maxim de obiecte selectate.

l,

189ME1DDA'PROGRAMARII DINAMICE

Evident, em [ 0] [0] reprezinta costul transformarii de cost minim a sirului X in sirul Y.

Solutie

Identificarea subproblemelor

Sa consideram ca x este sirul-sursa, de lungime m. iar Yeste sirul-destinatie, de lungimen. Sa notam cu Xi sufixul lui x, care Incepe la pozitia i (deci secvenja de caractereXiX i +1• .. xm_ 1) . §i ell yj. sufixul lui Y, care incepe la pozitia j (secventa de caractereY j Yj-f-l' •• Y ll - 1)·

Problema cere transfonnarea de cost minim a sirului x in sirul Y. 0 subproblema aproblemei date consta in a determina 0 transfonnare de cost minim a sirului Xi in siruly j

, 'v'ie{o. 1•...• m-l} §i je{o. I, ...• n-l}.

Restrictii

• Lungimea sirurilor de caractere nu depaseste 100.• Costurile operatiilor sunt numere naturate s 100.

Date de iesire

Fisierul de iesire sir. out va contine pe prima linie costul transformarii de cost minim.Pe urmatoarele linii ·vor fi specificate operatiile executate in·transfonnare.

Fiecare operatie are .asociat .un cost. CostuI unei transformari .esteegal -cu sumacosturilor -operatiilor .urilizate.

Cerinpi

Date fiind sirul-sursa si sirul-destinatie, $3. -se determine 0 transformare .de cost minim.

Date de intrare

Fi§ierul de intrare sir. in contine trei linii.Pe prima linie este ,specificat§irul-sursa, iarpeceade a doua, .sirul-destinane. Pecea de a .treia linie .se afla 6 numere naturaleseparate prin care un spatiu, care reprezinta costurile celor 6 operatii descrise mai sus (inordinea din tabel),

Stabilirea structurilor de date

Observam ca in formularea unei subprobleme intervin dona variabile: i (pozitia deInceput a sirului Xi) §i j (pozitia de inceput a sirului yj). Prin urmare, pentru a retinerezultatele subproblemelor §i a reconstitui solutia vom utiliza doua tablouri bidimen­sionale, em §i op , fiecare cu cate m linii §i n coloane, cu semnificatia :

- em I i 1 [j] reprezinta costul transformarii de cost minim a sirului Xi in sirul yj;- op [Ll [j] reprezinta prima operatie executata pentru a transfonna optimal Xi in Yj •

se poate

succesiunea de operatii prin care din sirul-sursa se obtine

Operajte Destinajie SursaCopy (A) A LGORITMCopy(L) AL GORITM

Rep!ace(G,T) ALT ORITMDelete (0) ALT RITMCopy(R) ALTR ITMInsert (U) ALTRU ITMCOPy{I) ALTRUI TMInsert (S) ALTRUIS TMCopy(T) ALTRUIST MKill (M) ALTRUIST

PROGRAMAREA iN LIMBAJUL C/C++ 'PENTRU LICEU

if (CMax [GMax]==-l) fout«"IMPOSI,BIL":

"eJ.se

{fout<~CMax[GMax]«endl;

£or (~nt k=l: k<=n; k++)if (Uz [GMax) {kl) :tout «k«" ";}

fout. close (); }

1. COpy (a) transfera caracterul a din sursa in destinajie

2. DELETE (a) sterge caracterul a din sursa

3. INSERT (al insereaza caracterul a in destinatie

4.REPLACE(a, b) inlocuieste caracterul a ell caracterul b (a dispare din

sursa, iar in destinatie apare b)TWI DDLE (ab) secventa ab din sursa se rransforma.In ba in destinatie

5.(ab dispare din sursa si apare ba in destinatie)

6.KILL (secventa) dupa ce s-au efectuat toate operatiile necesare, se poate

elimina secventa ramasa (sufixuI) din cuvantul-sursa.~

_BB

Transformare de cuvinte

nLJ

nI .IL~

r;I I

LJ

, ,

NUtrlinT transformarer sirul-destinatie., '• Ii .1 Exemplu

f"""'" Pentru transformarea sirului-sursa ALGORITM in strul-destinatie ALTRUIST,

:1 : folosi urmatoarea secventa de operatii :, ,, ,

r,I .

!L J'

r, ...

,---'

int main ()

{Citire () ;

aeaoi.ve re () ;Afisare () :return 0; }

int n, m:int cost [6]:int op[DMax] [DMax], cm[DMax] [DMax]:

char X[DMax], Y[DMax]:

void Citire():

void Rezo!vare();

void Afisare();

#include <fstream.h>

#inc!ude <string.h>

#define DMax 101

#define COPY 0

#define DELETE 1

#define INSERT 2

#define REPLACE 3

#define TWIDDLE 4

#define KILL 5

,, -..;

191

}

cm[n) [rnj-O,for (i=m-1: i>=O: i--)

£or (j=n-1: j>=O: j--)

(cm[i] [j]=cost[KILL)+cm[rnj [j]; op[i) [jJ~KILL;

if (X[ij=-Y[j] &&

cm l Ll [j]>cost[COPY]+cm[i+1] [j+1])

{cm[i] [j]=cost[COPY]+cm[i+1l (j+1]:op[i] [j]=COPY; }

if (em[i] [j]>cost [DELETE] +em[i+1] (j])

{cm(i] [j]=Cost[DELETE]+cm[i+1] l j l rop[i] [j]=DELETE, )

if (cm l Ll [j]>cost[INSERT]+cm[i] [j+1])

{cm[i] [j]=cost[INSERTJ+cm[i] [j+1]:op[i] [j]~INSERT; )

if (cm[i] [j]>cost[REPLACE]+cm[i+1j [j+1])

{cm l Ll [j]=cost[REPLACE)+cm[i+l] [j+1]:

op [i] [j ] =REPLACE: }

.if {i<m-l && j<n-l && X[i]==~(j+l} && X[i+l]==Y[j]

s s cm l Ll [j]>cost[TWIDDLE]+cm[i+2] [j+2])

{em[i] [j ] =cost [TWIDDLE) +cm[i+2J [j+2]:

op[i]'[j]=TWIDDLE: }

void Rezolvare ()

tint i, j:

//initializare

£or (j=O: j<n: j++)

{cm[m] [j]-(n-j)*cost[INSERT], op[mj [jJ-INSERT, jfor (i=O; i<m: i++)

{cm[i] [?J=cost[KILL]: op[i] [n]=KILL:.if Icm Ld l en] > (m-Ljwccs t [DELETE])

{em [i] l n l = (m-i) *cost [DELETE]: op [i] [n] =DELETE; }

METQDAPROGRAMARII DINAMICE

"Void Citire ()

{:i.nt i;ifstream fin ("-sir . .Ln" ) ;

Tin.qetline(X, DMax); m=strlen(X):

£in.getline(Y, DMax):n=strlen(Y):

for (i=O: i<6: i++) £.in»cost[i]:fin.close(): I

}

'PROGRAMAREA"iN UMBAJUL C/C++PENTRU.UCEU190

."[jetenninarea Telape{.:deTecurentaPentru..a':transforma:sufixul xijn sufixulv" -eomexecuta.toate .operatiile -posibile-si -vomalege varianta pentrucare -se -obtine -minimul. Relatia de Tecurenlliceearacterizeaza

-substructura optimala a problemeieste :'. cm Iml [j]-= (n-j)"'*.cost (INSERT) ; 'v'O:S:j<n ;(pentru.atransforma~irulvidln yj

trebulesa inser1im (n-j )earactere);• em [i] en] =min {cost (KILL), (m-i) *cost (DELETE) } ; 'v'OS;i<m (pentru a trans­

forma ;§irul Xi .in.sirul vid.putem-§terge.succesiv-celem- i .caractere san -putem .utiliza

-operatia KILL) ;• em l n l [mI _0 (pentru a transforma ~irul vid in sirul vid costul este 0) ;

• -cm Li.I [j]=min{cost{COPY)+cm[H1] [j+ll, dacaX[i]--Y[j]cost (DELETE)+cm[i+l] [j]

eost(INSERT)+cm[i] [j+1]cost{REPLACE)+cm[i+l1 (j+l]cost (TWIDDLE) +cm [H2 J [j +2] • dacil.X[i] ==Y [j+1 J ~i X[H1 J=-Y [j]

cost (KILL) +cm [m] [j] )

Rezo[varea relatiei .de recurentiiDin eauza faptului ell. subproblemele problemei date. se suprapuu, 0 implementarerecursiva este ineficienta. Vom rezolva relajia de recurenta in mod bottom-up. Solutia 0vom reconstitui pe baza intormatiilor memorate in op .

t;

Cerintii

nScrieti un program care sa determine numarul minim de palindromuri in care poate fil. ~impartit1i 0 secventa de caractere data.

nPalindromI ,~....

Un palindrom este un cuvant care, citit am! de la stanga la dreapta, cat ~i de la dreaptarIa stanga, este acelasi. Daca un cuvant nu este palindrom, el poate fi taiat in mai muite! :piirti care sa fie palindromuri.

193METODA'PROGRAMAR!I DlNAMICE

char s [LgMax] :.:int Lg;j,nt rez;

FILE *file;

Solulie

ldentijicareasubproblemelorProblema cere 'Sa determinlim numlinil minim depalmdromuri in care poate fi implirlit~iruls de lungime Lg. Sa notlim cu -e- -preftxul '3irului s ce setermina pe pozilia .L,o.s:i<Lg '(deci ~irul format din caracterele -SO·S1' ~.Si)'

osubproblemli a problemei date constaindeterminarea numarului minim de palindromuriin care poatefi implirliqirul s-.

Stobilireastructurilor-de dateDeoarece 'in formulareasubproblemelor problemei date intervine nnmai variabila i,pozilia de sfarsita prefixnlui,dedncem ca pentru a reline solutiile subproblemelor estesuficient un vector nrp eu Lg·componente. unde nrp [ilreprezint! numarul minim depalindromuridin descompunerea sirului s i, O~i<Lg .

Deoarece problema nu cere §i 0 modalitate de descompunere a sirului datin numarminim de palindromuri, nu este necesara utilizarea altor structuri de date pentru a retinemformatiilenecesare reconstituirii solutiei.

Determinarea relatiei -tj,e: recurentaDaca sirul s' este palindrom: nrp [i J-l.

Daca sirul s v nu este palindrom : nrp {i l =l+min {nrp (j l • O~j<i, §i SjSj+1' •• Si

este palindrom.

Rezolvarea relatiei de recurentaPentru ca subproblemele problemei date se suprapun, vom rezolva relatia de recurenta inmod bottom-up,determinand numlirul minim de palindromuri din prefixul de lungime 1,.apoi din prefixul de Inngime 2 s.a.m.d.

Pentru implementare este necesara 0 functie care sa testeze daca 0 subsecventa asiruhii dat este san nu palindrom.

#include <stdio.h>#include <string.h>#define LgMax 101#define InFile "pal.in".fl:define OutFile "pal.out"

void citire (void)file"" fopen(InFile, "rt"):fscanf(file" "%s", s): Lg = strlen(s):fc!ose(file):

.break:break;break:.break:

break:.break:

fout«"COPY\n"; i++: j++:

fout«"DELETE\n"; i++:

fout«"INSERT\n"; j++:

fout«"REPLACE\n": i++; j++;'fout«"TWIDDLE\n"; i+=2: j+=2:

fout«"KILL \n"; i=m:

IExplicajie pal. in Ipal. out IExpliccqiea_nahan abaccbcb 3 aba_cc_bcb

Concursul regional de informatica ..Urmasli lui Moisil" • 2003

PROGRAMAREA iN UMBAJUL C/C+ + PENTRU LIeEU

I~al.out

case COPY:case DELETE:case INSERT:case REPLACE:

case TWIDDLE:case KILL:

}

fout.claseO; }

192

pal.inr anaban!

r:Date de intrare

tjFi~ierul de intrare pal. in contine pe prima linie 0 secventa de caractere (litere mici alealfabetului englez).

r:Date de iesire

l !Fisierul de iesire pal. ou t contine pe prima linie numarul minim de palindromurideterminat.

rl jRestrictie

Lungimea secventei de caractere nu depaseste 100.

,nExemplel. .J

~,!,

I i

II voi.d Afisare ()

{..int L, j;ofstream fout (",sir.out");

£out«cm[O] [O]«endl;

i=O; j=O:whi.~e (i<m 11 j<n)

:sw.itc~ (op l LI [j])

1

SumaTraditia este ca, la iesirea la pensie, pentru fiecare zi de activitate In slujba sultanului, ,marele vizir s~ primeasca 0 prima stabilitli de marele sfat al \liri!. Astfel, vizirul Magira primit pentru doar 5 zlle de aetivitate prima totala de 411 galbeni, deoarece sfatul tJiriia hotarat pentru ziua intiii 0 suma de 53 de galbeni, pentru ziua a doua 200 de galbeni,pentru ziua a treia 12 gajbeni, pentru ziua a patra 144 de galbeni, iarpentru ziua a

cineea doar 2 galbeni.Vizirul Jibal, celebru pentru contributia Mud. la rezolvarea conflictului din zona,

primeste dreptul ca. la iesirea la pensie, 'sa modifice sumele stabilite de sfatul tari i , darnu foarte inult. El poate uni eifrele sumelor stabilite ~i Ie poate desparti apoi, duplidorinta, astfel incat suma primitlipe fiecare zi s~ nu depaseasca 999 de galbeni ~i s~

Date .deintrare

Cerinpi

; I,

i..J

~ l

iL1

: ii I

!.J

195

ExplicatiePrima maxima (1608) se obtine pentrudistributia : 2 341 720 5 540

Olimpiada Narionala de Informatica, Galati, 2005

METODA PROGRAMARiIDlNAMlCE

suma.out

1608suma.in

523 417 205 5 40

Solutie

Vom eoneatena eifre!e numerelor din sirul dat ~i vom obtlne un ~ir de cifre (sa-l notam a)de lungime L (L este maxim ne S),

Exemplu

Identijicarea subproblemelor

Problema cere sa tmpartim sirul de cifre a in n numere nenule, a carer suma sa fiemaxima. Sa notam Cll aP prefixul de lungime p al sirului a. 0 subproblema a problemeidate consta in a imparti aP in m numere nenule a carer suma sa fie maxima.

• 1<n<501.• O<si<1000, pentru orice lSiSn.• In orice distributie, nici 0 suma nu poate sa tnceapa cu o.• Orice suma dintr-o distributie trebuie sa fie nenula,

Restrictii # precizdri

Fi§ierul de intrare aume , in contine pe prima linie 'un numar natural .n, reprezentandnumarul de zile de .activitate, Pe linia urmatoarese afla n numere naturale separate prinspatii, 5 15:<. •••. sn' reprezentand sumeleatribuite de sfatul tihii.

Date de iesire

Fisierul de iesire suma.olit va contine a singura linie pe care va fi afisat un singurnumar natural, reprezentand prima rotala maxima ce se poate obtine.

'Pentrunum3.ruI-dezile nsi cele n .sumestabiltte desfatul ~riipentru Jfbal, scrieti unprogram .care sa -determine cea mai mare prima totala cese poate obtine prin unirea §i.despartirea eifrelor sumelor date.

.primease~.eel putin .ungalben pentru iiecare dintre zilele de activitate. Astfel, daca are

.doar 5 ztle deactivitate, 1'1~tite eu 23, ·41 7, .205, 5 ~i respectivc n.de .galbeni, in total680 .de -galbeni, .el poate .opta pentru.o nona distributie a .cifrelor numerelor stabilite .demarele_sfat;astfel::pentru::prima'zi cere 2 ·galbeni, pentru adoua 3,pentru.a treia ·417,pentru;apalra 205 ,~i pentru.a cmcea 540 degalbeni.rprimind astfel a i sv de galbeni in.total.

}

rez=nrp[Lq-l]:

zeturn '.1;

:int main (void)

citire 0;dinamic () ;

afisare () ;return 0;

void afisare(void)file=fopen(OutFile," wt");fprintf (file, "%d\n", rez);

fclose(file) ;

'PROGRAMAREA iN LlMBAJUL.C/C++ PENTRU LICEU

voi.d -dinamic'(voicl)int i, j,nrp[LgMax], nrmin;~or (1=0; i<Lg; i++)

if (palindrorn(O,i» nrp[i]=l;

-else(nrmin=LgMax+2:£or (j=O;j<i;++j)

.if (palindrom(j+l,i) && nrp[j] <nrmin)

nrmin-nrp [j ] ;

nrp[i]=nrmin+l:

int palindrom(int inceput,~nt 'sfarsit).{ whi1:e (inceput<sfarsi t)

·.{i-f (s (inceput'] 1=5 [sfarsitl) xeturn 0;

_inceput++; sfarsit---;

194

,;

l I

rl j Stabilirea structurilorde .date

Deoarece informularea subproblemelor Intervin.douavariabile (p, lungimea prefixului,n $i m, numarul de valori nenulece -se vor obrine), -deducem caeste necesar .unaabloul,J bidimensional amax ,ell L linii '~i ncoloane;cll.semnificapa"di -smax [p) Iml reprezinta

suma maxima ce .se poate -obrine-adunand celem numere in care ,fmpartUnpe .as sau ; .i ,

daca 0 astfelde impartire nu se poate obtine.r-tI 'i. j Determinarea relatiei de recurenta

197

/*citim numarul curent intr-un sir de caractere*/fscanf (fin, U%s" ,Sir_Dr);

/* concatenam numarul curent la sirul cifrelor */strcat(sir, sir_or);

}

/* determin numarul total de cifre */L=strlen (sir) ;

/* tranSform caracterele in cifre */£or (i=1;i<=L; i++)

a{i]=sir[i-1J- 101;

fclose(fin);)

void'Ci-tire (void)

{F.ILE'* .:fin=fopen (··suma.~n", ·"r");:int i;.char :sir_nr[16], sir lmaxn I ;£scanf (fin, "l%d", .&n);£or (i=O; i<n; i++)

(

METODAPROGRAMARIl DlNAMlCE

void Rezo1vare(void)lint i, j;

~ong suma;

/* intializare */~or (i=O; i<4; i++)

for (j=O; j<=n; j++) smax[i] [j]=-l;smax[O] ['0]=0; smax[1] [1]=a[1]; smax[2] [1]=a[1]*10+a[2J,.if (a[2]) smax[2] [2]=a[l]+a[2];

smax[3J [1]=a[lJ*100+a[2J*10+a[3];if (a[2]) smax[3J [2]=a[1]+a[2]*10+a[3];if (a[3] && smax{3) [2]<a[1]*10+a[2]+a[3])

smax[3] [2!=a[1]*lO+a[2]+a[3J;if (a[2] && a[3!)

smax[3J [3]=a{lJ+a[2l+a[3];for (i=4; i<=L; i++)

(

smax[i%4) [0]=smax(i%4] [1J=-1;for (j=2; j<=i; j++)

{if (a[i]==O) smax[i%4] [jJ = -1;e1se

{

/* folosim 0 singura cifra */if (smax[ (i-1+4)%4] [j-l] !=-1)

{suma=smax [ (i-1+4) %4] [j -1 J +a [i] ;

smax[i%4] [j]=suma;}

PROGRAMAREA IN UMBAJUL C/C++"PENTRU DeED1%

r-i

rI ,. ,

r

Studiem inprimul rand cazurile elementare,pentru p = 1, 2, 3 :

ii . smax[ll [l]=alll; smax[l] [m]=-l, pentrum=2, n;Lj". smax[2] [1]=a[11*10+a[2J;

• smax [2] [2) =-l,daca a [2] =0 san a [1] +a [2]. daca a [2]*0;n • smax[2] [m]=-l, pentru m=3, n;

: : • smax[3) [1]=a[1]*100+a[2]*lO+a[3];1.-' {a l l J+at Zl*10+al31,dadi a[21:;t:O;

• smax[3] [2] = max a[1]*10+a[2]+a·[31.dacaa[3];cO;n -1,daclia[2!=a[3]=O};l,j • smax[31 [3]=a[1]+a[2]+a[3]. daca a [2]:;i;O §i a[2]*,0 sau -l,altfel;

• smax[3] (m]=-l, pentru m=4, n.

Formula generala, pentru p>2 :

smax Ip l [m] =max{

smax[p-1] [m-1]+a[p], daca a[p]*OII al m-lea numar este format numai din cifra a [p]smax [p-2] [m-1] +a [p-1] *lO+a [p] • daca a [p-1] *0II al m-lea numar este format din cifrele a [p-l ] a [p]smax [p-3] [m-1] +a [p-2] *lOO+a [p-1] *lO+a [p] • daca a [p-2] *0Ilal m-Iea numar este format din cifrele a (p-2] a [p-1] a [p]-1, daca a[p-2]=a[p-l!=a[p]=O

)

ni j

nImplementarea relatiei de recurentaL. J Vom rezolva recurenta in mod bottom-up, determinand suma maxima pentru prefixul de

lungime 1., apoi pentru prefixul de lungime 2, 3, ...• L.r Observam ca pentru a calcula linia p din matricea smax sunt necesare numai liniileI p-1, p-2 §i p-3. Deci nu este necesar sa stocam toata matricea smax, sunt suficienteL...., aceste 3 linii §i linia curenta, pe care urmeaza sa 0 calculam, Deci,matricea smax va

avea 4 linii §i n coloane. Inijializam liniile 1. 2, 3 conform relatiilor precedente. Lan fiecare pas i=4, L determinam linia rezultat pe linia i%4 a matricei smax.

l. j I #include <stdio. h>#include <string.h>#define maxn 2000int a[maxn], L, n;10ng smax[4] [maxn];

r

Ldcusta

Cerinta

Gasiti traversarea pentru care suma celulelor vizitate este minima.

Se considera A 0 matrice cu m linii ~i n coloane cu componente numere naturale.Traversam matricea pornind de la coltul din stanga-sus la coljul din dreapta-jos, tacandcate un salt pe orizontala ~i un pas pe verticala.

Un salt inseamna ca putem trece de la 0 celula la oricare alta aflata pe aceeasi Iinie,iar un pas inseamna ca putem trece de la 0 celula la celula aflata imediat sub ea. Astfel,traversarea va consta din vizitarea a 2m celule. I

I~

: iI 'l.J

199

Olimpiada Judeteana de Informatica, 2005

ExpliauieDrumul este :(1,1)~(1,3)~(2,3)~(2,2)~

(3,2) --> (3, 3) --> (4,3)--> (4, 5)

ME10DA 'PROGRAMARU·DINAMICE

lacllsta.out28

lacusta.in

Exemplu

4 53 4 5796 6 34 46 3 3 9 665382

Stabilirea structurilor de date

Pentru a retine solujiile subproblemelor vom construi 0 matriee B, eu mlinii ~i n coloane,ell semnificatia ca B[i] [j J reprezinta suma minima care se poate objine din coljulstanga-sus pana la elementul A(i] [j] .

Evident, solutia problemei date este :

min{B[m-1) [jII0$j<n-1}+A[m-1j [n-1]

.Date de .intrare

·Fi~ierul -de .intrare lacus tao in'continepe .prima Hniedoua numere naturale 'separateprin :;spapU.m :§i .n, .cu .semnificatia-din ,:enunl.Pe urmatoarele m Iinii oeste descrisa.matricea, tite n .numere pe fiecareJinie. 'Numerele,de pe aceeasi Iinie .sunrseparate princate'un singur spatiu .

I

Date de iesire

Prima linie a fisierului ·de iesire lacus ta . out va .eontine suma minima.

Soltqie

Identificarea subproblemelor

Problema cere determinarea sumei minime ce se poate obtine din coltul din stanga-sus(Ala] [0]) pad in coltul din dreapla-jos (A[m-1] [n-1]), traversiind matricea inconditiile specificate.

o subproblem a problemei date consta in detenninarea aumei mmime, care.se poateobtine pornind din coltul din stanga-sus pana la fieeare element A[i] [j J al matricei,'Vi, j; O;5;i<m, O;5;j<n.

Restrictii

• 3::;;m, n::;;100;• A[i] [j]:::;;255, V O:::;;i<m, O;S;j<n.

'<1'

'PROGRAMAREAiN LIMBAJUL'C/C++ 'PENTRUUCEU

}

if (a[i-2]>O)

{

/* 'foLo s Lm trei cifre* /.if (smax( (i-3+4)%4] [j-ll !=-1){aumaesmax l (i-3+4)%4] [j-11+

a[i-21*100+a[i-ll*lO+a[i];•1.f (suma>smax[i%4] [j) -smax l L'se l [j ]=suma;}

..if (a[i-.1]>O){

I~ folosim doua ciIre '~/

-j"f (smax [ Ci-'2+4 )"4;4] Ij--1 ]'\=-1.)

Leumaesmax l (i-2+4)-'%4] [j-1.]+a[i-J.]~J.O+ali-];

.if (aumec-smax l.L'sa l [j]) -smax[J;%4] [j]=suma;}

1.nt main (void)

{Citire ();Rezolvare () ;Afisare () ;%'eturn 0; }

-vo1.d Afisare (vo1.d){FILE * fout=fopen (..suma. out", "w");

fprintf (fout, "%ld\n", smax[L%4] [n]);fclose (fout);

198

::=-~:=:-_'':.::~:-':::. 'iN LlMBAJULC/C++ ·PENTRU LlCEUMETODA PROGRAMARII DINAMICE 201

Ilminimul pe ultima linie

B[i+ll [j]=min2+A[i] [j]+A[i+1] [j];I

;i-f ($[i] [j]<min2) min2=B[i.] [j];

:£or (j=O; j<n; j++)

.if (j!=jmin)B[i+l] [jl~min1+A[i] [j]+A[i+l] (j];

.else

)

min1=8[m-1] [0];£or (j=l; j<n; j++)

if (Blm-1) [j]<min1-)min1=B[m-1] [j];

fout=fopen("lacusta.out", "wt");fprintf(fout, "%u\n", minl+A[m-1] [n-1]);fclose(fout);return 0;

Paragrafare optimala

Cerinta

Sa se determine 0 paragrafare optimala (de cost minim).

Fisierul de intrare text. in va contine pe prima linie numerele naturale N §i M, separateprintr-un spatlu. Pe fiecare dintre urmatoarele N linii este scris un cuvant.

Date de iesire

Fisierul de iesire text. out va contine pe prima linie costul paragrafarii optimale. Incontinuare, in fisier va fi sensa pagina de text formatata conform cerintelor din enunt.

Date de intrare

Se considera a secventa de N cuvinte §i un numar natural M. Se cere sa se fonneze 0

pagina. de text din aceste cuvinte in felul urmator :

- fiecare linie a textului sil' fie de eel mult M caractere ;- ordinea cuvintelor ramane cea din secventa initiaHi ;- dona cuvinte vor fi separate prin exact cate un spatiu ;- pe fiecare rand vor fi puse un numar intreg de cuvinte.

o astfel de aranjare in pagina se numeste paragrafare.Se noteaza ell S1' 82, .. " Sp numarul de spatii ramase Iibere la sfarsitul fiecarui rand,

. ell except~a ultimului. Costul unei paragrafari este S13+S23+... +s/.

#include <stdio.h>#define M 100int main ()

FILE * fin, * fout;unsi.gned A[Ml [M), 8 [M] [M), m, n , L, j, mLnL, min2, jmin;

fin=fopen("lacusta.in", "rt");fscanf{fin, "%u %u", &m, &n);for (i=O; i<m; i++)

for (j=O; j<n; j++)fscanf (fin, "%u", &A[i] [j]);

fclose(fin) ;8[1] (0]=32000; Ilinfinitfor (i=l; i<n; i++) Ilinitializarea celei de-a doua linii

B[l] [i]~A[O] [O]+A[O] [i]+A[l] til;

for (i=l; i<m-1; i++){Ilcalculez doua valori minime pe linia iif (B[i] [O]<~B[i] [1])

{min1=8[i] [0]; min2=8[i] [ll; jmin=O;

el.se{minl=8[iJ [1]; min2=B[i] [0]; jmin=l;

for (j=2; j<n; j++). Ilparcurgem liniaif (8(i] [j]<min1)

{min2=minl; min1=B[iJ.[j]; jmin=j;}el.se

III

I

r

; .J

.c,

nI ', II ,, .

n, ,, Il;

iI

r-i,,

I

Rezolvarea relatiei de recurental j Subproblemele problemei date nu·sunt independente, deci vom rezolva relatia de recurenta

in mod bottom-up, determinand suma minima ce se poate obtine pe un traseu intr-oi' matrice de doua linii, de trei linii §.a.m.d.

In calculullui B[ i J [j J este posibil sa intfunpinlim 0 problema: elementul minim depe linia i-I sa se gaseasca chiar pe coloana j. In aceasta eventualitate, vom calcula

....... min1 §i min2, doua valori minime de pe linia Le-L.

: I,j i

,:.i Detenninarea relatiei-de recurentii

'. B [0] [O]~A[O] [0]~ • B[Ol [i)=oo, 'V o-ct-en\ ! (Nu putemajunge Ja elementul A [OJ til 1lIc3nd un saltsi un pas.)

• B [1.] [0]=00r-t (Nu putem.ajunge Ia elementuI A [1] [0] facand un salt si un pas.)I '. B[l] [j]~A[OJ [OJ+A[OI [j]+A[l) Io L, 'if O<j<n: i (Facem un salt pauli la elementuI A. [0I [j] • apoi un pas pauli la A[1] [j J .)

• a l Ll [j]~A[i] [j]IA[i-l] [j]+min{B[i-l] l k l ! nxkcn , k"j}

r"'"l .• Pentru .a ajunge in A[i) [j] 'am facut un pas de pe elementul A [ i -1] [j] "iarpentrui: a ajunge pe elementul A[i -1] [j j .am flicut un salt." • Elementul A[i-1] [kmin]depe carese face saltul este ales astfel tncar sa

B[i-1] [kmin)= min{Bli-ll [k] 10~k<n, k;t:j}.

r,

'. 1~N:::;;100;

• 1~~50;

.. Lungimea unui cuvant ;S; -M.

Solutie

Identificarea subproblemelor

Vom considera ca subproblema a problemei date paragrafarea optimala a secventeifermata din cuvintele i ~ i +1, "', N, ell l;S;i::;;N.

voi.d citire () ;voi.d dinamica () ;void afisare () ;

203METODA PROGRAMARn DINAMICE

S~ -determinam cost [i r,

Daca itoate cuvintele .t., i+l, ...• N,incappe aceeasi Iinie • .atunci -cos t; [i J=O '§iu1tim[i]=N .

in caz contrar, vatrebui 'sa-disrribuhn cuvintele .L, i+1, ... , N pe mai multelinii.Cuvantul ipoate :fi plasat -singur pe .oIinie. in acest <:az,coslUl paragraflirii va :fi

(M-lg[i])3+coSt[i+1]. -undecu 19[i] am .notat -lungimea cuvantuhn L, iarllltim[i]=i. I

Cuvantul i poate fi plasat:pe .aceeasi Iinie ell alre cuvinte (i+1, i+2, ... , j), eui<j<N, .daca este posibil (lg [i JHg [HI J+ ... +lg [j J+j -i~).

jnaccst ultim caz, ultim [i 1-j, iarcostul paragraftirii va fi (M- (lg [il +lg [i+l 1++lg[j l+j-i» 3+cost[j+l].

Evident, -se va .alege varianta pentru care -se obtine minimuj.

Rezolvarea relatiei de recurenta

Yom rezolva relatia de recurenja in mod bottom-up. Pentru a optimiza aIgoritmnl Yomutiliza un vector 51g en N componente, avand semnificatia eli s1g[i] reprezinta sumalungimilor cuvintelor 1. 2. ...• i.

-H=include <fstream.h>-H=inc1ude <string.h>.:/I:define InFi1e "text. in".:/I:define OutFile "text.out"-#de:fine NMax 101.:/I:define MMax 51

-H=define p3 (x) (x) * (x) * (x)

.int Nt M;

int s1g [NMax] ;char c[NMax] [MMax];~ong cost[NMax], ultim[NMax];

text_out

510A £ost odataca-n povestia fast caniciodatadin rude mariimparatesti 0

prea frumoasafata

PROGRAMAREA iN LIMBAJUL C/C++PENTRU LlCEU

text.inl7 l5A

fastodataca-npovestiafastcaniciodatadinrudemariimparatestiapreafrumoasafata

Exemplu

Restrictii

202

Stabilirea structurilor de date

In formularea unei subprobleme intervine 0 singura variabila (L, numiirul de cuvinte dinsecventa), Prin urmare, pentru a rejine costuI paragrafarii optimale este necesar unvector cost ell N componente, unde cost [i} reprezinta costul paragraflrii optimale acuvintelor i, i+1, ... , N.

Deoarece problema solicita §i solutia optima, nu numai costul acesteia, este necesarsa retinem informatii suplimentare care sa ne permitli reconstituireasolujiei. Vom utilizaun vector ul tim en N componente, cu semnificatia ca u1 tim [i I reprezintli ultimulcuvant de pe linia pe care este plasat cuvantul L.

Determtnarea relatiei de recurenta

Evident, cost [N] =0. deoarece spatiile suplimentare de pe ultima linie a paragrafului nuse contorfzeaza §i ul tim [N] =N.

int main (){

citire (");dinamica () ;afisare () i

return 0;

void citire ()(int i;

ifstream fin(InFi1e);fin»N»M;fin.get ();

...J

,..-J

l.,...;

i

21"__.:..:=-_..:.=-".,:--.:::::. iNLlMBAJUL C/C++ PENTRU LICEU METODA PROGRAMARII DINAMICE 205

Date de intrare

Date de iesire

Cerintd

Olimpiada Judeteana de Informatica, 2002

cod.out75

Cod

cod.in7145

'847835

Soltqie

ldentificarea subproblemelor

Date fiind doua numere naturale x §i Y, de n §i, respectiv, m eifre, problema cere sa.determinam eel mai mare numar care se poate obtine prin stergerea unor cifre din x,respectiv prin stergerea unor eifre din Y.

Solutia este lungimea celui mai lung subsir comun al sirurilor X§i Y. Daca exista maimuIte subsiruri comune de lungime maxima, numarul eerut de problema este subsirulcomun de lungime maxima pentru care numarul corespunzator are valoarea eea mai mare(prima cifra a numarului are valoare maxima ; daca exista mai multe solutii eu prima cifrade valoare maxima, se alege varianta eu cea de a doua cifra de valoare maxima s.a.m.d.)

Putem reformula problema -astfel: sa se determine eel mai lung subsir comun alsirurilor X si Y, iar daca exista mai multe solutii, sa se determine solutia pentru carenumarul corespunzator este maxim.

Pisierul de iesire cod. out va contine pe prima linie p, codul celui mai evoluat stramoscomun at lui n §i m,

Fisierul de intrare cod. in contine doua linii. Pe prima linie se afla n, codul caraeteristical primului organism, iar pe cea de a doua, m, codul caracteristical celui de-al doileaorganism.

Exemplu

Date fiind codurile caracteristice ale doua organisme vii diferite, scrieti un program caresa .determine codul caracteristic at celui mai evoluat stramos comun al lor.

Principala misiune a unei expedijii stiintifice este.de a -studiaevclutia viejf -pe 0 planetanou descoperita, in urma -studiilor efeetuate, cercetatorti au asociat fiecarui organism viu.descoperitpeacea planet! un cod caraeteristic. Codul earaeteristic este un numar natural-de maximum 200 decifre zecimale nenule.

Cercetatorii au observat ca pentru orice organism viu de pe planetiicodurile carac­'reristice.ale stramosilor sai, pe scara evolutiei.ise pot obtine prin stergerea unor cifre dincodul caracteristic al organismului respectiv, iar un organism este cu atat mai evoluat eucat codul sau caracteristic .are 0 valoare -mai mare.

.£or (i=J.; .i<=N; i++)(£±n.get~ine(c[i], MMax);s~g [i ]=s~g [i-~]+.str.~en tc Id l )-;

fin. close () ;

void .dinamica ()tint 3., j;cost[N]=O: ultim[N]=N;£or (i=N-1: 3.>0: i--)

if (slg[N)-slg[i-1]+N-i<=M)/Icuvintele i, i+1, ... r N incap peultima linie?

{cost[il=O; ultim(i)=N;}

~J.se

{/Icuvantul i este plasat singur pe 0 liniecost[i]=p3(M-slg[i]+slg[i-1])+cost[i+11;

ultim[ij=i;for (j=i+l; j<N; j++)

/Iplasam cuvintele L, ... , j pe aceeasi linie{:if (slg[j]-slg(i-1]+j-i>M) //daca nu incap

break::if (cost[i]>cost[j+l]+p3(M-(slg[j]-slg[i-l]+j-i»)

(cost[i]=cost[j+1]+p3(M-(Slg[j]-slg[i-l]+j-i») :

ultim[i]=j; }

void afisare ()tint i, poz;ofstream fout(OutFile):fout«cost[l]«endl;poz=O; //ultimul cuvant afisatwhil.e (poz+l<=N)

{

for (i=poz+l; i<ultim[poz+l]: i++)zcutc cc tLj c-c ' ';

fout«c[ultim[poz+l]]«endl;

poz=ultim[poz+l];}

f out; , close (); }

,....,,,i I, .

", '

1, "

IiIi ,

,II

,....,, I

I

,....,, ,, 11 1l J

", ,I '

I

r-:l j

r III j

r1

l i

r-:

r

,,

I'

Rezolvarea relaiiei de recurentaRezolvam relatia de recurenta in mod bottom-up:

void dinamic (){int k, h;for (k=n-1; k>=O; k--)

for (h=m-1; h>=O; h--)if (x[kl==y[hj)

Lc s l k l [hJ=l+les[k+l1 [h+ll;

else

rl

,":': \

-'07

if (les[k+lJ [hJ>les[kl [h+l])

.Lca [kl Ih le.Lca [k+ll [hI;!S~se

Loa l k l [hJ=les[kl [h+ll;

METODA PROGRAMAJu! DINAMICE

int main ()"ci tire () ;dinamic () ;afisare () ;return 0; }

'"Void afisare ()(ofstream fout("cod.aut");Byte d[NMax);int h=O, k=O, ix, iy, max, paz=O;£or (i.nt i=lcs[O] [0]; i>O; i--)

{/* caut pozitia deinceput a unui subsir de lungime icare incepe cu cea mai mare cifra*/

max=-l;for (ix=h; ix<n; ix++)

£or (iyck; iy<m; iy++)·if {Lc s l Lx l [iy]==i && x[ixl==y[iy) && -max<x[ix])

( max=x[ix]; h=ix; k=iy; }d[paz++]=max; }

for (k=O; kcpc a s. k++) fout«d[k];fout«endl; fout.close(); }

Domnul G are de ureat 0 scara ell n trepte. In mod normal, la fiecare pas pe care il face.el urea 0 treapta. Pe k dintre aceste trepte se aflA care a sticHi cu un numar oareeare dedeeilitri de apa, fie aeesta x. Daca bea toata apa dintr-o astfel de sticla, forta ~i

mobilitatea lui G erese, astfel ineat, la urmatorul pas, el poate urea pana la x trepte, dupacare. daca nu bea din nou, revine la "nonnal". Sticlele eu apa nu costa nimic. Canttrateade apa continuta de aceste stiele poate sa difere de la 0 treaptli la alta.

Pe j trepte se afla cate a sticla eu bautura energtzama. Si pentru aceste sticle,eantitatea de bautura energizanta poate sa difere de la 0 treapta la alta. Sa presupunemca tnrr-una dintreaceste sticle avem y decilitri de bautura energizanta, Daca bea q (q$y)deeilitri dintr-o astfel de sticla, la urmatorul pas G poate urea piinllla 2q trepte, dupacare. §i in acest caz, dad nu bea din nou, el revine la "normal". InsA bautura energizantlicosta: pentru a cantitate de q decilitri consumati, G trebuie sa plateasca q lei grei.

Pot exista trepte pe care nu se afla nici un pahar, dar lji trepte pe care se atla atat 0

sticla cu apa cat si una cu bautura energizanta, In astfel de situatii, nu are rost ca G sabea ambele bauturi, deoarece efectul lor nu se cumuleaza ; el poate alege sa bea unadintre cele doua baururi sau poate sa. nu bea nimic.

Scara

l'ROGRAMAREA .IN LIMBAJUL C/C++ 'PENTRU LlCEU

#include <fstream.h>#include <string.h>#define NMax 201typedef unsigned char Byte;Byte x[NMax], ~[NMax], lcs[NMax] [NMaxl, n r m;

void citire ()ifstream fin("cad.in U

) ;

fin.getline(x, NMax); n=strlen(x);fin.getline(y, NMax); m=strlen(y);

fin.claseO;

Notaro ell xk=(xt..,~2' .•.• ·x

lo) (prefDruI'luLx:de1ungime k):-§i ell yh=(Yl' 'Y2' ····.·yh)

prefixullui y odelungime .h..Osubproblemli .a-problemeidate .consta in determinareacelui:maiiung:-sub§iricomun.al <§lrurilorxl: §iyh.

Stabilirea"'tructurilor de -dateVom unliza o matrice les ·CU n linii "§i m coloane, cu.semniticatia :

.Lcs [k] [h] -= lungimea celui mai Iungsubsir comunal:§irurilor xl: §i yh.

Lungimea -numiUului cerutin problema va fi .determinata in les [0] [Or.Nu vom.utiltza un tablou suplimentar pentru -reconstituirea .solutiei, ci vom construi

solutia bazandu-ne pe informatiilememorate in .tabloul Loa, Prin reconstinrire vomobtine solutia in ordine mversa, dinacest motivvom memora solutia intr-un vector d,pecare il vom aflsa ·de la sfarsit catre inceput.

Determinarea Tela/iei de recurentaObservam ca daca Xk=Y

h,atunci les [k] [h]=1+1cs [k+1J [h+l]. Daca x](-:I=yh , -atunci

lcs[k) [hj=max{lcs[k+11 [hI, Loa l k l [h+1]}.Din observatia precedenta dedueem easubproblemele problemei datenu sunt inde­

pendente ~i ca problema are substructura optimala. Caraeterizlimsubstruetura optimalaa problemei pt-in urmatoarea relatie de -recurenta :• lcs[k) [O)=lcs[O] [h]=O. 'ifke{1. 2, ...• n} , V'hE{1. 2 •...• m j ;

{

l +l e S [ k - l l [ h - l l , d aea X [ k l = Y [ h l ; .

• Lc e l k l Lh l v

max! les [kl [h-l I, les [k-ll [hI I, daca x [kJ*y u.i.

206

1 i

nRestrictiiIt, ;. n$120.

• O~k::;n.n. 0$5$0.I ! • Cantitatea de apa aflata in oricare sticla este 1'::;;x$10Q.l J • Cantitatea de bautura energizanta aflata in oricare sticla este l$y$l a o.

,,

:Cerinta_ Detennina\i p, numarul minim de pasi pe caretrebuie 'Sni fac~ G pentru a urcascara,: ;precum §i .suma minima ce .trebuie sa '0 cheltuiasca pentru a urcascara ,in P pasi., :L. ,;

Date de intrare

rFi!iierul text de intrare .s caxe . in contine :: i

t.:_ pe prima Iinie, un numar natural n , ~prezentandnumarultota1.de trepte;pe eea de a doua linie, un numar natural k, .reprezentand numarul de trepte pecare

;"1 se afHi sticle ell apa ;: : _ pe fiecare dintre urmatoarele k Iinii, cate dona numere naturale separate prin spatiu,l; reprezentand numarul de ordine al treptei 'pe care se afla 0 sticla ell apa §i. respectiv,

cantitatea de apa din acea -sticla, exprimata in decilitri ;n - pe urmatoarea linie, ,un numar natural j, reprezentand numarul -detrepte pe care sej, afla stic1e ell bautura energizanta ;I .j pe fiecaredintre urmatoarele j linii, cate doua numere naturale 'separate prin spatiu,_ reprezentand numarul de ordioe al treptei pe care se afta 0 sticla cu bliuturil energizantai I si, respecriv, cantitatea de bautura energizanta dinacea sticla, exprimatli in decilitri.i, "

Date de iesirenPisierul text de iesire scara. out va contine 0 singura lime pe care vor fi sense doua, j numere naturale. p §i c. separate -printr-un spatiu, p reprezentand numarul minim de

pasi, iar c suma minima cheltuita.

PROGRAM.A.R.E.A iN LIMBAJUL C/C++ PENTRU LICEU 209METODA-PROGRAM.ARII DINAMICE

int N, apa[MAX_N], sue[MAX_N];int nrpasi[MAX_N], sum[MAX_N];

Rezolvarea rekutei de recurenja

#inelude <stdio.h>#define MAX_N 121#define FIN "seara. in":ltdefine FOUT "seara·.out"#define INF 10000#define cmp (a, b, e, d) « (a) < (c ) I I «a) == (cl s s (bl < (dl l)

Pentru a rettne solutiile subproblemelor vomutiliza doi veetori (nrpasi §i sum) euN componente, cusemnificatiile :• nrpasi [i] reprezintii nuniarulminim de pasi necesari pentru a urea treptele 1•...• i ;• sum[i] reprezintli suma minima cheltuita pentru a urea treptele 1. 2•...• i ell

nrpasi [i] pasi,

Determinarea reltuiei de recurenta

Daca ne aflam pe seara i avem trei posibilitati :- faeem un pas ~,normal"; tn acest caz, vom ajunge pe treapta i+l §i veriflcam daca

accasta modalitate de a ajunge pe treapta i+l este mai eficienta (nrpasi [i+ 1] >nrpasi[i]+l I I nrpasi[i+l]==nrpasi[i]+l && sum[i+lJ>sum[i]);daca avem epa, atunei bern q dl de apa (q=l, apa [i]) §i ajungem facand un singur

,pas pe treapta i +q; verificam daca aceasta modalitate de a ajunge pe treapta i +q estemai eficienta (nrpasi[i+q]>nrpasi[i]+l II nrpasi[i+q]==nrpasi[i]+l&& sum[i+q]>sum[i]);daca avem sue. bern q dl de sue (q=1 , sue [i ] ) §i ajungem faea.ndun singur pas petreapta i+2q; verificam, de asemenea, daca aceasta modalitate de a ajunge petreapta i +2q este mai eficienta, caz In care 0 retinem.

Solutie

jdentificarea subproblemelor .

Vom considera casubproblema a-problemei .date .determinarea numarului minim de pasipentru a urcatreptele .1, -2,_'~", i §l .a sumei minime cheltuite pentru a urea treptele1. 2, _... ~ i~-eunumarminimde pasi.

Stabilirea structurilor de date necesare .1

Pentru a retine mformatiile despre stielele .de epa. respectiv sticlele de sue vom utilizadoi vectori (apa ~i sue) eu N componente, ell .semnificatiile :• apa (i] reprezinta.canritatea de epa aflata pe treapta i ;

• sue [i] reprezinta cantitateade suc aflata 'pe treapta i.

'1I

scara.ou4 1

Olimpiada Judeteana de Informatica, 2005

6

11 22

4 11 1

scara.inscara.out3 2

208

n Exemple, ,I ,l"j scara. in

6

'i 1

1 22

4 1n

1 2

I, j

"i I,

void eitire(void);void afisare(void);void dinamie(void);

II

:intmain (void)

PROGRAMAREA INLIMBAJUL C/C++"'PENTRU LlCEU

citire () ;

dinamic ();afisare();return 0;

211METODA PROGRAMARn DINAMICE

(nrpasi[i+q]=nrpasi[i]+~;

sum [.i+q]=sum [i ..]; )

/Idaea exista .auc -pe treapta i _,..:if (sue [.i])

£or (q=l; Q<=2*sue[i] && i+q<=N; q++)I/beau qdl de sueif (cmp(nrpasi[i)+l,sum[~)+«q+l)/Z),

nrpasi[i+q),surn[i+q))( nrpasi[i+q]=nrpasi[i]+l;

sum[i+q]=sum[i]+«q+l)/Z);

Polipe

Gigel §i Castel sunt doi polijisti eu experienta. Ei lucreaza tmpreuna de multi ani §i demulte .. ori au fast nominalizati pentru premiul ...Pohtistul anului". Anul acesta sunthotarati sa-l casnge §i pentru .aceasta trebuie sa incaseze cat mai multi bani din amenzi.In fiecare zi, Gigel §i Costel stau in tura 'r minute §i pot aplica trei tipuri de amenzi :

iExercuiu

Modificati programul precedent 'astfelincat sa reconstituie si solutia optima.

1

&1, &j);

&i, &j);

}

&K) ;

n%d %d",

)

"%d %d Ol,

for (; K>D: K--){fscanf(fin,apa(i] = j;

fscanf(fin, "%d",for (: K>O: K--)

(fscanf(fin,s uc I Lj = j;

fclose (fin);

}

void citire ()

lint i, j, K:

FILE * fin=fopen (FIN, "r");fscanf (fin, "%d", &N);

fscanf (fin, "%d", &K);

210

II,i

~p,~~f:~~

iMII

IIiI:,IIJresI."

ib'"

-void afisare (){FILE * fout=fopen(FOUT, "w");

fprintf(fOllt, "%d %d\n", nrpasi[N], sum[N);fclose (fout);

void dinamic ()

lint i, qrnrpasi[l)=l;for (i=2: i<=N; i++) nrpasi[i]=INF;for (1=1; i<=N: i++)

{ Iliac un pas "normal"if (i<N && cmp(nrpasi[i]+l,sum[i],nrpasi[i+l],sum[i+l))

{ nrpasi(i+l1=nrpasi[il+l;sum[i+l) = sum [i); }

//daca este apa pe treapta i

if (apa[i])for (q=l; q<=apa[i) && i+q <= N; q++)

/ /beau q dl de apeif (cmp(nrpasi[i)+l,sum[i),nrpasi[i+q),sum[i+q]»

Tip Semnificatie . Suma Durata deincasata aplicare

1. Pentru pietoni care traverseaza 81 T1neregulamentar

2. Pentru soferi de autovehieule care tncalca 82 T2regulile de circulatie

3. Pentru soferi de masini grele, eli transport 83 T3ilegal de marfuri

Amenzile de tipul1 ~i 2 pot fi aplicate de un singur politist (Gigel sau Costel). Pentruo amenda de tipul 3, Gigel §i Costel trebuie sa lucreze impreuna (unul venfica aetele detransport, iar celalalt verified marfa).

Durata de aplieare a unei amenzi reprezintii timpul necesar polidsttlor pentru averifiea aete, a scrie proces-verbal etc. Daca un politist trebuie sa apliee 0 amenda larnomentul x, iar durata aplicarii amenzii este y, polttistul care aptica amenda va devenidisponibil abia la momentul x+y. Politistii nu fae minute suplimentare (mai exact, ei suntin aetivitate din minutul 1 pana in minutul T inclusiv). Pentru ca in noulcod rutier nule mai este permis politistilor sa traga soferii pe dreapta §i sa-i lase sa astepte, pentru aaplica 0 amenda de tipul 1 sau 2 trebuie sa fie liber macar un polidst, iar pentru a aplieao amenda de tipul 3. ambii pOliti§ti trebuie sa fie liberi la momentul in care survineevenimentul.

l......:

2[3METODA PROGRAMARII DINAMICE1IDDI'ror-otoJVr1l.0J<1l. TN LIMBAJUL C/C++ PENTRU LICEU2)2 ..---.--.- •• -.----

Solutie. Varianta I

Ideniificarea subproblemelor

Vom considera ca subproblema a problemei date determinarea sumei maxime ce 0 pottncasa cei doi poltjisti, penalizand prin amenzi evenimentele r , i+l, ... , N. In condiriilein care politistul 1 este disponibil la momentul t.L, iar politistul 2 este disponibil lamomentul t2.

Punctulde observatie de la intrarea in eras comunica pr'in statie celor doi polith~ti

evenirnentele din trafic, in ordinea in care aces tea survin. Daca nu pot aplica amenzipentru toate evenimentele ce intervin in trafic, ei vor fi nevoiti sa Ie aleaga pe acelea careIe aduc mai multi bani.

Cerinta

Scrieti un program care sa determine suma maxima pe care Gigel ~i Castelo pot incasadin amenzi, tnrr-o rura.

Date de intrare

Fisierul de intrare poli tie. in contine :

pe prima Iinie. numarul natural T, reprezentand durata rurei exprimata in minute;pe lima a doua, doua numcrc naturale. SIT1 (suma Incasata ~i durata aplicarii uneiamenzi de tipul 1) ;pe linia a treia, doua numere naturale. S 2 T 2 (sUIUa incasata $i durata aplicarfi uneiamenzi de tipu1 2) ;

pe linia a patra, doua numere naturale, S3 '1'3 (suma rncasata 1}i durata apficarti unciamenz! de tipul 3);pe linia a cincea, urt numar N (numarul de evenimente survenite in trafic) ;pe fiecare dintre urmatoarele N Iinii se afla doua numere naturale, tip timp (tip

poate fi 1. 2 sau 3 §i reprezinta ripul amenzii ce poate fi apficata ; timp reprezintatimpul la care a survenit evenimenrul , exprimat in numar de minute fata de tncepurutturei).

Exemple

politie.in

30010 20

30 30

50 25

8

1 5

3 103 201 1302 142

2 160

3 180

2 280

pOlitie.out

140ExplicatieAplica amandoi amenda de tipul 3 din minutul10, apoi Costel aplica singur amenda de tipul 1din minutul 130, apoi Gigel aplica singuramenda de tipul 2 din minutul 142, apoiamandoi aplica amenda de tipul 3 din minutul180.

Olimpiada Natlonata de Informatica, Buzau, 2004

Date de iesire

Numerele scrise pe aceeasi linie sunt separate prin care un spatiu. Evenimentele sunrin ordine cronologtca.

Fisierul de iesire pol i tie. ou t contine 0 singura lime pe care este scrisa SUIUa maximace poate fi incasata.

Restrictii

0<'1', '1'1,0<31, 32,

0<N<501

'1'2, '1'3<20133<51

Stabilirea structurilor de date

Deoarece in fonnularea unei subprobleme intervin trei variabile, vom utiliza pentrumemorarea solutiilor subproblemelor un tablou tridimensional smax (N 1 [T J [T], elisemnificatia ca smax [i] [t1l [t2] reprezinta suma maxima ce 0 pot incasa cei doipolitisti ell amenzile i, i + 1, ...• N, in conditiile in care politisrul 1 este disponibil lamomentul tl, iar politistul 2 este disponibil Ia momentul t2.

Determinarea relatiei de recureruaDaca evenimentul i este de tip 1 sau 2, atunci, pentru a calcula smax [i] [t1] [t2] vomalege dintre urmatoarele doua cazuri varianta optima:a) primul politist da amenda L, daca este posibil (tl :-::;: timpul de aplicare a amenzii i) ;b) al doilea politist da amenda i, daca este posibil (t2 :-::;: timpul de aplicare a amenzii L).

/*primul politist dA amenda */

Daca (tl<=t) atunci

riac a (smax[i] [tll [t2]< S[tipj+smax[i+lj [t+T[tip]] [t2])

smax[i] [tIl [t2j=S[tip]+smax[i+l] [t+T[tip]] [t2];

/*al doilea politist dA amenda */

Daca (t2<=t) atunci

ue c a (smax[i] [tlj [t2]< 3[tip]+smax[i+1j (tIl [t+T[tipj])

-amax [~) [tl] [t2] =5 [tip]+smax [i+l] [tl] [t+T [tip] ] ;

Daca-evenimentul i este de tip 3~ .ambti -polttisti -dau amenda, -daca-estepostbil ,(adica.daca tl_§i t2 .$timpul,de .aplicare.a amenzti.L) :

Dac.!i (tl-<=t.&& 't2<=t) .e t.unc.a

neca ('smax[i] ttl] [t21<S[3j+smax[i+l] (t+T[3]] [t+T[3]]) atunci

'srnax[i) [tIl [t2)=S[3]+srnax[i+l] {t+'I'[3]] [t+T[31l;

Rezolvarea relcqiei .de recuremaVorn -rezolva -relatia de recurenja in -mod bottom-up. Observam ca.vpentru -avcalculaoptimul :.amenzilor L, i+l, ...• ri , oeste necesar sa .cunoastem -valortle-optime-pentruamenzile i+l •...• n.

Prm urmare, pentru implementarenu -este mecesar .sa utifizamnm-aablou ctrtdi­-mensional. Sunt suficiente doua matrice patratice eu T linii $i T coloane (un-tablou relinedatele de la 'pasul precedent, iarin cclalalt tablou calcularn valorilede lapasulcurent).Complexitatea in spatiu aalgoritmului este 0 (T*T) , .iar complexitatea in timpesteo (T*T*N).

'PROGRAMAREAiN UMBAJUL ·C/C++ 'PENTRU LICEU214

IIIII

IIIIli!'

#include <stdio.h>#include <stdlib.h>#define InFile "politie.in"#define OutFile "politie.out"#define NMax 501#define TMax 302i.nt nr, S[4], T[4], Tura;struct Ev {int timp; char tip;} e[NMax];unsigned int * smax1[TMaxl * smax2[TMax];

void citire(void);void afisare(voi.d);void rezolva(void);

int main (){citire() ;

rezolva () ;afisare ();return 0:

voi.d citire(void)lint x , y, i, N, j;

FILE * f=fopen (InFile, "r");fscanf(f, "%d", &Tura);for (i=l; i<4; i++) fscanf(f, "%d %d", &S[i],fscanf(f, "%d", &N);nr=O:for (i=l; i<=N; i++)

(fscant(t, "%d %rl", &x, &Y);

&T[i]);

1I

I

METODA PROGRAMARII DINAMICE

if (y+T [x] <""Tura) {nr++; e [nr] • timp=;y; e [nr] . tip=x; })

:for (i=O; i<=Tura+l; i++)

{smax1[il-(unsigned *) calloc(Tura+2, sizeof(unsiqned»);.if (!smax1 [i])

{printf ("Mernorie insuticienta\n"); exit (1) ;.)

~or (i=O; i<=Tura+l; i++)

(smax2[i]={unsigned *) calloc(Tura+2, sizeof(unsigned»;-if (! smax2 [i])

{printt("Mernorie insuficienta\n"): exit(l);}

for (i=O; i<=Tura+1; i++)for (j=O; j<=Tura+1; j++)

smax1[i] [j]=smax2[i] [j]=O;fclose (f) ;

)

void afisare(void){FILE *f=fopen(OutFile, "w");fprintf(f, "%u\n", smax2[1] [11);fc1ose(f);

void rezo1va(void){i.nt t , tip, i, t1, t2;for (i=nr; i>=l; i--)

(

t=e [i) . timp; tip=e (i) . tip:for (t1=Tura; t"l>=l; t1--)

for (t2=Tura; t2>=1; t2--){

if (tip<3){/*primul politist da amenda */if (tl<-t)if (smaxl(tl] [t2J <

S(tip)+smax2[t+T[tip]] [t2])smax1[t1] (~2]=S[tipJ+smax2(t+T[tip]][t2];

/*al doilea politist da amenda */if (t2<=t)

i.f (smax1 [t1] (t2] <S[tip]+smax2(t1] [t+T[tip]])smax1 [tl J [t2] ""S [tip] +srnax2 [t1] (t+T [tip] I ;

el.se

215

216 PROGRAMAREA iN LIMBAJUL C/C++ PENTRU LlCEU

METODA PROGRAMARII DINAMICE 217

fj"1\l]

l~

~j"~~:

:1

I:,,~·I

l ~;<

~£ (tl<=t && t2<=t)i.£ (smaxl[tl] [t2] <

S [3] +smax2 [t+T [3]] [t+T [3)])

smaxl [tl] [t2] =5 [3] +smax2 [t+T [3] ] [t+T [3] ] ;

for (tl=Tura; tl>=l; tl--)for (t2=Tura; t2>=1.; t2--)

smax2 [tl] [t2] <ema x t [tl] [t2] ;

o Daca evenimentul i nu este de tip 3 :smax[iJ [i]=max(smax[i-l] [i-l], smax[Last[i]] [i-l]+S[tip])

Pentru i<j, smax[i] [j]=smax[j] til.

Rezotvarea relatiei de recurenpi

Relatia de recurenta va fi rezotvara in mod bottom-up. Complexitatea-spat;iu ~i comple­xitatea-timp pentru acest algoritm este 0 (N*N) . Implementarea 0 propunem ca exercitiu.

Probleme propuse

Soliqie. Varianta a II-a

Identificarea subproblemelor

Vom considera ea subproblema a problemei date determinarea sumei maxime ce sepoare obttne in conditiite in care primul pofitist da amenzi numai pentru unele dintreprimele i evenimente, iar al doilea politist da arnenzi pentru unele dintre primele j

evenimente.

Stabilirea structurilor de date

Deoarece in formularea unei subprobleme intervin doua variabile, vom utiliza pentrumemorarea solutiilor subproblemelor 0 matrice smax, CU N Iinii ~i N coloane, cusemnificatia ca smax La l [j} repreainta suma maxima ce 0 pot incasa cei doi politisti incondltiile in care primul politist da amenzi numai pentru unele dintre primele L eve­nimente, iar al doilea politist da amenzi pentru unele dintre primele j evenimente.

Incadrarea amenailor in solurie, pentru evenimente de tip 3, are loc numai la ca1cululpoziriilor din matrice de pe diagonala principala.

Pentru a ea1cula eficient elementele matricei, vom precaleula un vector Last CU N

eomponente, eu semnificatia ca Last [i} reprezinta ultima amenda mai mica decat L

care nu se suprapune eu L.

1. RecnqiIn prima zi de armata, la ordinul comandantuluicei N recruti s-au asezat in rand.Comandantul sufera ori de care ori lucrurile nu sunt in perfecta ordine, iar sirul formatde recruti era complet dezordonat. Prin urmare, comandantul soltcita ca un numarminim de recruti sa iasa din rand astfel Incat soldatii ramasi in rand sa fie in ordineastrict crescatoare a Inaltimilor,

Date de intrarc

Pisierul de intrare recruti. in conjinc pe prima linie numarul natural N, reprezentandnumarul de recruti. Pe cea de a doua Iinie se afla N numere naturale separate prin careun spatiu, reprezentand Inaltimile recrutilor, in ordinea in care acestia s-au asezat inrand.

Date de iesire

Pisierul de iesire recruti .out va contine pe prima l i nie un numar natural Lg,

reprezentand numarul de recruti ramasi in rand. Pe cea de a daua Iinie vor fi afisate LS

numere naturale separate prin care un spatiu, reprezentand tnaltimtle recrutilor ramasi inrand.

Restrictie1.s;NS1000

2. Deserto regiune desertica poate fi reprezentata printr-un tablou eu m Iinii si :: coloane.Elementele tabloului reprezinta diferentele de nivel fata de nivelul marii (cota 0).

Un beduin trebuie sa traverseze desertul de la Nord (or-ice element de pc Iinia 1) laSud (orice element de pe Iinia m). La fiecare pas e l se poate deplasa tntr-unul dintreelementele vecine cu eel in care se afla, in una dintre directiile SE, S, S'V.

Determinarea relcqiei de recurenta

Analizam eazurile i<j, i=j si i>j.

Pentru i<j :eo Daca evenimentul j este de tip 3 :

smax[i} [j] = smax[i] [j-l].o Daca evenimentul j nu este de tip 3 :

smax[i] [j]=max{smax[i} [j], smax[i] [Last[j] ]+S[tip]

Pentru i=j :Daca evenimentul i este de tip 3 :sma x li] [i] =max (smax [i-l] [i-l], A [Last til J [Last [i]] +S [tip])

Exemplurecruti.in

7

5 4 2 7 5 9 7

recruti.out

3479

ObservcqieSolutia nu este umca. Alte solutii posibilesunt 5 7 9, 4 5 9, 2 7 9,2 5 9 etc.

~

Ressrictii

• ISm. n::::aoo.• Cotele sunt numere naturale S 255.

Un 'traseu oeste considerat··optimal.;dacl1suma--diferentelor .de .nivel (Ia urcare §i Iacoborare) -este minima.

i.J

219

"T l JOIN T2

1 ·42 4l 4

METODA 'PROGRAMARu DINAMICE

7,1 ..

34

De.exemplu :T,1 1

2 1

1 3

Date de intrare

Se considera ca operatia .JOIN;se executa in P*Q operatii elementare, .astfel : -pentrufiecare linie din Tl' -se verifica fiecare linie -din-T2 §i se .testeaza.daca Jncepe cu al doileaelement -din linia din Tl; in caz .afirmativ, .se introduce. 0 linie -Irr tabela-reznjmr, Seconsidera ca acest pas face parte din-operatia elementara In care s-a verfficat continutuleelor doua Iinfi.

'Iabela-rezultar poateavea intre e-st P*Q linii, in functie de datele din Tl

~i T2"

Seobserva ca operatia JOIN 'nu este comutativa ftn exemplul precedent, calculand T2

JOIN T1• objinem o-tabela cu 0 linii). 1n schimh.-operatia este asociativa, .adica (Tl

JOIN T 2) JOIN T 3=Tl JOIN· (T 2 JOIN TJ

) .

Cerintd

Pisierul join. in contine pe prima linie numarul N de tabele. Pe urmatoarele Itnii se afladescrierile tabelelor, in urmatorul format:- prima linie a descrierfi unei tabele contine numarul L1 de linii ale acesteia ;- pe urmatoarele L 1 HnH se gasesc liniiJe tabelei.

Dandu-se un §ir de N .tabele T l • T2 ••••• TN' sa se determine. folosind asociativitatea,numarul minim de operatii elementare in care se poate efectua calculul T

lJOIN T2

JOIN .. : JOIN TN'

••

Date de iesire

In fisierul j o Ln , out se va afisa un singur numar Intreg, 'reprezentand numarul minim deoperatii elementare in care se poate efectua calculul precizat anterior.

Restricfii

3:S:N:S:30.

Numarul de linii din fiecare dintre tabelele date este mai mic sau egal cu 30"

Numarul de linii din arlee tabela rezultata pe parcursul efectuarii operatiilor nu vadepasi 10 8

". Numarul minim de operatii nu va depasi 108 •

1I

I

PROGRAMAREA iN LIMBAJUL C/C++PENTRU LICEU

Exemplu

desert.in4 4

1 4 4 35 50 75 4

6 5 4 4

6 5 1 10

3. JoinSe numeste tabela 0 matriee ell N.HnH ~i doua coloane, eu elemente Intre 1 l}i 4 inclusiv,in eare nu conteaza ordinea liniilor (deci, dou'a tabele se considera identiee daca suntidentice dupa ordonarea liniilor). .

Se defineste operatia JOIN pe dcua tabele T 1 ~i T 2• eu s, respectiv Q linii, avand ca

rezultat a tabela T. Operatia se efectueaza in felul urmator : pentf!l fiecare Iinie din Tl'

de forma x Y. se alege fiecare linie din T2' de forma Y Z, ~i se introduce in tabela-rezuhato linie de forma x z.

Date de iesire

Pisierul de Ieslre desert. out va coniine pe -prima linie suma diferentelor de nivelpentru 0 traversare optimala (minima), Pe urmatoarele m linii sunt descrise elementelematriceiprin care a treeut beduinul (care un element pe 0 linie). Pentru fiecareelement, sunt specificati indieele de linie ~i indieele de coloana, separati prmtr-unspatiu,

desert. out1

1 3

2 43 34 2

Olimpiada Nationala de Informatica, Slatina, 1995 - text modificat

Date de intrare

Pisierul de dntrare desert. in contine pe prima linie numerele naturale m §i n , separateprtntr-un spatiu. Pe fiecare dintre urmatoarele m linii se .afla care n numere naturaleseparate prin cate un -spajiu, reprezentand elementele matricei.

Cerintd

Data -ffind -matricea care repreztnta-desertul•.sa se determine -o:modalitateoptimaHi .deatraversa .desertul,

218

L.J

.220 PROGRAMAREA iN LLMBAJUL C/C+ + PENTRU LICEUMETODA PROGRAMARII DINAMICE 221

4. LaruIon este un lingvist pasionat. Recent, el a descoperit un text scris Intr-o Iirnba necu­noscuta. Textul este scris pe mai multe linii §i e format din cuvinte eli litere mici dinalfabetul latin, separate prin spatii sau/si semne de punctuatie (, :;.! 7-). Ion a festfrapat ca exista multe similitudini Intre cuvintele din text. Fiind foarte riguros, Iondcfineste similitudinea a doua cuvinte dupa cum urmeaza.

Fie cl si c2 doua euvinte. Cuvantul c2 poate fi obtinut din cuvantul cl pr-intr-osuccesiunc de operatii elementare. Operatiile elementare ce pot fi folosite sunt :

Operatia Efect Exemplu

move(cl,c2) Muta primul caracter Daca cl-"alba" si c2-"neagra", dupadin ella sfarsitul efectuarea operatiei move (e1, c2) , el vacuvantului e2. fi "1ba", iar e2 va fi "neagraa".

insert (c1, x) Insereaza caracterul x Daca e1="alba" §i x-"b", dupala Inceputul lui c 1. executarea operatiei insert (cl,x), cl

va fi "balba".delete{el) Sterge primul caracter Daca c1="alba", dupa executarea

din cl. operatiei delete (ell, cl va fi "lba"

Definim similitudinea dintre cl §i cz ca fiind numarul minim de operatii insert sldelete ce trebuie executate pentru a transforma cuvanrul c1 in cuvanrul c2 (operatillemove nu se numara).

Fie cO primul cuvant din text. Incepand cu cO putem construi Ianturi de k-simi­litudine. Un lant de k-similitudine este 0 succesiune de cuvinte distinete din text euurmatoarele proprietati :

dad. un cuvant x apare in Ian; Inaintea cuvantului y, atunci prima aparitie a lui x intext preceda prima aparttie a lui y in text;daca .x si y sunt cuvinte consecutive in lant (in ordinea x y), atunci similitudineadintre x si y este ~ k ;

Certnta

Pentru 0 valoare s data, se cere sa se determine care piramide s-generatoare de inaltimemaxima exista.

ana banane castaneana si

ExpliccqieLanturile de 5-similitudine care se potforma sunt:ana are mere pereana are pereana arE' banane castaneana are si

Olimpiada Judeteana de Informatica, 2005

lant.out65

lant.in

ana are mere, banane,pere si castane.

Date de iesire

Pisierul de iesire lant.out va contine 0 stngura linie pe care va fi sorts numarul delanturi de k-similitudine ce incep eu cO.

Restrictii

o Lungimea unei Iinii din text nu depaseste 1000 de caractere.o Lungimea unui cuvant nu depasestc 30 de caractere.

Numarul total de cuvinte ~ 150.e Pentru datele de test, numarul de lanturi de k-sirnilitudine care incep cu cO va fi :::;

2000000000 (doua miliarde).

Exemplu

lantul este maximal (adica nu putem adauga inca un cuvanl la sfarsitul acesrui Iant,astfel Incat sa fie respectate proprfetatile precedente).

Cerinta

Scrieti un program care sa determine numarul de lanturt de k-similitudine ce incep cu cO.

Date de intrare

Fisierul de intrare lant. in contine pe prima Iinie valoarea k , Pe urmatoarele linii seafla textul dat.

5. Piramidao piramida de tnaltime n are Ia baza (baza fiind considerata de nivel 1) n numerenaturale nenuIe, pe nivelul urmator al piramidei (nivelul 2) exista n-1 numere, fiecarenumar de pe nivelul 2 fiind obtinut eu fonnula P2, i=P~, i +P 1 , i+l' pentru i=l, '.', n-1 §iasa rnai departe, pe nivelul k fiind n - k+ 1 numere, fiecare numar de pe acest nivel fiindobtinut cu formula Pk,i=PI;-l,i+PI;_l,i+l' pentru i=l, ... , n-k+l.

Piramida este s-generatoare daca numarul de pe ultimul nivel este s.

ExplicatieDaca se calculeaza (T1 JOIN T2) JOIN T3, se vorefectua 3*2=6 operarii elementare pentru primulJOIN, va rezulta 0 tabela cu 3 Iinii §i se vor efectuainca 3*1 operajii pentru al doilea JOIN, rezultand untotal de 9 operatii.Daca alegem varianta T1 JOIN (T2 JOIN T3),atunci primul JO I N efectuat necesita 2 operatiielementare §i conduce la obtinerea unei tabele cu 2Iinii : pentru al doilea JOIN se vor efectua 3*2=6operatii, deci in total se vor efectua 8 operatiielementare. Acest rezultat este optim.

.campion, 2003

join. out

B

Exemplujoin.in

3

31 1

2 1

1 3

2

1 4

3 4

1

4 3

Date de intrareIn fisierul piramida. .rnse .afla un aingur numar natural, 'reprezentand valoarea lui s.

Date .de iesirePisierul de desire piramida. out va conjine 0 singura.Iinie pe care va fi seris un singurnumar natural. reprezentAnd numarul total de piramide s-generatoare de inlUtime maximamodulo 10000.

6. GdinaGaina Chucky 767 trebuie sa strabata curtea sarind de pe un cote; pe altul sau zburandpeste cotete, de la primul Ia u1timul. Cotetele sunt reprezentate prin niste dreptunghiuride Hitime 1 m §oi tnatuml date §oi sunt numerotate in ordine de la stanga ell numere de la1 la n. Dod cotete ell numere consecutive sunt lipite (adiacente). Initial, Chucky.are unnumar de unitati de energie. Daca la un moment dat Chuckyajunge s~ aiba energie strictnegativa sau se afla in imposibilitatea de a mai face un pas (tntalneste un corer mai inaltdecat cota la care se afla), atunci nu mai poate continua acel drum.

Chucky poate sa se deplaseze facand urmatoarele tipuri de miscart :a) Pas. Gaina paseste pe orizontala de pe un cctej de tnatttme H pe urmatorul cote; de

aceeasi tnaltlme (in desen: de la pozrtia h Ia L), In acest caz, nu se pierde §i nu seca§tiga energie.

b) Aterizare, Gaina aterizeaza pe un cote; de tnatjtme H, venind in zbor, tot de larnaltlmea H (exemplu in desen: de la 9 la h). Nici in acest caz nu se pierde §i nu sec~tiga energie.

c) Decolare. Gaina zboara 1 m pe orizontala de pe un cotej (exemplu in desen: de la xIa a). in acest caz, gaina pierde 0 unitate de energie.

d) Zbor orizotual, Gaina zbcara pe orizontala (exemplu in desen: de la a la b, de la bla c •...). to acest caz, pierde cate 0 unitate de energie pentru fiecare metru parcurspe orizourala.

e) Picaj. Gaina coboara pe verticala (exemplu in desen: de Ia ala d , san de Ia d la g ...).in acest caz., ca§tiga care 0 unitate de energie penttu fiecare ~etru coborat. .

:223

gaina.out2

Energie initiaIaminima

2

1

1

gaina.in6

3 0 0 2 1 1

Olimpiada Nationala de Informatica, Buzan, 2004

'Bilant -eaergte pas cu pas

8~;_i~'

METODA PROGRA.MARn DINAMICE

x-+a(-l); a-+b(-l); b-+e(+l); e-+h(+l)

x-+a(-l); a-+d(+l); d-+e(-l); e-+h(+l)

x-+a(-l); a-+d(+l); d-+g{+l); g-+h(O)

gaina.out1

Traseu

x abe h

x a d e h

x a d 9 h

gaina.in3220

RestrictiiO<n<lOOOl

• o.:!:;"hi~30000

• Pentru datele de test exista intotdeauna solutie (primul cotet are rnaldmea mai maresan egala ell inilltimea orfcarui alt cotet).

Exemple

CerinlaSa -se determineenergia 'minima pe care 'trebuie sa 0 aibl1 Chucky la inceputul citUitoriei(cand se afla pe primul cotej) •.:astfel Incat sil poata ajunge pe cotetul n , avand in fiecaremoment, energia mai mare sau egala eu O.

Date .de irurare

Pisierulde intrare gaina. in conjine doua linii. Pe prima linie se afla numarul naturaln . Pe linia a doua se afla n numere naturale hI' h 2 ••••• h

n(unde hi repreztnta iniHtimea

cotetului L), separate de cate un spatiu.

Date de testreFisierul de testre gaina. out contine 0 singura linie pe care se affa un numar natural K.reprezentand energia minima initialit eu eare gaina Chucky poate sit ajunga la cotejul ri ,

avand in fiecare moment energia mai mare sau egala en O.

Mai jos, avem..un -drum format.dtn ·4 cotetecde inIDtimi 4 ~ I, 2, 2. Bxemplificamdiferite tipuri-dennscart din pozdtia x (ceea ce nu reprezinta un traseu compIet):

Din 'pozitia .de.start .x -se poate sajunge in poztda ,h -peS trasee :

", "

I,I

piramida.out7

piramida.in20

·PROGRAMAREA iN UMBAJUL C/C++'PENTRU LICEU

piramida.out3

'Iabara de pregatire a lotului national de informatica, Sibiu, 2005

Exemplepiramida.in10

Restrictie0<5<600000

De exemplu, '~entru s""lo.,existli 3 astfel .de piramide :

"10 10 ~O

6 4 5 5 4 6

4 2 2 3 2 3 2 2 4

3 1 1 1 2 1 1 2 1 1 ~ 3

222

r' "

L.J

224 PROGRAMAREA iN LIMBAJUL C/C+ + PENTRU LICEUMETODA PROGRAMARII DlNAMICE 225

Restrictii §i precizari

1~NS:500

OS:K<N

K..s:2 0 a1~CS:9

o Toate datele de test vor admire solutie.

K §i c,din sir,

. campion, 2004

produs.out234*5

produs.in4132 3 4 5

Exemplu

Date de intrare

Piaierul de intrare produs. in contine pe prima lime numerele naturale N,separate prin care un spatiu. Pe a doua linie a 'fisierului se afla cele N cifreseparate prin cate un spajiu.

Date de iesireFiaierul produs. out va contine 0 linie pe care sc va serie sirul rezultat dupa inserareaeelor K semne * in sirul de cifre. Elementele sirului (cifre §1semne *) nu vor fi separateprin spatii.

Date de iesirein fisierul de iesire joe. out se va scrie, pentru fiecare litera din cuvanrul obtinut prinamestecarea cuvintelor alese de Ana si Barbu, litera A sau litera B, dupa cum literarespectiva apartine cuvantului ales de Ana (A) sau cuvanrului ales de Barbu (B).

Evident, daca vom citi din cuvantul obtinut prin amestecare numai literele carora Iecorespunde in fisierul de iesire litera A, vom obtine cuvantul ales de Ana, iar daca vomciti din cuvantul obtinut prin amestecare numai literele carora Ie corespunde in flsierulde iesire litera B, vorrt obtine cuvantul ales de Barbu.

CerirqaScrieti un program care sa decida care litere apartin cuvantului ales de Ana $i careapartin cuvantului ales de Barbu.

Date de intrareFisierul de intrarc j o c . in contine pe prima lime cuvanrul ales de Ana, pe cea de a doualinie cuvantul ales de Barbu, iar pe cea de a treia lime cuvanrul rezultat prin amestecareaeelor doua cuvinte.

7. JoeAna si Barbu joaca un joe interesant. Fieeare i§i alege un cuvant, apoi se asaza amandoila acelasi calculator §i fiecare tasteaza cuvantul ales. Evident, in final, cuvintele s-auamestecat, astfel meat nu mai stiu ce litere apartin unui cuvant §i care celuilalt.

RestrictiiCuvintele sunt constituite din maximum 150 de litere mici ale alfabetului englez.

o Intotdeauna exista solutie pentru datele de test, nu neaparat unica.

Exemple

8. ProdusSe da un sir de N cifre. Se vor insera in acest sir K semne 7< (inmultit). Se obtine astfelun produs ai carui factori sunt numerele formate din cifrele dintre doua semne "* saudintre un sernn * 1}i unul dintre capetele sirului. Factorii respectivi vor avea eel putin 0cifra, eel mult c cifre §i nu pot incepe eu eifra O.

Cerinta

Detcrminati pozitfile in care se vor insera semnele 7<, astfel Incat produsul obtinut sa fiemaxim.

joe.intatamamamtatamaa

joe. outBAAABBAB

.campion. 2004

9. AvereItalag a fost toata viata pasionat de speculatii bursiere, reusind sa adune 0 avere consi­derabila. Fiind un tip original si pasionat de matemarica a seris un testament inedit.Testamentul contine doua numere naturale: s reprezentand averea ce trebuie tmpartitamostenitortlor si N reprezentand alegerea sa pentru Impartirea averii.

ltalag decide sa-si imparta team averea, iar sumele pe care le acorda mostenitorilorsa fie in ordine strict descrescatoare.

De exemplu, daca averea ar fi 7 unitati monetare, ar putea fi irnpartita astfel :4 (unitati primului mostenitor) 3 (unitatl celui de-a! doilea) sau6 (unitati primului mostenitor) 1 (unitate celui de-al doilea) sau7 (unitati doar primului mostenitor) sau5 (unitati primului mostenitor) 2 (unitati celui de-al doilca) sau4 (unitati primului mosrenitor) 2 (unitati celui de-al doilea) 1 (unitate celui de-altreilea).

Vazand ea Ii este foarte greu sa verifice daca nu cumva a omis vreo varlanta deImpartire, Italag le-a seris in ordine Iexicografica. Pentru exemplul de mai sus:

421;43;52;61;7.

A hotarat ca banii sa fie distribuiti conform celei de-a N-a posioilitati din ordinealexicografica.

-CerintaScrteti un program care pentru rtumerele.a, "N -date sa calculeze ~ioSa'3~ezemumarul 'tOtal.de posibilitlip de,imp~re.a .averft.rprecum.si .moduldn <care.se .\face.aceasta ·.impllrtireconform cua N-a 'posibifitate-din-ordinea Iexicografica.

Date de irurare'Fi§ierul.de 'Intrare .ave re . in condne 0 -singura linie 'PC care -se c.afla -doua numerenaturale 'separate -printr-un.singur-spatiu :_ primul mrmar (s)reprezintli -auma .totata :_ eel de-aldoilea (N)reprezintlnumarul -de .ordine .al Jmpartirfi cautate.

Date de iesireEisierul de tesrre avera.out va contine doua.Iinii :

pc prima linieva fl afisatnumarul total .de mcdalttatl de -impartire a averii ;pe ceade-a doua Hnie.va fiaIl§ata a N-a posibilitate de fmpartlre a lui s inordinelexicografica. Elementele sale vor fiseparate prtn cate un spatiu.

Restrictii §i precizari

". 1<5<70l.• O<N< numarul total de posibihtati eu surna s.• Posibilttatile de -tmpartire aaverii sunt numerotate Incepand eu 1.• Fie x=(x

1' x 2 ...• x~) §i Y=(Y 1 • Y2' ...• Yp)dou~ struri, Spunem ca x preceda pe Y

din punet de vedere lexieografic daca exista ~1 astfel .Incat xi=Yi'pentru oricei =1. k-1 §i Xk<Y

k• De exemplu, 4 2 1 preceda secventa 4 3 deoarece (4=4.2<3),

iar 6 1 preceda 7 deoarece 6<7.

asemenearca exista 'perechi~de.animale-care -se stmpadzeaza §i daca animalul mai slab.este satacat, .cel mai puternicIl -va 'proteja. Dupa .ce -vagonulsetnchide, .animalele .Incepsa 'se atace. "Transportuf -dureaza .suficient -de-mult, .astfel Jncat .roate .conflictele sa-se-epuizeze.

227MEIODAPROGRAMARIIODINAMICE

-Cerirqa

"Scrietlun program caresa determine 0 'modalitate'de Incarcare a :animalelor.in -vagoane,esttcr tncat sa ajunga la -destinajie un -numar maxim -de-animale 'vii.

Date de intrare

Pisferul de intrare transport. in contine :pe prima Iinie, numerele naturale N, K §i M, separate 1'00 spatii ;pe eea de a doua .Iinie, numarul natural D. care .repreztnta numarul. de perechi .de-animale care se antipatizeaza ;pefiecare dintre .urmatoarele D linii exista 3 numere naturale distinete, ABC. eusemnificatia : perechea.de vaei (A, B) se antipatizeaza, iar pereehea de vaci (c, B) se.simpatizeaza.. In.ambele perechic animalul B -este eel mai slab.eel mai puternie animal dintr-o pereehe de animale care se antipatizeaza fiU poate sij,apara intr-o alta .astfel de pereche ca at doilea:animal (adica eel mai slab). Animalulslab dintr-o pereehe .de .animale care se simpatizeaza are exact.un protector maiputernic (adica c este unic detenninat de A §i B).

Date de iesirePiaierul de iesire transport. out contine pe prima linie numarul deanimale ajunse viiIa destinatie (maxim posibil).

TII,

:.PROGRAMAREA iN LlMBAJUL~C/C++.'PENTRU LICEU226

10. TransportUn fermier trebuie sa transporte eu trenul 0 cireada fermata din N vaci. Pe fiecare.animaleste pietat un nUIJl3.r .de ordine, euprins intre 1 §i N. astfel Incat orieare doua animale aunumere distincte.

Trenul este format din K vagoane. in fieeare vagon pot fi mcarcate eel mult Mvaci.Vaeile stau la coada, in ordinea crescatoare a numerelor lor de ordine (vaca numerotataeu 1 urea in tren prima). La -un moment dat, sunt tncarcate Intr-un vagon un numaroareeare de vaei (care nu depaseste M). de 1a Inceputul cozri, dupa care vagonul esteIncuiat §i nu mai pot urea alte vaci in vagonul respectiv. .

Se stie ca exista pereehi de animale care se antipatizeaza §i daca 'sum Incarcate inacelast vagon se vor bate, iar eel mai puternic il va omori pe celalalt. Se sue, de

Restrictii

• i ss, K:::;;1000

1.s:M.s:20

Exempleavere.in7 2

avere.in12 5

avere.out54 3

avere.out156 5 1

Olimpiada Nanonala de Informatica, Galati, 2005

Exemple

transport.. in transport. out5 2 3 521 2 .3132

transport. in transport. out8 3 3 56

4 6 25 6 4786536765234

.campion, 2004

228 PROGRAMAREA iN LIMBAJUL C/C+ + PENTRU LICEU

II, METODA PROGRAMARII DINAMICE 229

CeriruaScr-ieti un program care. pe baza eelor trei variante ale mail-ului, sa determine eel mailung text ce ar putea fi continutul real al mesajului lui Ion.

Date de irurarePisierul de intrare fat. in contine trei Iinii. Fiecare dintre aceste Iinii reprezinta 0

varianta a mail-ului.

Date de iesirePisierul de iesire fat. out contine 0 singura linie pe care se afla cel mai lung text ce arputea fi continutul real al mesajului lui Ion.

RestrictiiPentru datele de test exista intotdeauna 0 solutie, nu neaparat unica.

Grice Iinie a fisierului de intrare este fermata din eel mult 100 de litere mici alealfabetului englez.

12. PesteIon a plecat la pescuit. in zona in care el pescuieste exista n lacuri. Teate lacurile suntplasate pe marginea aceleiasi sosele §i sunt numerotate de la 1 la n, in ordinea in caresunt arnplasate pe sosea. EI arc h ore la dispozttie pentru pescuit si se afla initial la laculcu numarul 1. Ion poate vizita lacurile exact in ordinea in care sunt amplasaie pe sosea,dar nu se opreste sa pescuiasca decat dad! dorc$te $i poate sa termine pescuitulla oricarelac dorc$te. Ion practica frecvent sportul accsta $i cunoa§te t. i (i = 1, 2, ...• n -1),uuma-rul de intervale de cate 5 minute care ii sunt necesare pentro a ajunge de la lacul ila lacul i+l.

11. FatIon s-a insurat st are 0 casnicie fericita. tn cursul ultimelor trei luni s-a ingrasat 20 kg.Degctele i-au devenit rnai groase §i are probleme serioase la tastare de fiecare data candti scrte un mail veehiului sau prieten Vasile.

De cele mai multe ad, Ion apasa mai multe taste in loc de una singura. Tastele pe careIon Ie apasa din greseala pot fi oricare dintre cele de pe tastatura, inclusiv tasta dorua ;ba ehiar poate apasa aceeasi tasta de mai multe on. Ion s-a mai obisnuit cu aceastaproblema si, pr-in urmare, numarul de taste apasate din greseala Impreuna cu tasta doritanu este rnai mare de 3.

Dupa ee a primit multe mail-uri ilizibile, Vasile l-a rugat pe Ion sa serie fiecare mailde trei ori , pentru a putea deduce continurul real al mesajului.

Restrictii1::S;h::S;162::S;n::S;25O<t i::S;192

Cerintd

Scriett unprograrn care sa determine numarul maxim de pesti pe care Ion ii poare pescui.precum sl modul in care el i§i planifica pescuitul pentru a obtine un numar maxim depesti.

Date de iesire

Eisierul de iesire peste. out va contine cere doua linii pentru ficcare set de date deintrare. Pe prima dintre aceste doua Iinii va fi afisat numarul maxim de pesti ce poate saii pescuiasca Ion. Pe cea de a doua lillie vor fi afisate n numere naturale separate princate un spatia. Al i-lea numar de pe linie reprezinta numarul de minute pe care Iepetrece Ion pescuind din lacul i. Numarul de minute pe care Ion Ie petrece la fiecare lactrebuie sa fie multiplu de 5 .

Daca exista rnai multe solutii (posibilttati de a planifica pescuirul , astfel Incat sa seobtina un numar maxim de pesti) se va alege solutia in care timpul petrecut la lacul 1 estemaxim. Daca in continuare exista mai multe solutii, va fi aleasa cea in care timpulpetrecut la lacul 2 este maxim etc.

Date de intrare

Pisierul de intrare peste. in contine mai mu1te seturi de date de test. Fiecare set de datede test confine P? prima linie un numar natural n ce reprezintii numarul de lacuri. Pe ceade a doua linie se afla un numar natural h ce reprezinta numarul de are pe care Ion Ie arela dispozitie. Pe cea de a treia linie sunt n numere naturale separate prin care un spatiu ,f l f z ... fn' ce reprezintii numarul de pesti pe care Ion se asteapta sa ii pr-inda inprimele 5 minute. din fiecare lac. Pe cea de a patra linie se afla n numere naturaleseparate prin cate un spatiu, d l d z ••• d n• ce reprezintii rata cu care scade, dupa fiecareinterval de 5 minute. numarul de pesrt ce poate fi pescuit in urmatorul interval de 5minute, din fiecare lac. Pe ultima linie se affa n-l numere naturale separate prin cate unspatia, t l t z ... t n_ l • ce reprez.inta numarul de intervale de 5 minute necesare penrru aajunge de la un lac la urmatcrul. Pisierul de intrare se incheie cu 0 linie ce continevaloarea O.

De asemenea, Ion cunoaste bine lacurile din zona si a determinat pentru flecare laci numarul de pesti f i pe care el se asteapta sa ii prinda in primele 5 minute. din laeulL. La fiecare 5 minute, numarul de pesti pe care el se asteapta sa ii prinda in interval de5 minute din Iacul i va scadea cu 0 rata constanta d i . Daca numarul de pesti pe care else asteapta sa ii prinda in urmatorul interval este :::;d i , deduce ca nu mai exista pesti inIacul L pe care ar putea sa Ii prinda in urmatorul interval.

Pentru a simplifiea problema. Ion presupune da nu mai pescuieste nimeni in zona inacelasi timp eu e'l, deci previziunile sale sunt exacte.

.campion, 2004

fat.outsarma

fat.inasaermxvqavscanrmabtstamrmhaqu

fat_outjuha

Exemplefat.injuehajudbhakjukhxa

13. CuvinteBalaurul Arhirel se decide sa fnvete biologie, asa ell doreste sa cumpere manualul declasa a X-a. Din pacate, acesta nu se mai gaseste pc piaja, dar balaurul reuseste sagaseasca 0 copie la un prieten. Dupa ce incepe sa cireasca, balaurul Arhirel observa caexista greseli in copia prtetenului, iar Intr-un impuls de energie, se hotaraste sacorectezemanualul. El are la dispozttie un dictionar de M cuvinte, din care trebuie sa extragavariante pentru cuvantul gresit. Asupra cuvantului gresit balaurul poate sa fuca urmatcareleschimbari, tn asa fel Incat acesta sa ajunga la 0 varianta din dictionar : poate sterge 0

litera; poate insera 0 Iitera ; poate schimba 0 litera In.alta litera.Balaurul Arhirel este Ienes•.asa ca nu dcreste sa opereze mai mult de K schimbari in

cuvantul gresit pentru a-l aduce la forma corecta (existenta in dictionar).

CerinpaAjutati-I pe balaurul Arhirel sa afle care dintre cuvintele din dictionar ar putea fi varianteale cuvantului greslt.

Date de intrarePisterut de intrare cuvinte. in contine pe prima linie cele doua numere, M §i K,separate printr-un spatiu, reprezentand numarul de cuvinte din dictionar si DUIl18.rulmaxim de modificari ce pot fi efectuate asupra cuvantului care trebuie corectat. Pe adoua linie se gasesc, separate prtntr-un spatiu, lungimea cuvantului greait, Lcuvant.' §icuvantul gresit. Pe urmaroarele Mlinii se gasesc cuvintele din dictionar, catc un cuvantpe 0 linie, in forma urmatoare : pe linia -L, lungimea L

i_ 2 a cuvantului i-2. separata

printr-un singur spatiu de cuvantul i-2.Orlcare dintre cele M(in cazul acesta, N=3. M=5) configuratii posibile are sanse egale

de a se intiimpla.Balaurul vrea sa stie care sunt sansele (in procente) ca la final sa iasa in fata maeinii

cu care se intrecea. .

Date.deiestre

-·Fi§ierul.de .iegire cuvinte. out -va.conune M.Iinti, 'Pe linia i .seena valoarea .rpentrucazul in care cuvantul i .din dicticnar este 0 vartanta a cuvantului greait dat, respectivvaloarea o. in -cazcontrar.

LJ

,: 1LJ

231

Intrare"e ~ rn rn···1RI" ,

Olimpiada Nationala de Informatica, Buzau, 2004

METODA PROGRAMARn DI1;'lAMICE

cuvinte. outo1

o1a1

cuvinte.in6 26 radiux5 ladin6 Radius6 ridica5 radio6 adipos5 cadiu

14. MastnaSe stie ca balaurul este un Impatimit al I .volanului. Jeri a ajuns la 0 intersectie ea(daca ii putem zice asa) foarte ciudata,ca in figura urmatoare.

La accasta intersectie au ajuns Nmasini (numerotate de la 1 la N). Balau­rul se afla in masina x. in momentulacela se Intrecea cu masina Y (x diferltde Y). Cele trei drumuri sunt foarte Inguste, asa Incat doar 0 masma poate sa Incapa peorlcare dintre ele, deci depasirea este imposibila. Totugi, datorita configurariei drumu­rilor, masinile i§i pot schimba pozijia la iesire.

De exemplu, pentru N=3. avem 5 pcsibifitati de ordonare a celor 3 masini :

• 1 2 3: intra masina 1 pe manevra §i -iese 1. intra 2 §i iese 2, intra 3 §i iese 3 ;• 1 3 2: intra 1 §i iese 1, intra 2. intra 3. iese 3. iese 2;• 2 1 3: intra 1, intra 2. iese 2. iese 1. intra 3. iese 3;

2 3 1: intra 1. intra 2. iese 2. intra 3, iese 3, iese 1;• 3 2 1: intra 1. intra 2. intra 3. iese 3. iese 2, iese 1.

Restrictii.. O<M<2l..• O<K<31.

o < lungimea oricarui cuvant (inclusiv eel gresit) < 10001 ..• Cuvintele sunt formate din litere marl si mici .ale .alfabetului latin.

Exemplu

'III

-peececout;

31-45 5

480240 0 a 0-724

115 10 50 35

Finala .campton, 2005

PROGRAMAREA·iN LIMBAJUL" CIC++-"PENTRU:L1CEU

Exemplepeste_in2

1

10 l2 52

4

4

10 15 ..20 17034 31234410 15 50 30a 3 4 31 2 3

o

230

232 PROGRAMAREA iN LIMBAJUL C/C+ + PENTRU LICEU

'Jate de irurarePe prima linie a fisierulut masina . in se afla 3 nurnere naturale N, x st Y, separate prinelite un spatiu, reprezentand numarul de masini, masma balaurului sl, respectiv, mesina";oncurentului.

Dcue de iesirePisierul masina. out va contine pe singura sa linie un singur numar real ell primelefoua zecimale exacte (obtinute prin trunchiere), ~i anume sansele (in procente) caBalaurul sa iasa la final in fata concurentului sau.

CAPlTOLUL 6,

Solupi! ~;i Iudtcatfi

Restrictii §i precizari1<N<101o-cx , Y<N+l

Exemplumasina.in

313

masina.out

60.00

BxpliccqieIn 3 dintre cele 5 configuratii masina 1 iese in fatamasinii 3, deci sansele sunt de 60 %.

Olimpiada Najlonala de Informatica. Galati, 2005

1. Recursivitate

1. a) Definitie Incorecta, deoarece pentru n> 1 functia este definita ciclic. De exemplu,sa evaluam f (3): 3 este impar, prin urmare evaluam f (2) : 2 este par, deci evaluamf (3) s.n.m.d ; b) Definitie tncorecra, deoarece daca argumentul este numar negativevaluarea nu "este posibila.

2. a) Pals (vezi, de exemplu, sirul Fibonacci); b) Fals (exista recuraivitate indirecta) ;c) Fals (acest mecanism este valabil pentru orice subprogram); d) Adevarat (reducereanumarului de parametri micsoreaza dirnensiunea spatiului de memorie necesar pe stivapentru un apel si reduce timpul necesar pentru alocarea parametrilor pe stiva).

3. Pentru n=4, programul va afisa ****++++.

4. a).

s. a) Programul calculeaza suma numerelor citite de la tastatura pana Ia citirea primuluinumar negativ sau nul. b) Programul cicleaza. Cand intram in functia Nr (), seatribuie variabilei locale i valoarea O. Se executa apoi atribuirea din ciciul for, deciin primul rand se evalueaza expresia din membruI drept, ceea ce conduce Ia un apelrecursiv. Prin urmare, se atoca din nou spatiu pe stiva pentru variabiIa Iocala i, seintra in ciclul for §i se atribuie variabilei i valoarea 0 etc.

6. 0.7. 0.8, 0.

9.~

ro.~.

11.int ms rec(~ong i)

if (i%lO) return 0;

return l+ms rec(i/lO)

..if (i==n-l) :return 1;

..if (a[i]==a[i+l]) return 0;

return dif (i+l);

}

TI.~

I f~oat Putere(f~oat x, unsigned n){ return !n ? 1 : x * Putere{x, n-l);}

'I,;~

.235

11

4

1

<laca n =0

.daca n par, n > a~dacii n impar

36

23

4

11

1

cSOLUTII$I INDICATII

.{O .NB(n)= NB{n/2),

NB (n-l),

Pentru a realiza a comparatie Intre cele dona variante, sa analizam execujia functieirecursive pentru n=5 §i k=3. Observam ca apelul comb (5, 3), genereaza dona apeluri:comb(4,3) §i comb (4,'2). Apelul comb (4, 3) genereaza ccmc (3, 3) §i comb (3,2).iar comb (4, 2) genereaza comb (3, 2) §i comb (3, 1) . Prin urmare, deja se observa case calculeaza acetees! valori de mai multe crt. in varianta iterativa, pentru a calculac~ se calculeaza c~ eu i variind de la a la n §i j de la 0 la L, dar 0 singura data.

Rezolvand caceasta relatte -de -recurenja, obtinem NB (n) egal icu rlog2n1 (parteajntreaga .superloara - celmai mic intreg mai anare decat login).

De -exemplu : I

·NA(16)-=16; "NB{B)=5;NA.(10) =10 ;NB (lO) =5;

Esteevident ca a doua .funcde de calculeste 'mai eficienta.

18. Problema cere calcularea numarufui de submuljirni de k elemente ale muttimit{I. 2 •...• n}, care In matematlca sunt denumite combinari de n -Iuate care k. Solutianerecurstva bazata pe formula de recurenta specificata-este fundamentul algoritmuIuide calculal combinartlor, cunoscut sub denumtrea de triunghiul lui Pascal. Deexemphr, triunghiullni Pascal pentru n=S este:

11 1

a)

Observed ca, pe linia i. (L variind de la 0 la n), in triunghiullui Pascal se gasesccombinarije de k elemente ale multimii {L, 2, ...• i} (k variind de la 0 la i).Pentru a rezolva problema nu este 'necesar sa reftnem Intr-o matrice triunghiul luiPascal in Intregime, este suficient saretinem.la fiecare pas i (L variind de la 1 la n) liniacurenta §i pe cea precedenta, pe care 0 vom utiliza pentru determinarea linlei eurente.

unsigned ~ong LNou[SOj, LVechi[SO];

unsi.gned ~ong combinari(unsigned n, unsigned k){ LNou[O] = LVechi[O] = 1;

for (:Lnt i = 1; i <= n; i++)

{ for (int j=l; j<=i; j++) LNou[jj=LVechi[j]+LVechi[j_l]:for (j=l; j<=i; j++) LVechi[j]=LNoU{j);

return LNou [k] ;

b) Varianta rccurstva

I unsigned ~ong comb (unsi.gned n , unsigned k)

(return n==k II !k 11 !n?l:cornb(n-l,k)+comb(n-l,k-l);}

1

b-a);

'Unsigned ..b)

f(f(x+2»; }

:'PROGRAMAREA iN .LIMBAJUL ·'CfC+ + "'PENTRU LICEU

b)f~oat Putere{f~oat x, unsi.gned n)

if (!n) return 1;f~oat p=Putere (x, n/2);

i.f (x%2) ~eturn x*p*p;

return p*p;}

i.nt f(.int ..x)

( return (x>=12)? .x-l

·mk (8 )=36; -mk (.50) =~275

OoservatuPentru claritate, functiile Putere () descrise au doi parametri, x §i n. Parametrul x esteinutil , deoarece el nu se mcdifica pe parcursulapelurilor recursive. Pr-in urmare, ar fifost mai eficient sa consideram ca x este variabiHi globala.

in cea de a doua vartanta a functiei Putere () am utilizat 0 variabila locala p in caream retinut valoarea retumata de Putere {x , n/ 2) , pentru a a putea ridica la patrat.

Pentru a realiza a comparatie intre cele doua functii descrise sa evaluam numarul deapeluri recursive necesare pentru un n natural dat in cele doua cazuri. Sa notam :

NA (n) - numarul de apeluri recursive necesare in cazul a), pentru a calcula x'";• NB (n) - numarul de apeluri recursive necesare in cazul b), -pentru a ealcula x";

NA (n) =n, pentru orice n numar natural.

15.

I .i.nt Surna (unsigned .1.ong x)(return!x? 0: Suma(x/l0) + (x%10%2?x%10:0);}

16. Puncjia returneaza valoarea 1 daca oricare doua elemente consecutive din vectorul asunt difertte.si 0 in caz contrar, Pentru a testaaceasta proprietate functia va fi apelatadif(O) .

.i.nt dif (int i)

12.

13.

I

I

·234

14.

Iunsiqned Cmmdc(unsiqned ·a,{ if (a==b) return a;

if (a<b) zeturn Crnmdc (a,

%eturn Cmmdc(a-b, b);}

~

236 PROGRAMAREA iN LIMBAJUL C/C+ + PENTRU LICEU SOLUTII $1 INDICATII 237

22. Problema este a aplicatie imediatii a codului Gray. Vom atribui nodurilor reteleivalori naturale obtinute prin convertirea in baza lOa unor- succesiuni de rn-r-n cifrcbinare. Mai exact, elementului de pe Iinia i (0;-<;i<2 m) §i coloana j (0~j<2") i seasociaza 0 succesiune de m+n cffre binare, obtinuta prin eoncatenarea secventei i dincodul Gray de dimensiune m ell secventa j din codul Gray de dimensiune n.

23. a) abc**2d*a12bc**++*+ b) 2ac**ab*c3d*ab*cd**+++"'-

24.#include <fstream.h>#include <string.h>struct {char ns; int v;} TS[200j;char e [200];int i;

void Citire ()int eval (char) ;

/* pentru functiile Citire() si eval{) vezi programul de evaluarea unei expresii aritmetice */long EvalExp(};

19. Problema este 0 aphcatie Imediata a problemei de calcul al sumei puterilor rada­cinilor. Se calculeaza :

s ~ (2 + .J3) + (2 - .J3) ~ 4 P = (2 + .J3) -(2 -.J3) = 1

Apoi se construieste ecuatia de gradul al Il-Iea : x2-4x+l=O.

20.' Punctia recursiva este:? int f (int n )

-1'-~ {return n<=2 ? 1 3*f(n-l)-2*f(n-31+f(n-2Ii}

, Puncua iterativa este :f .i.nt f (int rt )

r; {int £0=1, £1=1, £2=1, £3, i;

; if (n<=2) return I:for (1=3; 1<=n; i++)

£3=3*£2-2*£0+£1;

£0=£1; f1=f2; £2=£3;}

. ~~ return £3: }

Varianta recursiva nu este eficienta deoarece aceeasi valoare se calculeaza de mai

multe ori (vezi strut Fibonacci).

21. Pentru a genera toate paltndromurile de lungime n vom utiliza un vector P in carevom genera cate 0 jumatate de palindrom. in functia Afisare () vom afisa jumatateagenerata atilt in sens direct, cat ~i in sens invers. Generarea se realizeaza eu ajutorulunei functii recursive GenPalindrom (). ce are ea parametru poaitia k pana la caream plasat elemente in vectorul P. Pentru k>n/2, am terminat generarea unci jumatatide palindrom si apelam functia Afisare () . Altfel, ocupam succesiv pozitia k dinvectorul p cu cifrele bazei b si apelam recursiv functia de generare eu parametrul k+ 1.

~~,-"~

s

void GenPalindrom(int k)

{Ilcand apelam GenPalindrom(k)

if (k > (n-1)/2) Afisare();e~se

for (int 1=0; i<b; i++)

{P[k]=i;

GenPalindrom(k+l); }

am ocupat k pozitii din P

long EvalExp (){ l.ong el, e2;

void main (){Citire();i=strlen (e);

cout«"Valoarea expresiei este: "«EvalExp(}

*include <fstream.h>*define NMax 40

int n r b , P[NMax);of stream f("palind.out"}

void Afisare();void GenPalindrom(int);

void main (){cout « "n r b= "; cin » n » b;for (int i=l; i<b; i++)

{P[O]=i; GenPalindrom(l);}

f .close ();}void Afisare ()

for (int i=O; i<= (n-l) 12; i++)for (i=(n-1) /2-n%2; i>=O; i--)

f«endl; }

f «f «

P [i 1;P [i 1 ;

i--;

i.f (e[i]=='+'){ el=EvalExp ()

if (e [i 1== r * I )

{ el=EvalExp () ;return eval(e[i]);

e2=EvalExp() ;

e2=EvalExp();/Ie[i]

return el+e2;}

return el*e2;}este un operand

25.#include ·<iostream.h>4include <conio.h>#include <doa , h>~include <graphics.h>..:i.nth, .x , y;

-void a (int) ;

void b (.i.nt) ;

-vo.id c (int) ;

void d (i-nt) ;

void main ()

.i.nt n, i, xa, yO;cout «"n=": c1n»n;int driv=DETECT, mode;initgraph (&driv, &mode, "e: \ \borlandc\ \bgi");

h=getmaxy(): YO=xO=h/2;for (1=1: 1<=n; i++)

( h/=2; xO=xO+h/2; yO=yO+h/2:

x=xO; y=yO; moveto(x,y):a (1);

getche); cleardevice();}

PROGRAMAREAiN LIMBAJUL CtC+ +'PENTRU UCEU

~

, ;~

239

formula intre parant7ze

char tmp[LgMax];

FILE *input;

input=fopen (INFILE, "r");

fscanf(input, "%s", tmp);

strcpy(f, "("); //incadrez

strcat(f, tmp);

strcat(f, ")");

fclose(inptit);

void citire (void)

void afisare (void)

void d (.int i)

{ :i:f (i)

t.a (1-1.); line (x, y,:x,'y...,h),; y =, y-,.h;

d(i-~),; li.ne(x,.y,:x-h,y); x = x-.h;

d(i-l); line (x,y,x,y+h) ; y = y+h;c(i~l); ~elaY(20);}

'SOLUTU~~IINDlCATU

26. 'Vom;utiliza 'recursivitateadndirecta :*include -<stdio.h>

~include <string.h>

#-define .INFILE vme e e • in"

#define OUTFILE "mas a . out"

~define LgMax 100#define PSt ('

#define PDr ')'

#define Nr.Atomi 3

canst 'char atom[NrAtomiJ={ "c ", 'H', 'O'};

'const .int masa [NrAtomi] = { 12, 1 16};char f [LgMax+2] ;

int pos;

'int total;

FILE *output;

output=fopen (OUTFILE, "w");

fprintf (output, "%d\n", total);

fc1ose(output);

iiI

y-h;x+h;

y+h;

x+h;

y-h;

X-hi

x+n;y+h;

X-hi

y

x

line(x,y,x,y+h); yline(x,y,x+h,y); xline(x,y,x,y-h); ydelay(20);}

line{x,y,x+h,y) ;

line(x,y,x,y+h) ;

line(x,y,x-h,y); x

delay(20);}}

b(int i}

(i)

{e(i-I);

b (i-I);

bei-I);a (i-I) ;

a(int i)(i)

{d(i-I); line(x,y,x-h,y); xa(1-1); line(x,y,x,y-h); ya(1-1); line(x,y,x+h,y): xb(i-I); delay(20);}

void c (int i)

if (i)

b(i-l);

c(i-l);

c (i-I) ;

d (i-I) ;

voi.d

{ if

void{if

238

!,'-'

240 PROGRAMAREA iN LlMBAJUL C/C++ PENTRU LICEU SOLUTII sr INDICATII 241

i int cal cuI (void)

5. Subproblemele problemei date sunt de forma : "determinati Suma (i, j) , i=O, n-l ;j =0, L". Subproblemele nu sunt independente : pentru a calcula Suma (i, j) estenecesar sa cunoastem elementul urmatcr lui T [i] [j] pe drumul optim (T [i + 1] [j ]sau T[i+l] [j+l]). Deci subproblema Suma(i,j) ~i subproblema Suma(i,j+l)se suprapun, deoarece ambele implica apelul Suma (i+l, j+l).

Acesta este un exemplu de problema pentru care abordarea Divide et impera nu esteeficienta, deoarece subproblemele se suprapun.

o alta idee ar fi sa asociem fiecarui element T [i] [j] din triunghi 0 erichetaS [ i J [j J , care repreztnta suma maxima ce se poate obtine pe un drum de la T [ i] [j Jla un element de pe ultima Iinie, respectand conditiile problemei. Astfel, nu vomcalcula aceeasi valoare de mai multe ori, este suficient sa 0 calculam 0 data, sa 0

retinem in matricea S ~i sa 0 utifizam ulterior ori de care ori este necesar.Elementele matricei Spot fi obrinute prin urmatoarea relatie de recurenja :

Sri] [jl=max{S[i+l] [j),S(i+1] [j+l] }+T[il [j] ,i=0,n-2; j=O,i;S[n-l] [j]=T[n-l] l jl , j=O,n-l

t,'.,-,

f.:

F

.i.nt sum, i;;i..f (f[pos]==PSt)

{sum=O; pos++;whi~e (f [pos] ! =PDr) sum+=calcul () ;

pos++; }

else{for (i=O; i<NrAtomi; i++)

if (f[pos]==atom[i]) sum=masa[i];

pos++; }if (f[pos]>='l' && f(pos]<='9')

{sum*=f[pos}-'O';

pos++;

return sum;

int main (void)

citire() ;

pos=O;total=calcul()a r Ls a r e () ;return 0;

4.a)n-4 b)n=4 a)n=8 b)n-S

1. ebe 5. bab 8. def nmp 15. ebc ebc2. bbb 6. a aa 9. cccbmmm 16. bbbabbb3. dbf 7. bab 10. ecgbomq 17. cbcacbc

11. bbbbb 18. aaaaa12. ihkbsru , 19. cbcacbc13. hhhbrrr 20. bbbabbb14. j hI trv 21. cbc cbc

a[q]

Rezolvam aceasta relatie in mod iterativ, pornind de jos in sus (bottom-up) :

[ j ] ,.

j++)

n;

y)y; }

j=O; j<n; j++) S[n-l] [j]=T[n-l] [j];i=n-2; i>=O; i--)

(j=O; j<=i; j++)

Sri] [j]=max(S[i+l1 [j] ,S[i+l] [j+l] )+T[i]

cout«"Suma maxima este "«5[0] [Ol«endl;}

#include <fstream.h>

{Citire();

for (intfor (int

for

(int j=O; j<=i;

fin»T [i] [j] ;

fin.close() ;

int max (.i.nt x, int{return x>y ? x

void main ()

1,1

"f! .i.nt T[20] [20], 5[20] [20],,. ,

~ voi.d Citire()I {ifstream fin("suma.in");l.: fin»n;

~ for (int i=O; i<n; i++)~ for~{'

l!l'_

~,~:

"!!~o

2. Soluria esre asemanatoare algoritmului de cautare binara. De data aceasta, jucatorulnestiind numarul, nu poate face 0 comparatie directa, continuarea cautarit reali­zandu-se in functie de raspunsul celuilalt jucator.

3. Programul calculeaza n ! .

1. Solutia Divide et impera consta in tmparttrea sirului de elemente in doua subsiruri{ao' a

1••••• am}, rcspectiv {am+

l•••• , an_I}' unde m este mijlocul sirului, ~i aplicarea

asociativitatii operatiei min: min{a o' e , .... , a n_1 }= mi n {mi n {a o' a 1 ••••• am}'

min{am+ 1 ••••• an_I}}·int Min(int p, .i.nt q}{/Ifunctia intoarce minimul dintre a(p],

if (p==q) return alp];/Iimpartim problema in doua subprobleme

int Mijloc={p+q)/2, ml=Min(p, Mijloc), m2=Min(Mijloc+l, q);

if (ml<m2) return m1; //combinam solutiile

return m2;}

2. Metoda Divide et impera

,w

:-,

, ,

f -:I :

I

: "1

-

243

initializat coreet modul grafieIlstabilese euloarea de fundalIlstabilesc culoarea de desenareIidesenez triunghiul initial

,-SOLUTII $rINDICATII

I/inchid modul grafic

"Fraet (i+l,xa,ya, (xa+xb) 1_2, (ya+yb) 12, (xa+xc)/2, (ya+ye) 12);Fraet (i+l,xb,'yb, (xa+xb) 12, (ya+yb) 12, (xb+xc) 12, (yb+yc) 12);Fract(i+J.,'xc,yc, (xc+xb) /2, (yc+y~) /2, (xa+:xc) /2, (ya+yc) /2);)

}

void main ()(~nt GrDriver=DETECT,_GrMode,Eroa~e;

cout«"Coordonate~e varfurilor = ";cin»xa»ya»xb»yb»xc»yc;eout«"Numar"ulde i-teratii·ft ; ein»n;initgraph(&GrDriver, &GrMode,·"c:\\borlandc\\bgi");Eroare=graphresult();".if (Eroare == grOk) I lam

(setbkcolor(WHITE);setcolor (RED) ;line(xa,ya,xb,yb);line(xa,ya,xc,ye) ;line [x c , ye, xb , yb) ;Fract(l, xa,ya.xb,yb,xc,yc);getch ();

}

clo:segraph();}

8. Algoritmul de rezolvare este asemanator cu cel al rezolvarfi a problemei plierilor,numai ca inainte de pliere vom modifica valorile elementelor jumatatii receptoare,conform enuntului problemei, urmand sa rcsrauram valorile respective dupa apel,

9. Problema este 0 versiune in plan a problemei pIieriIor. Prin urmare, pentru rezolvarese poate utiliza 0 funcjie recurstva de fmpaturire a hartii. Functia va primi eaparametru coltul din stanga-sus si coljul din dreapta-jos ale portiurrii care se afla inmomentul apelului deasupra. in cadrul funcjiei, se tcsreaza in primul rand daca toateelementele aflate in zona de deasupra au cote egale. in acest caz, nu mai este necesaraplierea :;i comparam aria .acestel zone ell aria maxima obtinuta pana la momentulrespectiv, schimband, daca este cazul. in cazul in care zona nu este de aceeasi cota,se phaza harta, daca este posibil, mai intai orizontal, apoi vertical. apeldnd recursivfunetia de tmpartire pentru zonele obtinute prin pliere.

10. Algoritmul de determinare al celui al k-Iea eel mai mic element din sir se bazeaza peaceeast idee ca sortarea rapida (Quick Sort). Pentru aceasta, vom utiliza 0 funcjierecursfva denumita QuiekSeleet, cu doi parametri, st, dr, ce reprezinta extre­mitatile intervalului in care cautam al k-Iea eel mai mic element. in cadrul funcjiei,tmpartfm intervalul de cautare in acelagi mod ca in QuickSort: pozijionam pr-imulelement a [s t] pe poztjia sa corecta (notata m) in strut ordonat, astfel ineat in stangasa sa fie plasate numai elemente mai mici decat el, iar in dreapta numai elemente maimari decat el , Daca k-l este ega! cu m, a (m] este al k-Iea eel mai mic element. Dacam este mai mare decat k-l, continuam cautarea in prima parte a 'intervalului(st .. m-l), altfel conrinuam cautarea in eea de a douaparte a intervalului (m+l .. dr).

,-,I,

//determinrnijlo~ul

//marchezrnijloculI/gradez jumatatile

Ilinehid modul grafie

Ilam initializat corect modul graficIistabilesc culoarea de fundal

PROGRAMAREA iN LIMBAJUL C/C++ PBNTRU LICEU

vo:id main (){int L, h, GrDriver=DETECT, GrMode, Eroare;

couc c cv t> "; cin»L; c ou t.-c-cvb e "; cin»h;initgraph(&GrDriver, &GrMode,"c:\\borlandc\\bgi");Eroare=graphresult() ;if (Eroare == grOk)

(setbkcolor(WHITE) ;setcolor(RED); Iistabilesc culoarea dedesenareline (getmaxx()-L) 12,unde, L+ (getmaxx ()-L) 12, unde)Gradare«(getmaxx()-L) 12, L+(getmaxx()-L)/2,h);getch () ; }

closegraph () ; }

7. Pentru a genera triunghiullui Sierpinski vom utiliza 0 functie denumita Fractal CU7 parametri: i - numarul de iteratii :;i x a , ya, xo, yb, xc, yc - coordonatelevarfurilor triunghiului care genereaza fractalul. in functia Fractal, daca is;n (nu amexecutat numarul de iteratii cerut), vom determina mijIoacele Iaturilor triunghiului, Ievom uni prin linii, determinand astfel cele 4 triunghiuri incluse in triunghiul initial,apoi vom executa 0 noua Iteratie, apeland recursiv functia Fractal pentru cele 4triunghiuri obtinute.*include <iostream.h>#include <conio.h>#include <graphics.h>int xa, xb, xc, ya, yb, ye, n;void Fract(int i,int xa,int ya,int xb,int yb,int xc,int yc){ if (i<=n)

(line (xa+xb) 12, (ya+yb) 12, (xa+xc) 12,"(ya-+yc) 12);line «(xa+xb) 12, (ya+yb) 12, (xb+xe) 12, ,(yb+yc) 12);line (xe+xb) 12, (yc+yb) 12, (xe-r-xc) 12, (ya+yc) 12);

6. Ideea Divide .et impera -este de a -utifiza 0 -functie Gradare .cu rrei parametri : -et -.Iimita din .stanga .azoaei ce:trebuie gradata.dr -c Iimita-din-dreapta.st n - in3ltime~

diniei eu care.se-realizeaza gradarea la mjjloc. Daca h>o.':'Se..calculeaz~ntijlocul.-'Se

.deseneaza Ja mijloco -gradatie de -inaltimeh•.apot .se capeleaza-recursiv functiaceada re pentru jumatateastanga.capoi -pentru cea-dreapta,-specificand pentru unijloco gradatie eu iffiUtimea h/Z.

#include <iostream.h>#include <graphics.h>#include <conio.h>.:i.nt unde=400;-vo:id Gradare(:int st, int dr, .int h)

{i.f (h)

(:int m=(st+dr)/2;line (m,unde,ffi,unde-h) ;

Gradare t s c , om, h/Z);

Gradare (m, dr, h/Z);}

242

II

I!

u

244 PROGRAMAREA IN LIMBAJUL C/C+ + PENTRU LICEU SOLUTIJ $1 INDICATII 245

3. Metoda Backtracking

1. Programul afiseaza toate succesiunile de lungime 4 formate din literele a, b §i c ,astfel tncat oricare doua clemente succesive sunt diferitc, iar pe prima pozitie estetntotdeauna a.

2. a) Fals (metoda Backtracking se poate implementa §i iterativ, dar in acest cazprogramatorul trebuie sa gestioneze stiva in mod explicit); b) Adevarat ; c) Fals.

Analizand accst algorttm de selectie .rapida, observam ca. in medic, algoritmul esteliniar. Existli terns! cazuri defavorabile, in care numarul de operatii elementareexecutatc de algoritm este aproximativ n".

Observati ca. spre deosebire de QuickSort, QuickSelect face un singur ape!

rccursiv.int Qselect(int st, int dr)

int m=Divide(st, dr);if (m==k-l) return a[m];if (m<k-l) return QSelect(m+l, dr);

return QSelect(st, m-I);

Ilam fixat k-l margele

Ilverific daca N s e inchide" colieruls s ! (e[1]=='a'&&c[n]=='g'll e[1j=='g' &&

&& ! {c[IJ=='n'&&e[n]=='v' I I c[I]=='v' &&afisare () ;

else;

else

{if (NrRosii<n/2 && c[k-I]!='r')

illmai pot pune margele rosiie[k]='r'; NrRosii++;GenColier(k+l};NrRosii--;}

if (c(k-l] !='a' && e[k-l] !='g')Ilpot pune alb sau galben{e[kj='a'; GenColier(k+l);e[kj='g'; GenColier(k+1);}

if (e[k-I] !='n' && e[k-I] !='v')Ilpot pune negru sau verde{c[k]='n'; GenColier(k+l};c[k]='v'; GenColier{k+I);}

void GenColier(int k){if (k-I==n)

if (c[l] !=c[n]e(nj=='a')e[n]=='n'»

5.

Pentru a verifiea in mod unitar conditiile interne pentru or-ice k (inelusiv pentruprima pozitie), in funcjia prmcipala initializam pozitia 0 din vectorul e eu 0 valoarcdiferita de 'a', 'g', 'r', 'v' sau 'n' si apelam GenColier (1) . Observati , deasemenea, ca am utilizat 0 variabila gtobala NrRosii in care retinem numarul demargele rosfi utilizate in colier.

6. In primul rand, vom observa ca daca 5>45, nu exista solutie, iar pentru 5=0, singurasolutie este O.Daca 0<5$4"5, Yom genera toate solutiile in vectorol sol cu 10 componente. Nuputem genera solutiile Intr-o variabila numerica, pentru ca, de exemplu, pentru 3=45solutia 9876543210 depaseste valoarea maxima corespunzatoare tipului unsignedlong. Daca utilizati un compilator care accepta tipul long long, se poate folosipentru generare 0 singura variabiIa numerica.Pentru a respecta conditia ca cifrele sa fie distincte, vom utiliza un vector u z (vectorulcaracreristic al multimii cifrelor ce apar in vectorul sol).Pentru generarea tuturor solutiilor, Yom utiIiza 0 funcrie recursiva, Gen () . Candapelam Gen (k) , in vectorul sol sunt fixate pozitiile 0, 1, ... , k -1 . Pe pozitia k YompIasa orice cifra care nu a mai fost folosita si care, adaugata Ia suma cifrelor dejafixate, nu depaseste 3. Suma cifrelor deja fixate va fi retinuta in variabila globala sum.o atentie speciala trebuie sa acordam cazului in care am obtinut 0 solutie cu sumacifrelor egala cu s, dar in care nu apare cifra o. In acest caz , afisam si solutiaobtinuta, si cea Ia sfarstrul careia adaugam cifra 0 (solutie care are aceeasi suma a

Ie

!IilIi

I~

/Ipe pozitia k pot pIasa un 1

Ilcontinuam generarea/Ipe pozitia k pot pIasa un 0

Ilsecventa completa

{if (k-NrUnu < m-n)

{s l k l =0;Gen (k+ 1) ; l

if (NrUnu < n)

{s[kj=1; NrUnu++;Gen(k+l);NrUnu--; }

3. Dan Maria Ana Ion

4. Vom reprezenta 0 secventa binara tntr-un vector s eu m componente. Vom generatoate succesiunile prtn Backtracking. ell ajutorul functiei Gen ( ) . Cand apelam functiaGen (k), presupunem ca am fixat deja clemente pe poztriile O. 1, ... , k-1 insecventa. Pentru a nu calcula la fiecare pas numarul de 1 existenti in secventa, vomuriliza 0 variabila globala NrUnu, in care retinem permanent numarul de 1 din secventabinartt. Cand plasam un 1, incrementam valoarea acestei variabile, cand revenimdintr-un apel recursrv de dupa plasarea unui 1, decrementam valoarea variabilelNrUnu.

void Gen (int k)

{ if (k==m)afisare ()

el.se

',;

,<.

"*iii

7. Vom genera toateeotujtlje utifizand 0 funcjie .recurstvx Gen ( ). Cand apeUimGen (i, j ) ,:toate elementele .matrieei,pfula .Ia 'elementul de pelinia i '§i eoloana j

dnclusiv :(intr-o 'parcurgere.pe linii)~:;aufast deja fixate. Determinamm primul randurmatoarea 'pozijie ee urmeaza a fi-ocupata 'in matriee (urmatorut element de pe Iiniaisau primuI -element .de pe Jiniai+l).Pe .urmatoarea pozttie putem. pIasa oriceelement intre l§i n care.nu amai fost .urilizat -pe linia 'sau cotoana respectiva §i care.arealtliparitate.fatade .vecinul sau de .sus (daca exista) sau vecinul .sau din stanga(dacii exista).Pentru.a 'retine evidenja 'valorilor utifizate pe liniivom utilizamatriceauzl, .u z L [i] [j J e L, daca valoarea j .este utilfzata pe linia L, ·§i O. in caz contrar, De.asemenea, pentru a reline evidenta valorilor utilizatepe coloane vom utiliza matriceau a c , uzc l d l [j) =1. caca valoarea f esreutltizata pe coloana L, §i O. in caz contrar.#inc1ude <fstream.h>ofstream fout (·'matrice. out .. ) ;~nt n~ a[ll] [11];int uZl[ll] [11], uzc[11) [11):vo~d Gen (~nt, int);void Afis;are();

246 PROGRAMAREA iNL1MBAJUL.C/C++'PENTRU LICEU

.cifrelor), 'De .asemenea, -numerele.generate -nu -pot ,'S~ .tnceapa cu cifraO.Din .acestmoriv, -prima pozttie 0 vom completa -separat-In'funcjia-me.Ln ( r mumai cu cifremenuleo.§i-vom incepe ..generarea cu-pozijia.a -doua.

.*include <fstream~h>

#de£ine 'NMax 113.nt $01 [NMax], uz [10]:;

..intn, S, sum;ofstreamfout("nr.out");"Void Afisare (::i.nt );

void Gen (int k)

tint i;

if (sum==S)

(Afisare(k);if (luz[01)

(sol[k]=O; Afisare(k+l);}

,.SOLUTn~I INDICATII

247

I

I!!!!

-eaee

for (i=O; i<10 s s surn+i<=S; i.++)

.if (!uz[il)

{sol[k]=i; uz[i]=l; sum+=i;Gen(k+l);uz[i]=O; surn--i;

int main ()lint i;CQut«"S="; cin»S;.if (5)45)

r o u ti-c c vNu exista solutii \n";

elseif (5==0) z ouc-c-co-c-ce nda z

else

£or (i-I; i<10; i++)(sol[Ol-i; uz[i]=l; sum-i;

Gen(l) ;uz[i]=O;

}fout.close(); return 0;

void Afisare(~nt 19){~nt i;

for (i=O; i<l.g; i++) fout«sol[i);fout«endl;

!

int main ()(cout«"n= "; cip»n:'Gen(l, 0);fout.close();return 0;

void Gen(int i, int j){ int k, p, ok, urm_i, urm_j;if (i==n && j== n) Afisare();

e~se

{urm_j=j+1; urm_i=i;i.f (urm_j==n+1) {urm_i++; urm_j=l;}for (p=l; p<=n; P++)

if (! u a L [urm_i] (p] && ! uzc [urm_j J (p] ){ok=l;if (urm_i>l)

if (p%2+a[urm_~-1] (urm_JJ%2!=1) ok=O:if (urm_j>l)

if (p%2 +a[urm_i] (urm_j-l]%2!=1) ok=O;if (ok)

fa (urm_i] [urm_j] '=p;

uZ1[urm_iJ (p)=l; uzc[urm_j] [p]=l;Gen(urm_i, urm_j);uzl·(urm_i] [pJ=O; uzc[urm_j] (p]=O;

)

~

':'-l,J

....1

....1

8. Vom memora semnele ce se intercaleaza tntr-un vector 5 (s [k] este semnul care vafi plasat tnaintea lui a r x i). Var-iabila globala sp retine la fiecare moment valoareacalculata a expresiei (s p se va initializa in functia mai n ell a [ 1 ) ).void gen (i.nt k)

/* cand ape lam gen(k), am intercalat deja semne pana laa[k-l] inc1usiv */

{ if (k-l==n) afisare();else{//interca1ez +

s[k]='+'; sp+=a[k]; gen(k+1); sp-=a[k];//interca1ez -, daca este posibilif (sp>=a [k] )

(s [k) =' -'; sp-=a [k]; gen (k+1); sp+=a [k]; 1

248

{,

i:,

PROGRAMAREA IN LIMBAJUL C/C++ PENTRU LICEU

void Afisare (){int L, j;

for (i=l; i<=n; i++){for (j=l; j<=n; j++) fout«a[i] [jj«'fout«endl;

fout«end1;

!~~'

Ii,W

i[\'

!1!!

t

SOLUTII Sl INDICATII

#include <fstream.h>#define NMax 100

int s[NMax), smax[NMax];int a, b, 19max, sum;ofstream fout("sir.out");

void Gen (int k)//cand apelam Gen(k), am fixat in sir k valori{j.nt i;

if (sum==b) / /siru1 este completif (k>lgmax)

{ Lqme x-e k r

for (i=O; i<k; i++) smax[i]=s[i] }else;

elsefor (i=2*s(k-1]; i+sum<=b; i++)

{s(k]=i,. a um-t-w a rGen (k+l);sum-=i; }

249

return 0;

9. Reprezentarea informcqiilorVom utilize un vector p cu n componente, in care vom rctlne punctajele subieetelor(p [i ] =punctajul acordat subiectului a) sl un vector d eu n componente, in care vomrefine dificultatile subicetelor (d [i] =dificultatea subiectului i).Vom genera solutiile in vectorul sol cu maximum n componente, in care vom retinemultimea subiectelor rezolvate de student. Pcntru a nu genera de mai multe oriaceeasi solutie, vom retine in solutie subiectele in ordine crescatoare.

Conduit interne

501[i)E{l, 2, ... , n};501[iJ<s01[i+1J, Vi;d[sol[i] lSD, Vi;Lp[sol [i] ]~P.

Vom genera solutiile in veetorul s , iar in veetorul smax vom refine 0 solutie deIungime maxima. Pentru generarea tuturor solutiilor vom utiliza 0 functie recursivaceo (). Cand apelam functta Gen (k), prirnele k elemente din veetorul s sunt dejafixate. Daca surna elemcntelor din s este b, am obtinut 0 solutie ~i cornpar lungimeaei cu Iungimea maxima (lgmax). Daca este cazuI, rerin noua lungime maxima ~i

solutia curenta. Daca surna elementelor din s nu este egala cu b, continuam generarea.Pe pozitia k putem pIasa orice element mai mare decat dublul elementului precedent,dar care, adaugat la suma elementelor deja fixate in vectorul s, nu depaseste b.

int main (){i.nt i;

cout«"a, b="; cin»a»b;s[O]=a; sum-a; 19max=O;Gen (1) ;if (! Lqma x ) fout«"Nu exista solutii";

elsefor (i=O; i<lgmax; i++) f ou t c c s ma x La j « c '

fout«end1;fout.close() ;

11. RimdVom genera solutiile in vectorul s . Pentru a nu aseza in rand un copil de mai multcori vom utiliza un vector u z , ce reprezinta vectorul caracteristic al muljimil copiilordeja asezati in rand.Pentru a genera toate solutiile vom uriliza functia recursiva Gen ( ). Cand apelamGen (k), am asezat in rand k copii , Daca k<p, continuam generarea, plasund uncopil pe pozitia k (0 fata, daca precedentul copil este baiat, sau un baiat , dacaprecedentul copil este fata) $i apelam recursiv Gen (k+l) .Deoarece la fiecare moment trebuie sa existe un copil precedent (pentru a realizacompararia) , in functia main () vom pIasa pe prima pozttie, pc rand, fiecare copil sivorn Incepe generarea de la pozttia a doua.

-'250 PROGRAMAREA 'iN LIMBAJUL C1C++'PENTRU LlCEU

1'SOLUTII-SIINDICATII .251

: 1i I

#include <fstream.h>,#define 'NMax ::2.1

.j.nt ,5 [NMaX], uz [NMax] ;

int on, P, f, nr-sol;ofstream fout("sir.out fl

) ;

void Afisare();'Void Gen (int k)Ilcand apelam Gen(k), am fixat in sir k valori

tint i,if (k==p) l/sirul este complet

Afisare () ;

·el.seif (s[k-l]<=f) Ilpe pozitia precedenta sta 0 fata

{for (i=£+1; i<=n; i++)if (!uz [1])

{s[k]=i; uz[i]=l;Gen (k+l);

uz[i]=O;

el.se Ilpe pozitia precedenta sta un baiat

for (i=1; i<=f; i++)if (!uz[i)

(s[k]=i; uz[i)=l;Gen(k+l);uz(il=O;

.i.nt main ()

{i.nt i;

ccut c-cv n , p, f="; cin»n»p»f;for (i=1; i<=n; i++)

{s[O}=i; uz[il=l;

Gen (1);

uz[i]=O;}

.if (!nrsol) fout«"Nu exista solutie\n";

fout.close(); return 0;

voi.d Afisare (){j"nt i;

nrsol=l;for (i=O; i<p; i++)

fout«s[iJ«'fout«endl;

12. Vom genera.sfrurile ccrute -ln 'vectornl .e ell .aiutorul-functlet 'recursive Gen () . Cand.apelam Gen (k) ~'Sunt fixate -primele k elemente .din .str. .Daca .ultimul element .fixateste -n +19• .am obpnut o sclutie -si '0 .afisam. .In.caz contrar.cconrinusm -generarea,'plasand pe pozitia k orice element mai mare deceit 'precedentul, dar -care .nu depasesten+lg§Lapeland..apoi reeursiv Gen (k+l) ~

4include <fstream_h>*define 'NMax 20:.:int s [NMax] ;..i.nt n, 19;ofstreamfout("sir.out");void Afisare(int);void Gen (int k)

/ /cand ape1am Gen (k), .am fixat in sir k valeri{int i;

if (s{k-l]==n+1g) //siru1 este comp1etAfisare (k) ;.ea.ee

for (i=s[k-l]+l; i<=n+lg; i++)(s[k]=i;Gen(k+l) ;

int main ()(cout«"n, 19="; cin»n»lg;$[O]=n;Gen (1);feut.c1ose();return 0;

void Afisare(int 19)(int i;for (i=O; i<lg; i++) fout«s[i]«'fout«endl;

13. Vom memora un $ir de cifre in vectorul a . Vom genera toate solutiile formate numaidin cifrele 2 §i 4. Cand objinem 0 solutie, vom afisa §i solutia fermata din cifrele 1§i 3 corespunzatoare. Pentru generarea tuturor solutiilor vom utiliza 0 functierecursiva Gen (). Cand .apelam Gen (k). primele k pozfjii din sir sunt fixate $icontinuam generarea plasand pe poztjia k cifra 2 sau cifra 4.#include <fstream.h>#define NMax 20

int 5 [NMax] ;int n;ofstream fout(~sir.out");

void Afisare();

~

:,'ji-' '1

i, ,u

i i, I

,, ,i ::.J

[1f ~

W

I i

~

, 1

i

-i

252 PROGRAMAREA iN LlMBAJUL etc + + PENTRU LICEU SOLUTII ~I INDICATIl 253

Conditii interneo O~x[i]:;'::;r[il,'ViE{1, 2 .... , m};o (x[1]+1)XL[1}+(x[2}+1)XL[2)+ ... +(x[m)+1)XL[mj=n.

14. Reprezentarea informatiilorRetinem Intr-un vector v valorile celor n obiecte (v [i J =valoarea obiectului L}, iarin vectorul c rerinem categoriile din care fae parte obiectele (c [1 J =categoria obiec­rului i). Generam soluriile in vectorul e , in care retinem oblectele selectate in premiu.Pentru a nu selecta doua obiecte din aceeasi categorie, utilizam un vector uz, cereprezinta vectorol caracteristic al multimii categoriilo:r reprezentate in cadrul premiului.

Conditii internes [i] E{l, 2 •... , n};

o c[s[i]l;t:c[s[jJJ,'Vi;t:jLv[s[ill=S;Vom genera toate solutiile si le vom numara.

15. Vom refine lungimile reperelor Intr-un vector L, cu m componente, iar Inrr-un vectorr, vom rnemora pentru fiecare reper numarul maxim de bucati suplimentare (in afarade cea obligatorie) ce se pot tala din bara. Solutia 0 vom reprezenta tntr-un vector x ,Cll m componente Cll semnificatia x [i] - numarul de bucati suplimentare de lungimeareperului i.

Iisirul este complet

am fixat in sir k valori

am taiat deja bucati dek - 1 *1

if (k==m+l)

( if (5==n) Afisare{); } Ilpierderile sunt nuleeJ.se

for (i.nt i=O; i<=r(kJ && S + i*L[k] <= n; i++)II taiem i bucati de lungimea reperului k

I x[k]=i; S+=i*L[k];Taie (k+l);S-=i*L[k]; }

In functia main () vom calcula suma lungimilor reperelor $i vom verifica daca lungimeabarei este eel putin egala Cll suma lungimilor reperelor. Daca nu, problema nu aresolutie. Daca da, consideram ca am taiat deja bucata obligatorie din fiecare Teper sideterminam toate posibilitanje de a tala restuJ barei cu ajutorul functiei recursive '1'a i e () .in variabila globala 5 retinem la fiecare moment suma lungimilor reperelor taiate.

void Taie (int }:){/* cand apelam functia Taie{k),

lungimeareperelor 1, 2,

11,iif,

void Gen (int k ){int aux;if (nr+2<nrmin)

if (k==n) nrmin=nr+2;else

{if (gl+g[kJ<=gmax)(g1+=g[k]; Gen(k+l); gl-=g[k];}

if (g2+g[k}<=gmax){g2+=g[k]; Gen(k+1); gl-=g[k];}

#include <fstream.h>#define NMax 25

int n, gmax, g1, g2, nr, nrmin;int g[NMax);void Afisare () ;void Citire();

~

tl~

16. Vom utiliza 0 functie recurstva Gen () , care va repartiza obiectele in containerc. Laapelul Gen (k) , primele k obiecte sunt deja repartizate, continutul containerului 1are greutatea gl, iar continutul containerului 2 are greutatea 92. Obiectuj k poate firepartizar in containerul 1 (daca rncape), in containerul 2 (daca Incape) sau poate fiinchis containerul 1 !}i deschis un alt container in care plasam obiectul k, sauJnchidem containerul 2 ~i deschidem un alt container in care plasam obiectul k , LaInchiderea unui container, acesta va fi nurnarat in variabiIa gkobala nr, astfel Incatnumarul total de containere utilizate este nr+2. Observati faptul ca am optimizatgenerarea testand mai Intai daca nr+2<nrmin (adica numarul de containere folositepana Ia un moment dat estc mai mic decat numarul minim de containere folosite), incaz contrar nu continuam generarea acestei solutii.

void Afisare ()

{:i.nt i;

for (i=O; i<n; i++) fout«s[i];

fout«'for (1=0; i<n; i++) fout«s(i]-l;

fout«'

int main ()

(cout«"n= to; cin»n;

Gen (0);

fout.close(); return 0;

void Gen (int k)

Ilcand apelam Gen(k),

{:i.nt i;if (k==n)

Afisare () ;

e1.se

for (i=2; 1<=4; 1+=2)

(s l k l =1,Gen{k+l) ;

~II

hii,

r;

::'1

~,r,,~

i,b~

.~~h'~;I'II\l~,;;

Ii>

,j

~

'-'

LJ

; 1i ,

LJ

'··1I I

LJ

255

se_poate=O;

k cu una dintre cUlorile,

eolorez punctul~/

/'* incerc sa-exa e t.en t.e

ok=O;'for (i=l; i<=nrc; i++)

(se_poate=l;£or (j=l; j<k && se_poate; j++)

if (dist(k, j) <= D && c[j]==i)if (se_poate)

(c[k]=i; ok=l;Gen(k+l); )

-eJ.se

.if (nxc-cnxmf.n).if (k==n+.1)

{nrrnin=nrc;£or (i=l; i<=n; i++) cmin[i]=c[i];}

}

:if (!ok)/* nu .am putut colora punctul k ell una dintre

culorile existente */(nre++; //adaug 0 noua culoarec[k]=nrc;Gen(k+l);nrc--; }

SOLUTU:$I INDICATII

void Afisare (){ofstream fout ("puncte.out");:int i;

int main (){:int i;

CitireO;/* 0 solutie triviala este de a colora fieeare punct i

in culoarea i */nrmin=n;£or (i=l; i<=n; i++) cmin[i]=i;/* consideram ca intotdeauna primul punct este

colorat in euloarea 1 */c[l]=l; nrc=l;Gen(2);Afisare();return 0;

1II

..

void Afisare ()(ofstream fout ("banda.out");fout«nrmin«endl;fout.close();

nr++;.aux=gl; gl=g[k]; Gen{k+l); gl=aux;,aux=g2; g2=g [k]; Gen (k+l); .g2=aux;

.nr-- ;

'.pROGRAMAREA iN LIMBAJUL 'C/C++ 'PENTRUUCEU

intrnain ()(Citire ();

nrrnin=NMax;Gen{l);Afisare () ;-return 0;

void Ci tire (){ifstream fin("banda.in");fin»n»gmax;for (int i=O; i<n; i++) fin»g [i];

fin.close(); )

17. Yom defini 0 structura denumita Punct in care vom retine coordonatele cartezieneale unui punet. in vectorul P ell componente de tip Punct vom retine eele n punetedate.in veetorul c vom genera toate colorartle posibile (c [i J =euloarea asociata punctu­lui i), dar vom repine in veetorul emin numai eolorarea ee fcloseste numar minimde eulori. Observati ca am introdus 0 optimizare in funcjia de generare: cecanumarul de culori folosite panala un moment al generarii solutiei este eel putin egaleu numarul minim de culort, nu vom mai continua generarea.

iinclude <fstream.h>#include <math.h>#define NMax 30

struct Punct lint X, y; } P[NMax];int n, nrmin, nrc, 0;int e[NMax}, emin[NMax];void Ci tire () ;void Afisare();doub~e dist(int, int);void Gen (int k)//cand apelam Gen(k), am colorat k-l punctetint i, ok, se_poate, j;

254

056 PROGRAMAREA IN LlMBAJUL C/C++ PENTRU LlCEU SOLUTlI st INDlCATII 257

18. Reprezentarea informatiilorDatele initiale ale elevilor (greutatile lor), se retin Intr-un vector elev. 0 echipa estecaracterizata de numarul de elevi repartizati la un moment dat in ecbipa, irrdiciielevilor din echipa §i greutatea echipei respective. Deci, pentru a retine acesteinformatii vom descrie 0 echipa ca 0 data structurata de tip struct ce conrine cele treitipuri de informatii descrise rnai sus. De remarcat di numarul maxim de elevi carepot exista intr-o cchipa este N-l (deoarece pot exista minimum 2 echipe si fiecare echipatrebuie sa aiba eel putin un elev). Echipele se formeaza intr-un vector E ell componentede tipul struct deserts. De asemenea, cea rnai buna repartizare a elevilor in echipecste retinuta in fiecare moment Intr-un alt vector de acelast tip best_E.

o toate echipeleell

//elevul j

//greutatea echipei

//numarul de elevi

//greutatile elevilor& (elev[i]);

E[i] .nr=O;

for (j=O; j<9; j++)

E[i].elev[jJ=O;E[i] .G=O;

} echipa;elev[lO];

E[6], best_E[6];

N, P, best_suma=Infinit;

for (i=O; i<N; i++)

fscanf(inp, "%d "fclose(inp)

)

echipaint

for (j=O; ]<best_E[J..] .nr; j++)

fprintf(g, "%d" best_Eli] .elev[j]+l};fprintf(g, "\n");

fclose(g) ;exit(O) ;

int calc_suma(void) //calculeaza suma diferentelor{ int suma=O, i, j;

for (i=O; i<P; ~++)

for (j=i+l; j<P; j++)

suma += Abs(E[i] .G-E[j] .G);

return suma;

void c~tire(void)

int i, j;

FILE *"inp;

inp=fopen("concurs.inN,NrN);

fscanf(inp, "%d %d", &N, &P);

for (i=O; i<6; i++) //initializeaza

int Abs (int x)

( return x>O ? x: -x;

int

void afisare(void)int i, j;

FILE *g;

g=fopen("concurs.out","w");

fprintf (g, "%d\n", best~suma)for (i=O; i<P; i++)

iIi

Ii.,!

IIiir.1Ii~11

Ii,j~II!~UIIqH""!~

i~iI'

~Iiu

//structura unei echipe//numarul de persoane/Icei (maximum) 9 elevi (indicii)

//greutatea echipei

typedef struct{ int nr,

elev[9];int G;

#define rnfinit 32767

fout«"Nr minim de culori: v-c c n r-m Lnc-c e n d Lr

for (i=l; 1<=0; i++) fout«cmin[i]«' ';

fout«endl;fout.close() ;

voi.d Citire ()

{i.nt i;

ifstrearn fi.n("puncte.i.n n)

£1n»0»0;for (1=1; 1<=n; i++) fin»P[i] .x»p[i] .y;

fin.close{);

)doub~e dist(~nt i, int j)( return sqrt({P[il .x-P[j] .x)*{P[il.x-P[j] .x)+

(P[il _y-P[j).y)*(P[il .y-P[j] .y»);}

il):Ij

iit',\!.";

\11;,

Conditii interneo E[i] .elev[j]E{O •...• 9}. V'iE{O •...• 5}. V'jE{O, ...• 8};

o elev[i] E{40 •.... 99}. \fiE{O, ... , 9}.

in momentul in care tori cei N elevi au fost repartizati in eebipe conform conditiilorproblemei - eel putin unul Inrr-o echipa -. se calculeaza suma diferentelor greutatilordintre oricare doua eehipe si, in cazul in care a fast determinata 0 suma mai mica.se retine suma ~i configuratia echipclor. De remareat faptul ca, in cazul in care s-aajuns la suma diferentelor O. a fast determinata solutia optima, dec! proeesul poatcfi oprit (vezi §i problema "Static").#include <stdio.h>#include <stdlib.h>

li(I"I'f!,!U!I

"~,,~"1,

\1I',\1

I---!

Ilback - 'se incearcareparti~areaelevuluik

PROGRAMAREA iN LIMBAJUL C/C++ '"PENTRU UCEU

intEchipa~goala(void)

.inti;~or (i=O; i<F; i++)

..:i.£ -(E[i] .nr==O) '7:eturn 1;

return 0;

r I,

..J

_259

terenului1a margineareturn 1.;

y) ey==m)

'SOLUTlI $1 INDICATII

Pentrua testa daca bilaa ajuns la marginea terenului.am utilizat functia Out:

,int Out (int x , int y)/ /intoarce 1 daca pozit.ia (x ,

{if (x==n t t x==1 I I y==1 t treturn O;}

1.9. Problemabilei'Pentru a determina-toate traseele -pe care .le poate 'UDD.abila 'pentru .a .ie§i din teren-vom.folosi functia -recursiva Misca (x, 'Y) , .care.marcheaza.rrecerea -bilei 'prin pozftia(x,y) (transfonn..and_cotain -opusul-ei algebric, pentru -a marca rtrecerea prm pozftia-respectiva), 'apoi.se .autoapeleaza-pentru toate .pozitfile :ad.iacente 'pozttlet (x,y),avando .cota :strict dnferioara.

-vo.i.dMisca (int x , ..int y)

{T [xl (y]-=-T [x] {y] ; / /marcheztrecerea .bd Lea:.if (Out (x, 'y) ) Afisare () ;

·el.se£or (.:i.nt i=O; i<8; i++)

...:if (abs(T[x] [y]) > abs(T[x+dx{i]] [y+dy[i]))Misca(x+dx[i), y+dy[i]); //cota este strict inferioara

T{x] [y]=-T[xJ [y}; } //demarchez trecerea bi1ei

I

i20. Vom reprezenta tabla de sah ea pe 0 marrice patranca T eu n linii §i n coloane, in care

vom marea traseul calului, retinand in fieeare celula pasul la care a fost atinsa,memorat in variabila globala Pas. Vom utiliza doua eonstante eu tip, in care vomreline deplasarea pe linie (ctx}, respectiv cojoana (dy). pentru toate cele opt directiide mtscare posibile pentru un cal.

.int dx[8]={-2,-1,1,2,2,1,-1,-2};int dy[8]={1,2,2,1,-1,-2,-2,-I};

1"

retinem//si retinem configuratia//echipelor//suma=O este optima

/Icalculam suma diferentelor1/daca e .ma L buna

//daca nuexista echipa vida

//daca i-am repartizat pe toti

Iinu i-am repartizat pe toti/Iparcurg toate echipele si//daca in echipa j mai e loe

best_suma=suma; //0£or (i=O; i<6; i++)

best_E[i]=E[i);if (best_suma==O)

afisare () ;

suma=calc_suma();if (suma<best_suma)

e1sefor (j=O; j<P; j++)

if (E [j) . nr<9)

"Voi.d c a LcuL (int k)

int suma, r., j;

if (k==N)

{

..:if (! Echipa_goala () )

{

258

E[j] .elev[E[j] .nr)=k;

E[j] ~nr++;

E [j] . G+=elev (k] ;

ca1cul(k+l);E{j] .nr--;E[j] .elev[E[j] .nr]==O;E[j] .G-=elev[k];

.i.nt main (vo.i.d)

ci ti,r:e.n ;calcul(O);afisare(); return 0;

//pun e1evul k aici//numar inca un elev//actualizez greutatea echipei//trec la elevul urmator//revin, scad numarul de elevi//sterg indice1e

Dinpozitia (L;c) calul sepoate deplasape directia L, deci inpozitia(l+dx [i] ,c+dy [i])

daca §i numai daca T [I+dx [i] ,c+dy [i}] =0 (calul nu a mai trecut prin aceastapozitie).Pentru a nu verifica permanent daca nu cumva ealul a ajuns la marginea tablei desah, bordam tabla de sah eu cate doua linii §i care doua coloane eu valoarea 1.

void Muta_Cal(int x, int y)"{if (!T[x] [y})

{T(x} [y]=++Pas;.if (Pas==n * n) Afisare();

el.sefor (int i=O; i<8; i++) Muta_Cal(x+dx[i], y+dy[iJ);

Pas--; T[x} [y]=O;}

21. Se aplica un algoritm de tip fill, Incepand cu pozijia initiala.

22. Este 0 problema "elasiea" de Backtracking in plan, care cere determinarea unui"drum" Intr-un tablou. Certnja suplimentara de a nu mai treee peste aceleasi caracterereduce foarte mult numarul de mutarf - de fapt, numarul maxim de mutliri este 2 6,ce reprezinta numarul de caractere litere mari ale alfabetului.

l...-'

'''''1

l......,j

PROGRAMAREA iN LIMBAJUL etc + + PENTRU LICEU

void Numara(int Lin, int Col)int k;

if (!viz[T[Lin] [Coll-'A'])

{ viz[T[LinJ [Col]-'A']=l;nrm++;

if (nrm>nrMAX) nrMAX=nrm;

for (k=O; k<4; k++)

Numara(Lin+dx[k}, Col+dy[k]};

viz[T[Lin} [Coll-'A']=O;

Pentru a evita testarea de iesire din tablou am bordat tabloul cu elementul din coI!;U1din stanga-sus, unde s-a efectuat prima mutare. Penrru deplasarea in cele patrudirectii am folosit doi vectori de deplasare (ctx §:i dy). Multimea caracterelor vizitateeste memorata in vectorul caracter-istic viz.

261

"wt") ;

nrMAX) ;

0;return

SOLUTII SI INDICATIl

.int main (void)

FILE *out=fopen("joc.out",

c L tire () ; bordare ()

rezolva () ;

fprintf (out, "%d\n",

fclose(out);

void rezolva(void)

for (int i=O; i<26; i++) viz[i]=O;

nrm=D; nrMAX=D;Numara (1, 1);

#include <fstream.h>

#include <iomanip.h>

f10at p(50]; //preturile speciilor de pesti

int a[50} [50]; //matricea relatiilor de incompatibilitate

int 501[50), So!Max[50]; //vectorul solutie si solutia optima

int NSMax, n;

f10at S, Sum, SumMax;

23. Problema este asemanatoare eu ...Saritura calului", numai ca anumite campuri aletablei nu sunt utilizabile (prin urmare, le vom marca de la citirecu -1, de exemplu).Pentru a detennina toate traseele posibile vom utiliza doua funcjii recursive.Cal_Rege ~i Rege_Cal. Cal~Regedetermina drumul de la pozitia initiala a caluluila rege. La obtinerea unei solutii este apelata functia Rege_Cal, care determinadrumuri de Intoarcere, de la rege la poaitia initiala a calului.

24. Reprezentarea informcqiiiorRetinem in vectorul p, cu n componente, costul fiecarei specii. Relatiile de incorn­patibilitate intre specii Ie vom retine Intr-o matrice astfel: a [ i ] (j ) = 1 daca si numaidaca speciile i §i j sunt incompatibile, altfel a [i) (j ] =0.

Vom construi recursiv solutiile Intr-un vector Sol, in care retinem indicii speciilorcumparate. Vectorul SolMax va reline 0 configuratie maximala a acvariului. CuNSMax am notat numarul maxim de specii ce pot fi cumparate, iar s umr-re x reprezintasuma maxima ce poate fi cheltuita In acest scop.

Conditii interne

Sol [i] E{l. 2 •... , n), Vi;

Sol [i] <Sol [i+1 J, Vi (pentru a nu obtine de mai rnulte ori aceeasi configuratie,convenim sa aseznm pescii in acvariu in ordinea crescatoare a indicilor) ;a ( 5 a 1 [ i l , Sol (j ) ] = O. Vi>*j (oricare doua specii din acvariu sum compatibile) ;

e p [Sol [1] J +p [Sol [2] J + ... ::::::;5 (costul total al speciilor cumparate se incadreaza insuma S).

~,~~

I!,!

Ii~i0, -I} ;1,0,

[MAX] ;

nrm, nrMAX;

O}, dy[] ={

)

fclose (in)

void bordare(void)

int L, j;char c=T [1] [1) ;for (i=O; i<=n+1; i++)

{T[i] [O}=T[i] [m+1J=c; T[i] [m+2)={char)0;

for (j=O; j<=m+1; j++)

T[O] [jJ=T[n+1] [j]=c;

typedef char linie

linie T [MAX] ;

char D [MAX] [MAX) ;

int viz [27J, n , m ,int dx[J={-l, 0, 1,

void citire(void)FILE * in=fopen("joc.in~, "rt");

int i, j;

char x [MAXJ ;fscanf (in, ~%d %d", &0, &m);

for (i=O; i<n; i++)

{fscanf (in, "%s", x);

for (j=O; j<m; j++)

T [i +1] [j + 1] =x [j ] ;

#include <stdio.h>

#include <stdlib.h>

#define MAX 50

{"e~

iJ~~

',~

r:

260

nrm--;

262 PROGRAMAREA.JN LIMBAJUL .C/C++.PENTRU LlCEU

i'

.sOLUTII -SI INDICATII 263

.....J

.25. Vom reprezenta un nod ell -substanta-mnririva ea am-articol eu trei campurl : -x -liniapecarese 'gase1lte nodul; y -, coloanape care -se 'gaseste -nodulst -SN - cantitatea desubstantanutritiva.mn;nod.Configuraparetelei -0 -vorn -rettnefntr-un vector a cu Nrcomponente (NrNod 'fiind numarul de nodurf cu substanta nurritiva), in care retinem.nodurtle cu substanta'alutritiva. -Solujiile -vor figenerate Jntr-un vector p. in care-retinem -ordinea :indieilor .din n.corespunzatoare traseului nimei.Deci, -se cere 0 permutarea eelor NrNod indici rai nodurilor eu substanta nutritivacaresarespecteocondipesuplimentara: IR [p [1] J • x-R [p [i+1 J j c.x I+ IR (p [1 J ] • y­

"R[p(i+1]] .yl'::;;S {distanta-dintreoricaredoua noduri vizitate suceesiv sa fie eel-mult egala eu s, eantitatea totala.desubstanta nutritiva acumulata pana la momentul-respectiv),Solutia flnala este retinutli .In vectorul PMax §i reprezfnta permutarea care 'maxi­-mizeaza s , eantitatea de substanta nutritiva acumulata.

vo.id GenTraseu(int k){.if (k-1==NrNod)

if {S>SMax){SMax=S:for (int i=l: i<=NrNod; i++) PMax[i]=P[i];}

eJ.se:eJ.sefor (.int i=l: i<=NrNod; i++)

if (!uz[i)&&(abs(R[i] .x-R[p[k-1]].x)+abs(R[i] .y-R[p[k-1]] .y)<= S)

{uz[i)=l: p[k]=i:S+=R [i] . SN- {abs (R [i] . x-REp [k-1] J .x) +

abs (R[i] .y-R[p[k-1]] .y»;GenTraseu(k+1):uz[il=O;S=S-R[i] .SN+(abs(R[i) .X-R[p[k-1]] .x)+

abs(R[i] .y-R[p[k-1)) .y»;}

I

-void Ci tire (){ifstreamf (v.acv , in-") ;

:.i.nt i, j;

f»S»n;£or (1=1; i<=n; i++) £»p[i);whi~e (! f ..-e o f ()

{f»i»j; a[1] (j]=a[j] [1]=1;}

f. close (); )

void cumpara(int k)/*cand .apelam Cumpara{k) sunt curnparate

speciile Sol(ll, ... ,Sol[k-l] */int gasit=O; //incercam sa rnai cumparam 0 specie£or (int j=Sol[k-l]+l; j<=n; j++)

if (Sum+p[j]<=S)

(/* testezdaca specia jeste compatibila ell

cele cumparate */for (int 1=1; l<k && la[501[1]] [j]; 1++);

if (!==k)

(gasit=l; Sol{k]=j; Sum+=p[j];

Cumpara(k+l);sum-=p[j]; }

}

if (!gasit) Ilconfiguratia acvariului este maximalaif (k-l>NSMax I I k-l==NSMax && Sum>SumMax)

{NSMax=k-l; SumMax=Suffi;for (j=l; j<k; j++) SolMax[j)=Sol[j];}

.int main ()Citire ();Cumpara(l);ofstream fout ("acv.out");.if (!NSMax)

.rou c-c cvtcu exista solutiil";-eJ.se{fout « "Nr. maxim de specii este "«NSMax«endl;

fout « "Suma cheltuita este ";fout « setprecision(2) « SumMax « endl;fout < "Spec1i1e cumparate s urrt, ~';

for (.int i=l; i<=NSM"ax; i++) fout«SolMax[i]«' •.fout«endl; }

fout.close(); return 0;

I~

I

in functia principala, apelez 0 functie de eitire a datelor de intrare, inftlafizez SMax,eantitatea maxima de substanta nutritiva acumulata, eu -1 §i Incep generarea traseelordin oriee nod eu substanta nutritiva. La sfarstt, voi afisa mesajul Rama moare dacaSMa x a ramas -1 (nu am gasit niei 0 solutie) sau voi aflsa solutia obtinuta in vectorulPMax.

Ci tire () ;SMax=-l;for (.int i=l; i<=NrNod; i++)

{pE1]=i: uz[i]=l; S=R[i) .SN;GenTraseu(2) ;uz[i]=O;}

Afisare () ;.

]....i

Ii iLJ

r1U

: 1U, tI ,

Ur 1! i

LJ

r- -I

i iLJ

u[IlJ

r:

U

u. i

J

~. Elernente de combinator-lea

Hinelude <fstream.h>;int prIOl]., L[lOlj;

long int k;

;i.nt ni

-1) Calculam produsul Pr1=L2*L3* ... *L,," Determinam Pl=l +k/Pr 1"

Scadem din k pe Pr]* (PI-I), calculam Prz=PrJLz sl determinam P2=1+k/Pr zs.a.rn.d. La pasul i, calculam Pri=Pri_1/L i , determinant Pi=l+k/Pr i si scademdin k pc Pr i * (Pi-I)

1. a).

~. a).

3. d).

4. a).

..

265

cin»L[iJ

cin»p[iJ

i++)

i++)

for (i=l; i<=n;

for (i=l; l<=n;

i++) Pr*=L[i];

cin»n;

cout«"Lungimile:

cout«"Elementul:

(Pr=l, i=l; i<=n,:

(i=l; i<=n; i++)

{Pr/=L[i] ;

k+=(p[i]-l)*Pr;

cout«k«endl;

return 0;

int i;long Pr;

Ilcitire

cout«"n=

SOLUTII SI INDlCATII

forfor

#lnclude <fstream.h>

:i.nt p[I01], L[IOl];

long int k;

int n;int main ()

~~,~'I~il,~~Iii'

!I~

"

PROGRAMAREA iN LlMBAJUL CIC+ + PENTRU LlCEU264

toate elementcle pentru care e I =P 1 , e 2=P2 , .•• , e n_1=Pn-l ~i en<r-, (aeestea sunt P n-1).

Totalizand, obtinem formula :

') Fie P =(p 1 ' P2' ... , p) un element al produsului eartezian. Numarul sau de ordine esteegal eu numarul de elemente ale produsului eartezian care il preced in ordine Iexico­grafica. inaintea elementului p se afla toate elementele e =(e

1, e

2, "', en) pentru care:

e j < P l (acestea sunt (P j-l)*L2*L3* ... *Ln);toate elementele pentru care c, =P 1 si e;:<P

2(accstea sunt (p;:-l) * L 3*L4* ... *L) ;

cout.«"Lungimile: "; for (i=1; i<=n; i++) cin»L[i];

cout«"Numarul de ordine: "; cin»k;

for (Pr=l, i=1; i<=n; i++) Pr*=L[i]

fO;E;" (i=1; i<=n; i++)

{Pr/=L[i]; p[i]=k/Pr+l;

k-=(p[i]-l)*Pr;for (i=1; i<=n; i++)

cout«p[i]«'cout.«endl;return 0;

9. Yom genera permutar-i de dimensiune n- (y-x), dar Ia afisare, atunci cand Intalnimvaloarea x , vom afisa Intreaga secventa x , x+l, ... , y, iar valot-ile mai mari decat xvor fi translate eu (y- x ) .Numarul de solutii este, evident, (n-y+x)

*include <fstream.h>

I/apel recursiv

abs(p[k-l]-i»v)

Ilcontinuam generarea

parametrul k, pozitiile

sunt fixat-e*1

I/solutia este completa

i=l; i<=n; i++)

(!uz[i] && i==l II

{p[k]=i; uz[i]=l;

Gen(k+l) ;

uz[iJ=O; }

(i.nt

if

for

void Gen (int k)

I*eand apelam functia Gen eu

1,2, ... , k c- L din v ec t.o z-u L p

(if (k-l==n)

Afisare ()

e~se

7. Numarul de euvinte de lungime n formate eu cele 26 de litere mici ale alfabetului este26". Cu 0 litera oarecare x incep 26 n - 1 cuvinte.

8. Problema solicitii generarea tuturor permutarilor de n elemente care respecta 0condirie supfimentara : IP[kJ-P[k-l] I>v, pentru orice kE{2, 3, "', n}. Pr-inurmare, vom modifica programul de generare a permutar-ilor, ver-ificand §i aceasraconditie :

cin»n;

i.nt main ()

int i;

long PrJ

/Icitirecout«"n=

~[(P' -1) n,L,) :i.nt n, p[40], uz[40], x, y, nr;

ofstream tout ("perm. out"); /Itisierul de iesire

:266 ,-PROGRAMAREA 'iN _LIMBAJUL C/C++ PENTRU-ClCEU

.',·SOLUTII $1 INDICATII 267

~,, ,, i1... ...1

"Vo:idA"fis-are (.)

.:i.nt i, j;:for (i=l-ii<=nr; .i++)

..5..-£ (p[il==x)£or (j=x; j<=y; j++) fout«j«'

'e~se

if (p [i] >x) £out«p ['i]+ (y-x)«'

,e1se fout«p j Lj-c-c ' ••

fout«endl; )

.,.

~or (.i=l; i<~n;.i++)

.if (!uz"[i){

:for (ok=l, j=l; j<k .&& ok; j++)i~ (abs(j-k)==abs(i-p[j]) ok=O;

.if (ck)

{p[k]=i; uz[i]=l/.cenaermucar L (k+l) ;uz[i}=O;}

L."

'-

1

L;

li-j l:;elp[i]-p[j] I; 'Vi, j e j t , 2, ... , n}, i:;ej

r :.

, ,, i. ,

W

'-J

r'~

w

,I~

:-

'-I

U

I !

, 1,u

vo~d GenCombinari(~nt k){/*eand apelam functia GenCombinari eu parametrul k

pozitiile 1, 2, ... , k-l din veetorul e sunt fixate*/if (k-l==m) //solutia este completa

Afisare () ;'e~se //eontinuam genera reafor (int i=c[k-l]+l; i<=n-m+k && i+V<=VMax; i++)

(c[k]=i; V+=i;GenCombinari(k+l);V-=i; }

12. Pentru a forma 0 echipa trebuie sa selectam m fete din cele f care exista in clasa, deeitrebuie s:l generarri combinartle de f luate care m. Fiecare grupa de fete poate ficompletata de 0 grupa de p-m baieti, Prtn urmare, trebuie sa generam §i toatecombinartle de n-f baieti Iuati care p-m. Echipele se constituie din orice grupa defete. completata cu orlee grupa de baieti,o alta solujie ar fi numerotarea fetelor de la 1 la f. iar baietii de la f+1 la n §i dea constitui toate echipele de p elevi din eei n existenti in clasa (combinarl de n luatecate p). impunand 0 conditie suplimentara : numarul de fete sa fie m.

13. Vom genera Intr-un vector toateriumerele prime mai mici decat n. Modificamprogramul de generare a partititlor unui numar natural. astfel Incat Sa utilizeze numairmmerele prime generate.

14. a) Numarul de modalitati distincte de a pIasa n obieete in p cutii, astfel Incat in eutia1 sa se atle m

1obiecte, in eutia 2 sa se atle m2 obiecte, ...• Iar in cutia p s~ fie plasate

mp

obieete este :

11. Trebuie sa generam combinarile de n' elemente luate care x, .astfel dncat sumaelementelor oricarei submultimi sa nu depaseasca valoarea VMax. Prin urmare, vommodifica programul de generare.a combinartlor, vertficand §i aceasta conditio. Pentru.aceasta, vom eonsidera 0 varfabila globala v ; in care vom retine permanent sumaelementelor fixate in submultime. Punctia modificata de generare a combinarilcr este :

//solutia este completasolutiei eonsta in afisare

//continuam generareacandidatii pentru pozitia k/ /determin

/ /preluerarea

void GenPermutari(~nt k)/*eand ape lam functia GenPermutari ell parametrul k,

pozitiile 1, 2, ... , k-1 din veetorul p sunt fixate*/

(i.nt i, j, ok;.if (k-1==n)

Afisare() ;.ea.ee

""Void GenPermutari (.i.nt k)/*cand .apelam functia GenPermutari Cll parametrul k,

pozitiile 1,2, ... ,k-l din vectorul p sunt fixate*/{:if (k-l==nr) I/solutia este campleta

Afisare(); /ipreillcrarea salutiei consta in afisare~1se //continuam generarea

//determin candidatii pentru pozitia k

for (:i.nt i=1; i<=nr; i++)

if (!uz[i])

{p[k]=i; uz[i]=1;/*i este un candidat, deoarece nu este

irnaginea nici unui alt element fixat*/GenPermutari (k+l); / lapel recursiv

uz[i]=O; }

i.nt main (){cout«"n, x, y= "; ein»n»x»y;

nr=n- (y-x) ;GenPermutari(1) ;fout.elose{); return 0;

10. Vom modifica programul de generare a permutarilor, impunand 0 conditie -suplt­

-mentara :

n!

!fIl!>< m2!><·· .><mn!

,

-i

_=-_=:_ iN LIMBAJUL C/C++ ;'-~~~7~~ i.rcsu SOLUTII SI INDICATII 269

22.

;. Problema este echivalenta cu determinarea -numarului de airur-i cu 0 elemente dinmultimea {-1, O. I}. care 'sa condna eel putin un 1. un 0 $i un -1 ~i pentru carenumarul elementelor ncnule este a .Cele n- s elemente nule Ie putem aseza in ~ir pe orice pozttie, deci numarul deposibilitiiti este ega! cu numarul de submultimi de n-s elemente ale multimii {I.2 ••.•• n} (deci Comb(n,n-s)=comb(0,5».Raman s pozijii in sir; fiecare poaitie poate avea valoarea 1 sau -1. Exista 2 s

posibtlttati , dintre care doua se exclud (cea in care toate valorile sunt 1 ~i. respectiv,cea in care toate valorile sunt -1)". Deducem ca -numarul de solutii este:

(2~-2) Comb (0, 5).

16. Sa notam eu T (o) numarul de permutari de ordin 0 care au proprietatea din enunt.o astfel de permutare trebuie sa cantina numai cicluri de lungime 1 sau 2. Dacap (0) =0, cele n-1 numere din fata lui n pot fi asezate in T (0-1) moduri pentru aobtine 0 permutare eu proprietatea din enunt. Daca p mj sen, va exista k-err, astfeltncdt p (0) =k $i p (k) =0 (altfel , 0 ar face parte dintr-un cicIu de lungime mai maredecat 2). Numerele din {I. 2, 3, ...• o}-{k. n} pot fi asezate in T (0-2) moduri $i. cumk poate fi orieare din cele n -1 numere, avem (n-1 ) * T (0- 2) permutari ce verificarelaria ceruta, in care p (0) sen. In total. obtinem relatia de recurenta T (0) =T (0-1) +(0-1) *T{n-2). Este ncccsara implementarea operanilor cu numere mario

-.7. Pentru detenninarea gradului unei permutari se fbloseste descompunerea permutiiriiin cicluri. Un cicIu de lungime k intr-o permutare este 0 secventa 1:S::;il' i 2•...• ikSncuproprietateaCap[i l]=i2• p[i2]=i 3•...• p[ik]=i l·Sa observam ca :p2 {il' =p (p (i l) =p (i 2 ) =i 3p3(~1)=P(p2(~1) )=P{i3)=~4

pk (i l) =p (pk-l (ill ) =p (i k) =i l

Acelast lucru se tntampla $i eu i 2 •••• , ~k'

Sa consideram descompunerea permutarfi p in produs de cicIuri. Dedueern eagradul permutarii este eel mai mic multiplu comun al lungimilor ciclurilor dindescompunere.

18. Determinam numarul de etaje la care exista angajati $i atribuirn fiecarui etaj catc 0cuIoare. Pe masura ce citim datele referitoare la angajati, vom verifica daca etajullacare lucreaza angajatul are asociata a culoare st, daca nu, ii vom atribui 0 nouaculoare. Daca ajungem in situatia in care numaml culorilor disponibile este mai miedecat numarul etajelor determinate. atunci problema nu are solutie. Atribuind cate 0

culoare fiedtrui etaj, practic, am rezolvat cea de-a doua parte a problemei. Pentruprima parte vom considera ea avem hi dispozitie k culori $i exista x etaje la carelucreaz~ angajati. Va trebui sa determinam numaruI de posibilitiiti de a atribui celorx etaje dite 0 culoare astfel iDcat fiecare etaj sa aiba propria sa culoare. Practic. secere detenninarea submultimilor ordonate de x elemente ale multimii {l. 2, ...• k},adica aranjamente de k elemente luatecate x.

20. Daca permutarea datil era cea identica. numarul de minute necesare este O. Descom­punem pennutarea in produs de cicluri. Daca permutarea data contine numai cicluri

[j.:

t:";

f~j~'

de lungime 2.· numarui necesar de minute este 1 (in acest minut i§i schimba locurilesimultan toate perechile de persoane inversate). Daca permutarea contine eel putinun cicIu de lungimemai mare decat 2. .arunci numarul necesar de minute necesareeste 2. Sa consideram ~l' i 2,....• ~k un ciclu oarecare al permutarfi (p[i lJ=i2 'p[ i 21=i 3, ...• P[ikl=~l)' In primul minut, interschimbam e j j i j Cllp[ikJ. p[i

2]

cu p [1 k_l ] s.a.m.d. Daca ciclul are Iungime impara, elementul din mijloc ramaneneschimbat. In minutul al doilea, schimbam p[i21 cu P[ikl, p[i 3] Cll p[ik_1ls.a.m.d., obtinand astfel configuratia dortta. Procedam simultan in acest mod eutoate cicIurile din descompunerea permutarii date.

Se calculeaza mai intai numerele lui Catalan. care reprezmta numaruI de siruricorect parantezate.

10ng Catalao[lOl];void Determina_Cata1an(){int j, k;

Catalan[O]=Cata1an[1]=1;for (k=2; k<=o; k++)

for (j=O; j<k; j++)Catalan[k]+=Catalan[jl*Catalan[k-j-1);

Sa consideram ca functia recursive Nr_ord (i, n) determina numarul de ordine aIunui sir coreet parantezat care Incepe la pozitia i in sirul dat si are 0 pereehi deparanteze. Sirul nostru are forma (o.)f3.Pentru a calcula numarul sau de ordine, trebuie sa determinam numarul de siruricorect parantezate ce preeed sirul dat.Sa dcterminam pozitia x pe care se afla paranteza tnchisa corcspunzatoare primeiparanteze deschise $i sa notam eu k lungimea acestui str corect parantezat. Sirul dateste preeedat :

de toate sirurtle de forma (o.)y. unde y preceda pe f3 (exista Nr_ord (i+k+l,n -1-k/ 2) posibifitati) ;de toate sirurile coreet parantezate care pe pozfjia x au paranteza deschisa ;numarul de posibilitati este :

~ Catalao[jjxCata1an(n-1-jjjw~/2'1

de toate sirurile care au pe pozitia x paranteza Inchisa, dar pe poziriile i . . x seafla un $ir care preeeda pe a (exista Nr ord (~+1, k/2) *Ca talan [n-1-k/2 ]posibilitilti) .

long Nr ord(~nt ~, int n)/* determina numarul de parantezari care preced

parantezarea care incepe 1a pozitia i si cont~ne nperechi de paranteze */

{long nr=O;

int j, k, dif=l, x;

if (!n) return 0;

270 'PROGRAMAREA -iNLIMBAJUL -C/C++'PENTRU LlCEU

,.SOLUTII:;iI INDICATII

.271

r Iir

-'

I~ determinpo~itiapecare 'se -afla paranteza inchisacorespunzatoareparantezei ~eschise de ~epozitia ~ ,*/'for (k=;O; 'rlif;,)

{k++;:.if (s[i+k]==' (f) di"f++;

>el.se ,dif--;

)

£or (j=n-l; j>=k/2+1; j--)

nr+=Catalan[j)~Catalan[n-~~jl;nr+=Nr_ord(i+l, k/2) * Catalan[n-l-k/2];

return nr + Nr_ord(i+k+l, n-l-k/2); }

24. Culm!Numarul de combinatii corecte posibilereprezintli exactnumerele Catalan (n) •

Numerele Narayana suntdate de formula:

N (n,k)=}..C~C~-\ 1 £k£nn

Si reprezinta 0 descompunere a numerelor Catalan data de urmatoarea -suma :

Catalan (n)=.LN (n,k),'.

Urmarind ."muntii" figurari conform conventiei, se observa ca N (n, k) reprezmtanumarul de "munti" care au exact k varfurt.

25. Numim multimultime 0 multime in care elementele se pot repeta. Exista

c::::: +-""_1+-•••+-n~-dposibifitati de a insera k-urile Intr-o permutare a multimultimii {n 1 *1, n 2*2 •... ,n

k_

1* (k-1 ) }, .unde eu n

1* i am notat n 1 elemente eu valoarea i.

Deci solujia este :pn c~: +-nk_1 +•••+nk_d,.,

26. Fie B (i) b-str--ut de lungime i. Se poate genera b-sir-ul de lungime 21+1 in

urmatorul mod: B (2 1 + 1 ) =8 (2 1 ) concatenat eu complementul binar .al Iui B (21

) •

Precalculam sirul x (i) eenumarul de palindromuri dintr-un b-str de Iungime 2 i •

folosind recurenta :.• X(i)=2*X(i-I)+ 2 1 - 1 , daca i epar;• x (i) =2*x (i-I) +(2 1_2) /3. daca i e impar.

Consideram b-§ir-ul ca fiind indexat incepa.nd cu 1, adicii pe pozitia 1 se va aflaprimul element al §irului. Pentru a calcula numa.ml de palindromuri dintr-un b-§ir delungime N. vom afla cea mai mare putere K.astfel inca.t 2K= N (se considera N¢21<pentru ca in aeest eaz putem atla r~punsul din valorile tabelului x). In momentulaeesta, problema se imparte in trei stibprobleme :1. determinarea numarului palindromurilor din §irul de lungime 2K (acest pas se

rezolva utilizand valorile precalculate mai sus in tabelul x) ;

2. determinarea 'numarului -palindromurilor care au capatuldin"8tanga.intr-o pozfjie-mai :miel -sau egala -decat 21( ~i eel .din dreapta intr-o pozitie 3Il3.imare decat '2 K;

3. -determinarea mumarului -palindromurilot -din 'porthmea .de ~ir .care Jncepe""din'pozttia 21<+1 _~i -se rermina :in pozfjta N.

Din -simetria b-gir-ului, 'eubproblema '3 'poate .fi -redusa Ja ca-calcula 'palindromurtledintr-un b-str de lungime -N_Zk. I

jnrezolvarea.subproblemei 2 apar, 'din-nou, .doua .cazuri :.a) pentru K par, 'numarul palindromurtlor vafi N-2K;

b) 'pentru x impar; observam c~ Ia pozitia 2 k+ 1 '§i a'az-setcrmina N/2 palindromurf,la urmatoarele 6 pozlttt ,(panlla B) .se termina N/ 2 -1 palindromuri Ja .urmatoarele24(pana la 32) .se termina N/2-2 -palindromuri .s.a.m.d ;se -observa ca -putemdetennina in timp logaritmic 'raspunsul pentru -subproblema 2, .In.acesr caz.

La flecare pas, N -se reduce eu eel 'putin jumatare .din valoarea sa. in concluziecomplexitatea va fi Iogarltmuca.

5. Metoda programarf] dinamice

1.' Problema se reduceIa determinarea eelui mai-lung subsir strtct crescator a1 siruluiinlHtimilor soldajilor.

2. Problema este .asemanatoare eu problema triungbiului.

3. Vom considera ea subproblema determinarea numarului minim de operatii neeesarepentru a ealcula JOIN-ul intre tabelele L, i+l •...• j (l:5i:5j:5N). Solutfile subproble­melor Ie vern retine Intr-o matrice A .cu N linii §i N coloane, unde A [i] [j] estenumarul minim-de operant pentru a caleula JOIN-ul intre tabelele L, i+I, ...• j.Initializam diagonala pr'incipala eu a (A [i] [i] = 0). Pentru a calcula A [ i J [j] • saexaminam ealculul JOIN-ului corespunzator. Acesta este rezultatul JOIN-ului dintretabela objinuta din tabelele de la i la k Si tabela obtinuta din tabelele de Ia k+1 la j.

unde k variaza de la i 1a j -1. Numarul de operatii rezultat este A [i) [kJ +A [k+1] [j) +numarul de operatit al JOIN-ului final (produsul numarului de elemente din eele douatabele). Pentru a determina A [i] [j] este necesar caleulul pentru toate valortle lui kposibile §i selectarea valorfi pentru care se obtine ntinimuI.

4. Se citeste textul §i se memoreaza euvintele distincte Intr-un tablou c.

Fie n c numarul de cuvinte distincte determinate. Fiecare cuvant este numerotat de laa la nc-1 (indicii din tabloul c). Observati ea numerotarea cuvintelor respectiiordinea primei aparitii in text a cuvintelor. Construim 0 matrice A eu nc linii §i nceoloane. cu elemente a §i 1. A [i] [j J=1, dac~ numarut minim de operatii insert§i delete necesare pentru a transforma cuvantul c [i) in euvAntul c [j] este maimic sauegal eu k (i<j), §i o. in caz contrar.Pentru a determina matricea A trebuie sl1 rezolvam urmiitoarea subproblema: sa sedetermine numarul minim de operatii delete §i insert necesare pentru a transformacuvantul x in euvcintul y.Rezolvam aceastli subproblema prin programare dinamiea.

r •

, :: :u

f'1

:....r

iw

,,;......J

, 1

u

;'1• r: r, iW

i i'-'

i, i

U

!!

'-'

,!

u

iI

LJ

SOLUTII SI INDlCATH

void Adauga_Cuvant(char *p)

{int i;for ·(i=O; i<nc && strcmp(p,c[i]l); i++);if (i==nc) strcpy(e[nc++),p);

void Ci tire (){ifstream fin(InFile);char s[1001J, *p;fin»k; fin.get(};whi1e (!fin.eof(»

{fin.getline(s,lOOl);if (fin.good())

{p=strtok(s," .;;?!-");

whi1e (p){Adauga_Cuvant(p);p=strtok(NULL," .:;?!-");

272PROGRAMAREA iN LIMBAJUL C/C + + PENTRU LICEU

Fie d (i 1 L'l l numarul minim de operatii insert §i delete necesare pentru a trans­forma sufixul lui x , care Incepe la pozttia i, in sufixul lui y, care Incepe la pozitia j .

Fie n lungimea ouvantului x ~i m lungimea cuvantului y.dEn] [jl=m-j, pentru orice j=O,m;d [i] [ml e-rr-e L, pentru orice i=O, n;d[i] [jl=min {d[i+l] [j+l1,dacap[i]==q[j]; - move

l+d[i] [j+l J - insertl+d[i+l] [j] - delete

Solatia este d(O] [OJ.Pentru a determina numarul de Ianturr de k-similitudine sa notam eu nr (i] numarulde Ianturl de k-similitudine care Incep eu cuvantul LDetermirUim nr folosind urmatoarea relatie de recurenta :

nr [i l =1, daca cuvanrul i este terminal (nu exista nici un cuvant astfel rncat saputem obtine cuvantul j din cuvantul i ell eel mult k operatii) ;nr[i)=nr[i

1] +n r [ i z ] + ' .. +nr[i

k) . unde i 1 , i 2 •••• , i k sunt cuvinte cu

proprietatea ca A [i] [i j l = 1, pentru j =1, k.

#inelude <fstream.h>#inelude <string.h>#include <stdlib.h>#define InFile "lant.in"#define OutFile Ulant.out"

#define LgMaxC 31#define NrMaxC 151

typedef char Cuvant(LgMaxC);

Cuvant e[NrMaxC];/* cuvintele distincte din text, in ordinea primei aparitii */

int nc, k;int a [NrMaxC] (NrMaxC];int d[LgMaxC+1] [LgMaxC+1];~ong int nr[NrMaxC];/* nr(i]= numarul de lanturi de k-similitudine care incep ell

euvantul i */

void Citire ();void ConstrA () ;void Numara (int) ;

void main (){i.nt i;

ofstream fout(OutFile);

Citire() ;ConstrA () ;Numara (0);

II

II

Iil!

Iti,I

Ini~

I,!!II

i~

I~"

fout«nr [0] «endl;.r cuc . close () ;

}

fin.close() ;int dist (char *p, char *q)//determina distanta de editare dintre p si q

int D, m , i, j;n=strlen(p); m=strlen(q);for (i=O; i<=n; i++) d[i] [m]=n-i;for (j=O; j<=m; j++) den] [j]=m-j;for (i=n-1; i>=O; i--)

for (j=m-l; j>=O; j--){d(i] [j]=l+d[i] [j+l];if (d[i] [jJ>l+d[i+l] [j])

d(i) [j]=1+d(i+1] [j];if (p(il==q[j] && d[i) [j]>d[i+1] [j+ll)

d[i] [j]=d[i+l1 [j+l1;}

return d[O] [0]; }

void ConstrA (){int r , j;for (i=O; i<nc; i++)

for (j=i+l; j<ne; j++)if (dist(c[iJ,c[j])<=k)

{a[iJ [0]++; ali] (a[i] [O])=j;

273

~.."

c~ ·bo+C~ ·bl + ...+C~-l·bn_i+C~ ·bn

;~'

~

-'

:;

!,,

LJ

r )

!j!I'l" I"IrI!\i~l!i '

~

~

, '

w

, ,,

: 1

..J

275

&& Barbu[j-1]==Amestec[i+j-1])"

&& Ana[i-1]==Amestec[i+j-1])

Barbu [LgMax+1.J ,'funestee [2*LgMax+1.] ;

(i && T[i-1] [j]

T[i] [j] = 'A';(j && T[i] [j-1]T[i] [j] = 'S';

if

void afisare(vo:id)int i, a=Lg1, b=Lg2;char rez[2*LgMax];FILE *fout=fopen(OUTPUT_FILE,"wt");/*reconstituirea solutiei */£or (i=O: i<Lg1+Lg2: ++i)

{ rez[a+b-1]=T(a] (b];if (T[a] [b]=='A') --a;

e1se --b;

SOLUTIISI'INDICATII

}

for (i=O; i<Lgl+Lg2; ++i)fprintf(fout, "%e", rez[i]):

fprintf(fout, "'nit), fc10se(fout);

#inelude <s-cctdo., h>'#ine1ude '<string.h>>#define INPUT_FILE ""joc.i.n"

. 'itdefine OUTPUT_FILE "j c c c o utr''-#define LgMax '1.50-#define 00-1char Ana[LgMax+1.],::int Lg1, Lg2;char T[LgMax+~] [LgMax+1];vo:i.d ci tire (void){FILE '*fin=fopen (INPUT_FILE,"ltrt") ;fseanf (fin, "'%s", Ana);zs can.r t r r n , "%s", Barbu);fscanf(fin, "%05", Amestec);Lgl = strlen{Ana); Lg2= str1en(Barbu);fclose(fin); }

void rezolvare(vo:i.d){int i, j;£or (i=O; i<=Lgl; ++i)

~or (j=O; j<=Lg2; ++j)T[i] [jf = 0;

T(,O] [0]=00;for (i=O; i<=Lgl; ++i)

for (j=O; j<=Lg2; ++j)(

HiIIII~

I

'Numara (a [vfl [i]) ;

PROGRAMAREAiN LIMBAJUL C/C++ PENTRU LlCEU

-if (nr[a[vf] [i]]==O)s+=nr [a (vf] [i]] ;

Inr(vf]=s;

-void Numara,(i.nt vf){:int i;if (!a[vf] (01) {nr[vf],=l; '%'eturn;}~ong .ints=O;-for (i=l; i<=atvf] [0]; i++)

{

Prin urmare.cproblema se reduce la a determinatoate valorile b o' b l , .••• b n pentrucare expresia 'precedenta rare valoarea s. Aceasta problema este .asemanatoare cupro'!'lema rucsacului,

6. 0 subproblema a problemei date consra in a determina pentru fiecare pozttie i:::;ncostul (energia minima) pentru a ajunge de 'pe pozttia i pe pozitia n . Pentru a rettnesolutiile subproblemelor VOID utiliza un vector cost eu n componente (cos t [i] =energiaminima necesara pentru a ajunge de pe cotetul i pe cotetul n}. Evident, cost in] =0.Sa notam cu frrna x [i] cea mai mica pozrtte (mai mare dedit L) pentru care serealizeaza maximul inaltimilor pe segmentnl (i+1, n]. Prin definitie, hmax [n] =n.Pentru a ajunge in mod economic de la cotetul i la cotetul n (daca este postbil, adicahi "2: hhm"xliJ)' trebuie sa ne deplasam fi1ra·aterizliri intermediate de la cotetul i lacotetul nma x [i] , apoi de la hmex [i 1 hi n , Costul deplasarii fi1raaterizari inter­mediare de la eotetul,i la cotetul hmax(il este (hmax(i]-i-l)-(h~-hl'"n"x{il)

deoarece se consume (hmax [ i 1- i -1) unitati de energie pentru zborul orizontal ~i

se c~tiga (hi-hhmaxlil) unitati de energie prin zborul in picaj pana la tnatumea

hhmaxliJ'Obtinem astfel relatia de recurenta :

cost [i 1= (rimax [i] -i-1) - (h1-hhm"xlil) e co s t; l frma x [i] 1

7. Subproblemele problemei date constau in determinarea capartenentei literelor dincuvantul obtinut prin amestecarea prefixului de lungime L, din cuvantul ales de Ana,eu prefixul de hmgime j, din cuvantul ales de Barbu. Pentru a retine solutfilesubproblemelor vom utiliza 0 matrice T cu Lg1+1 Iinii (unde Lg1 este Iungimeacuvanrului ales de Ana) si Lg2+1 coloane (unde Lg2 este lungimea cuvanrului ales deBarbu) eu semniflcatia ca T (i] [j] este litera corespunzatoare eoncurentului (A sauB) caruia ii corespunde litera din cuvantul obtinut prin amesteearea prefixului delungime i, din cuvanrul ales de Ana, cu prefixul de lungime j • din cuvantul ales deBarbu.

)

s. inaltimea maximaa piramidei este (10g 2 s 1+1. Daca VOID considera ca la bazapiramidei sunt valorile b o' b p ..•• b n• atuncivaloarea .care se obtine in varfulptramidei este :

274

I

Ii

276PROGRAMAREA IN LIMBAJUL CtC + + PENTRU LlCEU SOLUTII Sf INDICATII 277

o alta optimizare (de data. aceasta a spatiului de memorie) se poate face observandca pentru a calcula linia k din matricea nrmax este necesara numai linia k-1. Prinurmare, este suficient sa folosim numai doi vectori (crt ~i pre) in care vom memoradoua Iirri'i consecutive din matricea nrmax - lima precedenta ~i linia curenta.

#include <stdio.h>#include <string.h>#define NKMax 1000#define MAXVEL 1000000~nt raman [NKMax] [NKMax];/* raman[i] [j] este numarul de v e c L care raman vii daea vacilede la i la j sunt urcate in aeelasi vagan */~nt slab (NKMax] [NKMax];~nt tare (NKMax] [NKMax];·int 19[NKMax], N, NrV, MaxV, NrP, rez;void init(){/*prepraeesare */int i, j, k , z, mar;int viu (NKMax];for (i=G; i<N; ++i )

for (j=i; j<i + MaxV && j<N; ++j/*urcam vaeile de la i la j in aeelasi vagon */

{mar=1 ;memset(viu, 1, NKMax * sizeo£(int) l;/* initial toate sunt vii */whil.e (mor) /*cat timp mai mar. */

{mar=O;for (k=i; k<=j; ++k)

for (z=O; z<lg [k]; ++z){

/*pareurg vacile mai slabe deeat vaeanr. k din aeelasi vagan*/

if {viu[k] && slab[k] [zJ>=i &&

slab[k] [z]<=j && viu[slab[k] l e J ] )if (tare [k] [z 1<i I I tare [k 1 [z 1>j I I

!viu[tare[k] [z]l l{ viu[slab[k] (z]] = 0;

mar = 1; }

int main (void)t: {citire();;i. rezolvare ();

afisare(); return 0;

o subproblema a problemei date consta in determinarea produsului maxim de jfactor! obtinuti prin inserarea a j -1 operatori intre -primele L cifre din sir. Pentru aretine solutiile subproblemelor vom constr-ui 0 matrice A cu N linii $i K+l coloane,in care A [i] [j) reprezinta eel mai mare produs ce se poate construi inserand j-1operatori (deci avand un produs cu j factori) intre primele L cifre. Un astfel deprodus este format dintr-unul cu j -1 factori al prirnelor p cifre (p-c L}, Inmuljit cu unnumar format din cifrele de pe pozttiile p+1, p+2, ... , i. Evident, A[i] [j] secalculeaza folosind A [p] (j -1 J cu p<i si respectand conditiile din enunt (un numarnu incepe cu 0 etc.). Rezultatul se obtine in A [N] [K+1]. Observati caimplementareaacestei metode necesita folosirea operatiei de Inmultire pe numere mat-i. 0 idee deoptimizare, care ar elimina aceasta complicatie, se bazeaza pe relatia matematica"logaritmul produsului este egal cu suma Iogaritmilor", Astfel, rransformam numerelein logaritmi si tnmultirea in adunare. A[i 1 [j] va contine astfel Iogaritmul produsuluiamintit rnai sus. Practic, in lac sa inmultim un produs cu un numar format din cifrelep+ 1, p+2, ... , i, adunam la logaritmul acestui produs logaritmul numarului respectiv.

1. Consideram ca subproblema a problemei date numarul de posibifitati de tmparttre asumei x conform conditiilor din enunt, folosind valori :s; v. Pentru a retine solutiilesubproblemelor vom utiliza 0 matt-ice c eu S linii ~i S eoloane. Obtinem recurenta :

c l v l [x} =c (v-l J l x l , punand pe prima pozitie valori :s; v-I+e [v-I] [x-v] , punand pe prima pozitie v ;

c Lc l [0]=1, c t o j [x]=O, pentru x>O.

Numarul total de posibilitati va fi obtinut in c [S] [S] .Reconstiruirea solutiei se face stabilind priroul numar ca fiind eel mai mic i, astfel Incate [i) [S]~N ~i e [i-I) t s j <N. Procesul continua pentru S=S-i si N=N-c [i-I] [S]

pana cand N=O.Pentru a optimiza memoria folositii, observam ca recurenta depinde doar de liniaantertoara, asa di ea se poate calcula folosind un singur vector.

10. 0 subproblema a problemei date consta in a determina numarul maxim de animalevii care raman jncarcand vacile i, i +1, ... , N in k vagoane. Deoarece enuntulsubproblemei depinde de doua variabile, deducem ca pentru memorarea solutiilorsubproblemelor este necesara 0 man-ice n rma x cu NrV linii (NrV fiind numarul devagoanc) §i N coloane (N fiind numarul de vaci),Vorn incarca vacile i, L+1, ... , j in primul vagon (cu conditia ca j - i +1 sa nudepaseasca MaxV, numarul maxim de vaci care incap tntr-un vagon, deci j .variaza dela i lai+MaxV-1), apoivomrepartizaoptimalvacile j+1, j+2, ... , n tn cele k-lvagoane ramase. Obrinem rclatia de recurenta :

nrmax[k] [iJ=max{raman[i} [j]+nrmax[k-l} [j+l]}j=j.,i+MaxV-l,j:S;N

uncle cu raman (i 1 [j] am notat numarul de vaci ce raman vii, daca sunt Incarcatein acelasi vagon vacile t.. i+1, ... , j (aceste valori vor fi calculate in prealabil ~i

memoratc in matricea raman pentru a optimiza algoritrnul).

!IIi!,~

~~i

Ial~

I"i,II~~~

for}

(k=i; k<=j;if (viu[k]l

++k) /*numar vaeile++raman[i] [j];

care au ramas vii */

~,-' ,,~------

r"

n.#include <stdio.h>

#define MAX 100#define INFILE "fat.in"

#define OUTFILE "fat.out"

iU

, i

'-'

'-'

~

r!

~

--i

~

, .

, 'r

u

.'-'

iU

'-'

, .,, i..'-'

[ 1

279SQLUTII <~I INDICATII

voi.d citire(void){FILE '*f=fopen ( INFILE, "rt" ):fscanf(f, "%s", sl);

fscanf(f, "'s", s2):fscanf (f, "%s", s3);fclose (f) ; }

voi.d gen_a (voi.d)( -int i, j;

£or (i=O: i<MAX + 1; i++ )for (j=O; j<MAX+1: j++)(a(O] [i] [j) .1g=-I; ali] [0] [j] .1g=-I; ali] [j] [O].lg--l;}

a[O] [0] [01.1.9 = 0;

. }

voi.d rezo1va(int i, int j, int k)(int s i , jl. kl,'. b;

char tasta(5] [5], temp:ali] [j] [k) .1g-0;for(i1-0; il<5: il++)

for{jl=O; jl<5; jl++)tasta[il] [j1]-'l';

for (iI-I; (il<5) && (i-il>=O); il++ )for (jl-I; (j1<5) && (j-jl>=O); j1++

{temp- '-1' ;'for {kl-1; (kl<5) && {k-kl>=O); k1++

{i.f ({sl[i-il]-=s2[j-j1]) &&

(s3[k-kl]=-s2[j-jl]) && (temp-'l'){for (b=O; jl+b<=4; b++)

tasta[jl+b] [kl]=sl(i-i1];

}

if (tasta[j1] [k1] !='1'

temp=tasta[jl] (k1]; )i.f «a[i-il] [j-j11 [k-kl) .1g+1>a[i] [j] [k] .lg)

& & (temp! -' 1 ' ) )(ali] [j] [k] .1g-a[i-il] [j-jll [k-kl] .1g+1;a[i1 [j] [k] .x=i-il; ali] [j] [kJ .y=j-jl;

ali] [j] [k].z=k-kl;ali] [j] [k) .c=temp;

<stroct tiplint -x , y, ·z;-<char c;.:int .1g; };

~truct tip a {MAX+2] [MAX+2] [MAX+2];.char s a [MAX+2], 052 (MAX+2], s3 [MAX+2] ;

:int a.i , :1'2, :1'3;·.char s [MAX+2];

I

Icrt[il=O;

PROGRAMAREA iN LlMBAJUL CIC++ pENTRU LICEU

(1=0; i<N; ++1 )

( pre[il=crt[i];for

return pre [N-l) ;

int ma Ln (){FILE *fin=fopen("transport.in", "r");

FILE *fout=fopen{"transport.out", "w");

5..nt i;fscanf(fin, "%d %d %d", &N, &NrV, &MaxV);

fsc;anf (fin, "%d", &NrP);

for (i-D; i<NrP; ++i)

{i.nt x , y, z;fscanf (fin, "%d %d %d", s x , &y, &z);

slab(x-1l (lg[x-1] l=y-1;

tare[x-1] [lg(x-1]]-z-1;

19[x-1]++; }

init ():r~z=rezo1va() ;fprintf (fout, "%d\n", rez);

Ec Lo e e (fout); fclose (fin);

return 0; }

int rezolv a ()/*programare dinamica*/:i.nt crt [NKMax), 'pre ('NKMax] ;

.i.nt it j, k;£or (1=0; i<MaxV; ++1) l*prirnul vagon~1

{pre [i]=raman(Ol [il; crt [il=O; }

£or (i=MaxV; i<N; ++i){ pre[i] = -1; crt[i] = 0;

for (k=l; k<NrV: ++k) I~incarc vagon u 1 k*/{ £or (i=k; i«k+l)~MaxV && i<N; ++1)

£or (j=i-MaxV+l; j<=i; ++j){ if (j-l<k-l) continue;

if (pre [j -1) ==--'1) continue;~f (crt[il<pre[j-l]+raman[j] [i]

crt[i]=pr~[j-l1+raman[jl(i);

\,,,ritl~"w.~~

I"i,,""~,,~

t\,"11

\ii,~

278

.}•!~

if (a[i) [j] [k].1g""=0) a[i) [j) [k) .1g=-1;

PROGRAMAREA iN LIMBAJUL C/C + + PENTRU LICEU281SOLUTII SI INDICATII

for (i=n-2; i>=O; i--)

for (j=minS-l; j>=O; j--)

{sum=dee=O;

nrp[il [jj=-l;

for (k=O; k<=min5~j; k++)

{if (j+k+t[ij<minS)

1* pescuim 5*k minute si plecam *1{temp=nrp[i+l] [j+k+t[i]]+sum;}

else { 1* ramanem aiei *1temp=sum; }

~f (temp>=nrp[i) [j])

{nrp[il [jj=temp; 19[i] [jl=k;}

if {(f=F[iJ-dee)<O) {f=O;}

sum+=f; dee+=d[i];

void afisare_rez()

int d , j;

fprintf(fout,"%d\n", nrp[O] [0]);

~nt 19[MAX_LAKEj [MAX_MINS];

/* 19 l a I [j] timpul pe care il petreeem pescuind la lacul i,

pentru a obtine nrp[il [j l pesti */

int eitire_test(void)

{ i.nt i;fscanf (fin, "%d", &n);

if (n==Ol return 0;fscanf{fin,"%d", &min5); minS*=~2;

for (i=O; i<n; i++) fseanf (fin, "%d", F+i);

for (i=O; i<n; i++) fscanf(fin,"%d", d+i);

for (i=O; i<n-l; i++/ fscanf(fin,"%d", t+i);

return 1;

void rez_test(void)

{ int i, j, k , sum, dec, f, temp;

1* determin nrp[n-1j [j), pentru j=minS-l, 0 *1sum=dee=O;

for (j=minS-l; j>=O; j--)

if «f=F[n-l]-dec) < 0) {f=O;}

sum+=f; nrp [n-l] [j 1=sum;

19[n-l] [jj=minS-j;

de c-t-e d [n-1 J ;

I:f,;

i_

r:-(j,"

\;rl

,~

~

~I~~

!!,~ii!(:,¥,

afisare() ;

return 0;

FILE"" fout, *fin;int n, minS, F[MAX LAKE], d[MAX_LAKE). t[MAX_LAKE];

int nrp[MAX_LAKEl [MAX_MINSl;1* nrp[i] [j]=numarul maxim de pesti care pot fi pescuiti

incepand eu lacul i in conditiile in care au trecut deja 5*j

minute *1

't';

r:r,r~

'i,

fprintf(f, "%5\n", s)

fclose (fl ;

int main (void)

tint L, j, k;

citire o.gen_a (l;11=strlen (s1l; l2=strlen (52); 13=strlen (53);

for(i=1; i<=11; i++)for(j=1; j<=12; j++)

for(k=l; k<=13; k++)

rezolva(i, j, k)

~o~d afi5are(vo~d)

{int 19501, i, j, k, x, y, z, nr;

FILE *f= fopen (OUTFILE, "wt");

i=11; j""12; k=13;

19sol=ali) [j] [kl.1g;

nr=O;wh~le «(i!=Ol 1\ (j!=O) II (k!=O))

{nr++;5[1g50l- n rl=a[i] [j] (k] .C;

x=a[il [j] [kJ .x; y=a[i) [j) [k) .y;

z=a [il [j 1 [k] . -z :

i=x; j=y; k=z;

~2. 0 subproblema a problemei date consta in a determina numarul maxim de pesti carepot fi pescuiti din lacurile i, i+l, .. _, n , in conditiile in care au trecut deja 5*j

minute. Solutiile subproblemelor vor fi retinute in matricea n r-p .

#include <stdio_h>

#define InFile "peste.in"

'define outFile "peste.out"

#define MAX~LAKE 25

#define MAX_HOUR 16'define MAX_MINS MAX HOUR*12

t

,~

\i

~

28-

,1-,.;

t

82 PROGRAMAREA iN LIMBAJUL C/C++PENTRU LlCEU 'SOLUTII sr INDICATlI 283

ill, I

Irr-'

i.nt N, x, y;doub1e A[NMAX] [NMAX];

//numaru! de posibilitati, i parateze deschise, j inchise

u

1

r-l, !

'.....1

I :

u

)1....

'-"Ii

,. ,! i...J

~ 1, I~

w

1,

U

r--l! i

I :~

~'--1

i i! :w

i>j-l;i>j-l;i<=j-l;i<=j-l.

i-1>-j ~

i-l<j §ii-1>-j §ii-l<j .§i

dacadacli

-dacadaca

daca i>=j+l;daca i<j+1.

,. A[i] [0]=1, \ii"e{a.. ~._2 •.. ~, "N}-. A[i] [j)=A[i-n [j]+A[i] ('j-ll,

O+A[il [j-1J,

A[i:-l] [j]+O,

0,pentru 'Vi, j E{J:..2 •. ~.~N}~i i>=j .

<b) Pentru -rezolvarea ncestui .caz vom-utihza -0 .alta -matrice, Q, cu y-x.n linii ~iY-'X+l .coloane cu 'semntficatia eli Q [il [j] repreztnra numarul de postbilftati de-procesare .a .L mastni -avand j In stiva.Relatia de. recurenta care permite calculul valorilormatricei Q este :'. 'v'bE{l. 2, .... x}.adicli au intratin stiva 1, 2 •...• x masini ;• Q[x+(i-b)] (il=l. 'v':.e·{b•... , b+(Y-Xl};

• Q[i] tn-or r-r i [j-l]"-Q[i] Lj-t i l , V'ie{X+l•... , Y}, Vje{b+ (Y-X) -I, ... , b}.c) Vom utiliza omatriee A eu N+1 linii §:i N+1 coloane eu semnificajta Ca B [i] [j]

reprezinta-numarul de poaibilitati de a Incheia situatia (N deschise, N Inchise) dela sttuatia In eareavem i 'paranteze deschise §i j paranteze inchise.Evident, A[O] [0] va contine 'rezultatul vfinal, .adica toate parantezele au fosttratate corecr, ceea ce pentru noi Inseamna ca toate mastnile au treeut prin drumulauxiliar. Relatia de recurenra care permite ealeulul valorilor matricei Beste:• 8 [N] (i] =1. v i ej n, 1, ...• N};

8[i] [j]=B(i+l]Ul+B[i] [j+l],

B[i+1] [j)+O.

penrru v'r , j E{N-1. N-2, ...• O} §i i2:=.j.

Avand matrieile A §i B eonstruite in prealabil, vom proceda astfel :- variem momentul in care apare x in stiva (b), §i anume poziria in stiva pe care se

va gasi in momentul.aparijiei ;- pentru fiecare pozttie b :

• eonstruim matricea Q ;

• pentru fiecare masina dintre x o$i Y Inmuljim numarul de poaibifitati deprocesare in stiva eu numarul de posibihtati de finalizare a operatiei :

• adunam rezultatul la 0 suma partiala ;rezultatul obtinut n Inmultim. cu numarul 'de posibilitati de a ajunge in aeeastiisituaiie;eeea ee am obtinut se aduna la 0 suma totala.

Pentru fieeare dintre ealeulele anterioare se ealeuleaza de fiecare data §i nUffiarul deposibilitlip pentru eazul X>Y. Evident. in final. suma celor doua sume trebuie sa fieegala cu numarul total de posibilitati de a procesa eele N ma§ini, adica A [N] [N] .Pentru ealcule se foloseo$te tipul double. Determinarea rezultarolui ell doua zecimaleexacte se face utilizand calcule matematice simple §i conversii de tip.#include <stdio.h>#include <string.h>#define NMAX 101

I

o.e~se {fprintf (-fout, "0");

"fprintf (fout,-"\n") ,.

£or (i=j=O; i<n; i++){~-£ (i) {£printf(fout,·" ")-;}

.:,i;'f (j <min5){xprint-f (fout,-~'-%d", .lg n.] (j l'"*5);

if (i<n) {j+=.l~[i] (j]+t[i];

)

.i.nt main (void)fout=fopen (OutFile, "w") ,.fin=fopen (InFile, '''r'') ;whi~e (c~t~re_test(»

(rez_test(); afisare_rez();}fclose (fout); fclose (fin);-::return 0; }

13. Problema este asemanatoare eu problema determirUirii distantei deeditare .dintredoua cuvinte (numarul minim de operatii necesare -pentru a transforma un cuvant inceUUalt),-dar rezclvarea ..,elasie~"are complexitatea 0 (N*M) . Pentru problema,dataeste necesarun algoritm -de complexitate 0 (K*N) . PentrU .aceasta observam cadin ..toata aceamatrice nu ne sunt necesare decat Kelemente in jurul diagonalei principale.Orice element aflat in afara acestei benzi poate fi considerat infinit, pentru caajungerea in colt necesiti'i. eel putin K incrementi'lri, deci rezultatul final va fi maimare .decat K.

14. Considerlim drumul auxiliar, din mijloc, ca stiva, iar operatiile de intrare/iesire aleunei maainl in stiva sunt desehiderea unei paranteze (atunci cand intra 0 masina insuva), respectiv Inchiderea unei paranteze (cand iese 0 mastna din suva).Presupunem en x < Y, in caz eontrar Ie vern inversa §i vom tine seama de aceasta lasfargit.Cazurile pe care Ie distingem suut urmatoarele :a) determinarea numarului de posibilitiiti de parantezare eorectli pana in momenrol

aparipei ID8.§inii X ;b) determinarea numarului de posibilitap de parantezare corecta intre momentul

aparipei IDa§inii x §i aparitia m8.§inii Y ~

c) determinarea numarului de posibiliti1ti de inchidere coreeta a tuturor parantezelorpornind de la 0 eonfiguratie data, pana in situatia in care au fast deschise §iinchise eorect toate eele N paranteze.

Fieeare dintre aceste cazuri se rezolva prin programare dinamica.a) Vom utiliza 0 matrice A eu N+ 1 linii o$i N+1 coloane en semnifi~ti.aea A[i] [j]

Teprezinti'i. numarul de posibilitliti de a avea i paranteze .,C §i j paranteze ..)".Evident. A[N] [N)· va contine rezultatul final, adica toate parantezele au fost tratateeorect, eeea ce pentru noi inseamna ea toate m8.§inile au trecut prin drumulauxiliar. Relatia de recurenta care permite caleulul valorilor matricei A este :

1i~

'II,I,

nIi'.

(,I.!t

PROGRAMAREA iN LIMBAJUL etC + + PENTRU LleEU

doub~e B[NMAX1 [NMAX];/* numarul de posibilitati din pozitia (i deschise, j inchise)

pana la final (N, N) */doub~e ps;//numarul de posibilitati de a ajunge aiei

doub~e Q [NMAX 1 tNMAX1 ;/* Q(i,j) numarul de posibilitati, s-au procesat i parantez

edin

sirul de intrare si j paranteze sunt inca deschise */

int main ()int L, j, b, sch=O;doub~e tt, total=O, tti, totali=O;freopen("masina.in", "r", stdin);freopen("masina.out"t "Wilt stdout)scanf("%d %d %d", &N, s x , &y);if (x>y) { int auxv x r x=y; y=aux; sch=1;}

//determinarea va1orilor matricii Afor (i=O; i<=N; i++) A[i] (01=1;

for (i=1; i<=N; i++)for (j=l; j<=N; j++)

if (i>=j)A[il [j]=«i-1>=j)? A[i-I] t i i : O)+«i>j-I)? Ali) [j-11 0);

//determinarea valorilor matricii Bfor (i=O; i<=N; i++) B[N] [i]=I;

for (i=N-l; i>=O; i--)for (j=N-l; j>=O; j--)

if (i>=j)B[i] [jl=B[i+l] [jl+«(i>=j+l} ? B[i][j+l]:O);

total=O; //total posibilitati X<Ytotali=O; //total p05ibilitati X>Yfor (b=l; b<=x; b++)//inchidern 1,2, parantez

e

//pentru fieeare b avern

PS=A[x-1] [x-b); lipS - avem x-I' (' si x-b ')

mem5et(Q, 0, sizeof (a» ;Iideterminam valorile matricii Q

for (i=b; i<b+(y-x); i++) /Iinitializare

Q[x+(i-b) 1 [i]=1;for (i=x+l; i<=y; i++)

for (j =b+ (y-x) -1; j.>=b; j--)Q[i] [jl=Q[i-1] [j-1]+Q(il [j+ll;

tt=Q; tti=O; IIX<Y; x>y total partial

for (i=x; 1<y; i++)/Ipentru fiecare element dintre X 51 Y avern

tt+=Q[il [bl*Btil [i-b+1];Ilposibilitati de a procesa 1 Masini si de a incheia

~-

t((Ii?I'~~I'~

re

SOLUTII SI"INDlCATIl

for (i-b; i~b+(y-x); i++)tti+=Q[y-I1 [il*B[Y) [y-i-lJ

tt*=ps;l/se inmulteste cu numarul de posib initiale

tti*=PS;total+=tt; lise aduna 1a totalul general

totali+=tti;

if (sch) total=totali; / /dkca X>Yprintf ("%d. %02d\n", (int) (total *100/A [N] [N]),

(i.nt) (total~'lOOOO/A[N)[N]) %100);

return 0; )

285

Bibliografie

Andonte, Razvan ; Garbacea, Ilie, Algoritmi fundamentali, 0 perspectiva C+ -t-, Editura Llb rj s,

Cluj, 1995.Atanastu, Adrian; Pintea, Rodica, Culegere de probleme Pascal, Editura Petrion, Bucurcstt,

1996. .Cerchez, Emanuela; Serban, Marinel, Informatica. Manual pentru clasa a X-a, Bditura Polirom,

Ia~i, 2000.Cerchez, Emanuela; Serban. Martnel, Informatica. Culegere de probleme pentru liceu, Editura

Polirom, test, 2002.Cerchez, Emanuela; Serban, Marinel, Programarea tn limbajul CIC+ + pentru liceu, Editura

Pollrom, Iasi, 2005.Coricl, C.; Manz, D.; Simulescu, A.; Serban, M .• Limbajul Pascal, Editura Libris, Cluj, 1992.Cormen, Thomas; Leiserson, Charles; Rivest. Ronald, Introduction to Algorithms. The

Massachusetts Institute of Technology, 1990.Prancu, CltlHin, Psihologiaconcursurilor de informatica, Editura L&S Infomat, Bucurestt, 1997.Jamsa, Kris; Klander, Lars, Totul despre C # C+ +, Editura Teora, Bucurestl, 2001.Livovschi, Leon; Georgescu, Horta, Sinteza .# analiza algoritmilor, Editura Stiintifidi lji

Bnciclopedica, Bucuresti, 1986.Lucanu, Dorel, Bazele protectartt programelor §i algoritmilor, Editura Universitatii ..AI.I. Cuza" ,

Iast, 1996.Mitrana, Victor, Provocarea algoritmilor, Editura Agni, Bucuresn, 1994.Niculescu, St.; Cerchez, Em. s.a.• Bacalaureat ~i atestat, Editura L&S Infomat, Bucuresrt,

1999.Sedgewick, Robert, Algorithms in C++, Addison-Wesley Publishing Company, Reading, MA,

1992.S.N.B.E., Subiecte pentru examenul de bacalaureat (2000-2005).

[

!u

["1, ., ,'-'

; iU

....;

,.-....,I ,I •

i....,;

Ii: !LJ

. ,! I,

...J

r I

I 1, .W

• 1

L

.,

!

La Editura POLIROM

au aparut :

vfircea Badut - Calculatorul in trei timpiErnanuela Cerchez, Marinel Serban - Informatica. Manual peruru clasa a X-a

Lurnirtita Einaru, loan Brava - Visual Basic. Primii past ... ~i urmatorii

Emanueta Cerchez, Marinel Serban - PC. Pas cu pasStefan 'Tanasa, Cristian Olaru, Stefan Andrei - JAVA de La 0 La expertBmanuela Cerchez, Marinel Serban _ Informatica. Culegere de probleme peruru liceu

Mihai Cioata - ActiveX. Concepte ~i aplicatiiEmanuela Cerchez, Marinel Serban - Programarea in limbajuL C/C+ + peruru liceu

Mircea Badut _ AutoCAD-uL in trei timpi. Ghidul protectarii projesionale

Emanuela Cerchez, Marinel Serban - programarea in limbajul C/C+ + peruru liceu.Metode si tehnici de programare

in pregatrre :

Traian Anghel _ pragramarea in limbajul PHP. Ghid practic

www.polirom.ro

Redactor: Ml'icUUina IordaeheCoperta: Ionut Brosrianu

Tehnoredactor: Gabriela GheIliu

Bun de tipar: octombrie 2005. Aparut 2005Editura Po!irom, B-dul Carol I nr. 4 • P.O. Box 266

700506, Iasj, Tel. & Fax (0232) 21.41.00 : (0232) 21.41.11(0232)21.74.40 (difuzare) : E-mail: [email protected]

Bucurcllti, B-dul I.e. Bratianu nr. 6, ct. 7, ap. 33,O.P. 37 • P.O. Box 1-728, 030174

Tel. : (021) 313.89.78 : E-mail: [email protected]

Ttparul executat la S.C. LUMINA TIPO s.r.l.su-. Luigi Ga.lvarri nr. 20 bis, sect. 2, Bucure~ti

Tel.!Fax: 211.32.60,212.29.27, E-mail: [email protected]

IJlJ

::::J c= r:=: L _ l [_~::: 1_


Recommended