Sunteți pe pagina 1din 81

Culegere Probleme De

Informatic
CUPRINS:
Introducere. 2
Ce anse am s devin un bun programator? 3
Legile succesului durabil (Ghidul studentului ndrtnic). 6
Probleme de judecat. 8
Probleme de perspicacitate. 8
Probleme cu chibrituri. 9
Probleme de logic i judecat. 10
Probleme de logic i judecat cu tent informatic. 12
Noiuni fundamentale de programare. 15
1. Cele trei etape ale rezolvrii unei probleme cu ajutorul calculatorului
15
2. Cum se stabilete corectitudinea i eficiena soluionrii? 15
3. Noiunile fundamentale ale programrii: algoritm, limbaje de descriere
a algoritmilor, program, limbaje de programare. 16
3.1. Algoritmul. 16
3.2. Descrierea algoritmilor. 17
3.3 Programul. 18
4. Secretul nvrii rapide a programrii. 19
Noiuni primare de programare n Pascal i C. 20
Exemple de probleme rezolvate. 21
Metoda practic de nvare ce garanteaz rezultate imediate. 26
Probleme selecionate Enunuri. 26
Probleme propuse spre rezolvare (probleme de antrenament). 26
Probleme de examen. 28
Probleme dificile. 30
Probleme nesoluionate nc. 32
Probleme insolvabile algoritmic. 35
Noiuni aprofundate de programare. 37
Metode i strategii de proiectare a algoritmilor (alias tehnici de
programare) 37
BackTracking. 39
Greedy. 42
Programarea dinamic. 42
Branch & Bound. 43
Recursivitatea. 44

Probleme rezolvate i exerciii de programare. 49


Probleme elementare. Exerciii de programare. 49
Probleme ce necesit back-tracking. 66
Probleme cu soluie surprinztoare. 70
Elemente de programare a PC urilor. 75
Curioziti i trucuri de programare. 91
Confruntare de opinii: Informatic versus Matematic. 93
Bibliografie, adrese i locaii de interes pe Internet. 95
Introducere

Exist multe culegeri de probleme de informatic ce permit nvarea i


perfecionarea n programare. Prin aceast culegere am ncercat nu doar s
sporim aceast mulime cu nc una ci s oferim un punct de vedere nou,
original i incitant. Originalitatea nu este dat de enunurile problemelor sau
de rezolvrile oferite, ci de ideile i sfaturile cu caracter mobilizator pe care le
oferim, precum i de faptul c am introdus cteva capitole cu coninut mai
puin obinuit ntr-o culegere de probleme de programare.
Ni s-a prut mai important ca n aceste vremuri, caracterizate prin
cuvintele m simt ntr-o permanent criz de timp, s oferim ct mai mult din
experiena noastr direct, att cea de programator ct i cea de profesor de
programare. Dei nu credem c exist metode perfecte de predare sau de
nvare a programrii, totui sperm c prin asimilarea informaiilor originale
oferite eficiena procesului de nvare a programrii n limbajele C i Pascal va
crete. Este important ca informaiile suplimentare s fie asimilate gradat i
numai n limita suportabilitii fiecruia. De aceea, n paginile ce urmeaz vei
gsi i o serie de informaii i sfaturi ce sintetizeaz experiena didactic
acumulat ca profesor de informatic i urmndu-le v asigurm c vei obine
succesul n programare.
n primele capitole a fost pus un accent important pe motivarea iniial a
celor ce doresc s nvee programare. n capitolul Ce anse am s devin un
bun programator sunt chiar prezentate cu sinceritate nzestrrile necesare
unui bun programator.
Tot astfel se explic motivul introducerii unui capitol ce conine probleme
de judecat. Rezolvarea acestora pot fi considerate nu doar ca un excelent
antrenament al minii ci i ca o bun ocazie de a aprinde pasiunea pentru
informatic i de a ntri motivaia programatorilor nceptori.
Asta nu nseamn c aceast culegere nu le este util i celor care au
dobndit deja suficiente cunotine de programare. Am introdus n ea cteva
capitole ce conin informaii mai puin cunoscute. Unul cuprinde o list de
probleme deosebite, unele foarte dificile, altele crora nu li se cunoate nc o
soluie i altele pentru care exist demonstraie riguroas c nu pot fi rezolvate
cu ajutorul calculatorului. Alt capitol cuprinde exemple de programare a PCurilor: lucrul cu tastatura, mouse-ul, accesul direct la memoria ecran, etc. Iar
unele capitole ca Noiuni aprofundate de programare, Probleme cu soluie

surprinztoare sau Curioziti i trucuri de programare le sunt n ntregime


destinate celor care au depit stadiul de nceptor. Probabil c aceste
informaii constituie o provocare destul de substanial chiar i pentru cei
avansai n ale programrii.
n concluzie, scopul acestei culegeri nu este doar de a contribui la
formarea i specializarea programatorilor sau pentru aprofundarea tehnicilor de
programare, ct mai ales de a le oferi o baz, o motivaie i o iniiere celor care
doresc s fac primii pai n domeniul programrii. Iar acelor mptimii ai
programrii care se simt deja plictisii, stui sau plafonai le promitem c
parcurgnd aceast culegere vor aprofunda cunotinele pe care i le-au nsuit
deja i, dac vor avea curajul de a se lua de piept cu unele din problemele
nesoluionate nc, li se va reaprinde cu siguran focul pasiunii pentru
programare.
nceptorilor le urm Bun venit n programare i tuturor Mult succes!
Ce anse am s devin un bun programator?
Aceast ntrebare apare deseori n discuiile sincere dintre profesori i
studenii lor descurajai de ntrzierea apariiei unor rezultate care s certifice
buna lor calitate ca programatori. Vom ncerca n rndurile ce urmeaz s
rspundem ct mai clar la aceast ntrebare oferind, n plus, o perspectiv
prosptat asupra acestui subiect, prin luarea n considerare a unei serii de
factori mai puin utilizai n procesul didactic contemporan.
Mai nti s vedem ce s-ar putea nelege prin sigtagma bun
programator, insisitnd n continuare doar pe aprofundarea adjectivului bun,
fr a mai defini sau detalia ce se nelege printr-un programator. Vom cita
cuvintele recente ale lui Timoty Budd (profesor la Oregon State University) care
d urmtoarea definiie: Un bun programator trebuie s fie nzestrat cu
tehnic, experien, capacitate de abstractizare, logic, inteligen, creativitate
i talent. ntru-totul de acord cu aceast definiie vom trece n cele ce urmeaz
la explicitarea fiecrei caliti.
nainte vom deduce urmtoarea consecin imediat deosebit de
important ce rezult din definiia de mai sus: cele apte caliti trebuie s fie
prezente toate pentru a se obine calificativul de bun programator. Deci, prin
lipsa sau prin prezena atrofiat a uneia, sau a mai multe din ingredientele
reetei de mai sus, acest calificativ nu mai poate fi atins.
1. Tehnica este desigur o calitate ce poate fi i este, dobndit doar prin
aplicarea asidu (conform proverbului: exerciiul l face pe maestru) n
activitatea concret de programare a tehnicilor de programare nvate i
asimilate de ctre programator n timpul formrii sale profesionale. Nu este
exclus aici posibilitatea obinerii tehnicii de programare nafara unui cadru
specializat (ntr-o facultate de profil), ci chiar exist posibilitatea obinerii ei
prin studiu individual i formaie proprie (autodidact).
2. Experiena este perechea geamn a calitii de mai nainte, fr ns
a se exclude una pe cealalt. Nu vom mai repeta cum i n ce condiii poate fi
ea obinut ci vom deduce urmtoarea consecina imediat: nici un
programator nceptor nu poate fi numit bun programator ntruct el nu a avut
cnd (adic timpul necesar) s dobndeasc ambele caliti. Este binecunoscut

faptul c o rubric important ce se cere completat la angajare sau la


schimbarea locului de munc este experiena de programare n ani. Se
consider n general c experiena apare abia dup minimum doi ani de
programare. Acest fapt nu trebuie privit ca o descurajare pentru cei mai tineri
programatori ci mai degrab ca pe un motiv de ambiionare i ca o invitaie la
rapid autoperfecionare.
3. Abstractizarea este o trstur a intelectului uman i constituie un
dat al oricrui om normal, dar din pcate (!) este o nsuire prea puin
dezvoltat i prea puin folosit de oamenii obinuii. Ea const din capacitatea
de a extrage din context, de a vedea dincolo de suprafaa imediat i de a putea
sesiza structura scheletul ce susine ntreaga reea de detalii ale unei
probleme generale. Pentru a fi un bun programator acest calitate trebuie s fie
net amplificat fa de normal ntruct st la baza oricrui proces de analiz
i modelare a problemelor, ct i la baza procesului de proiectare a soluiilor
generale. Absena sau mai exact atrofierea acestei capaciti se constat practic
la studeni prin incapacitatea de a nelege sau de a asimila explicaii,
demonstraii sau modele abstracte (simplu spus, o acut i permanent lips
de chef atunci cnd sunt atinse anumite subiecte ce nu mai au contact direct
cu realitatea concret, imediat adic subiecte abstracte). Metoda pentru a
recpta sau a amplifica aceast capacitate este de a face ct mai des uz de ea,
adic de a o exersa mereu (conform zicalei funcia creeaz organul) ntr-un
domeniu particular, susinut de o motivaie personal puternic. Altfel spus,
capacitatea noastr de abstractizare se va amplifica dac vom ncerca gsirea
de soluii la problemele dintr-unul din domeniile noastre preferate, pentru c
rezolvarea acestora va fi automotivat, fcut cu chef i va prezenta o doz
sporit de atractivitate.
4. Logica este o alt calitate intrinsec a oricrui intelect sntos. Ea
este absolut necesar att pentru a putea folosi mecanismele mentale de
deducie i inducie logic, ct i pentru a putea nelege uor, dar n acelai
timp corect, cursul firul rou al unei demonstraii sau al unui raionament
ntins pe mai multe pagini. Asemenea tuturor calitilor intrinseci existente n
stare potenial, antrenarea i amplificarea acesteia se face prin exerciiu
repetat, prin folosirea ei n mod curent. Din pcate, doar prin rezolvarea de
integrame nu se ajunge la amplificarea logicii.
5. Inteligena este una din cele mai de pre caliti intrinseci ale
intelectului uman. n cteva cuvinte, fr a avea pretenia de a da prin acestea
o definiie, prin inteligen nelegem capacitatea de a face (de a stabili)
conexiuni sau legturi noi i folositoare (din latinescul inter-legere) ntre idei,
cunotine sau informaii aparent fr legtur. Fa de logic, pe care o
considerm ca fiind o calitate bazal, inteligena este o calitate ce se ntinde pe
verticala intelectului i are n plus trstura de a fi mult mai dinamic i mai
mobil (chiar fulgertor de rapid) n aciune. Pentru cultivarea, amplificarea i
cizelarea acestei caliti este nevoie de punerea ei la lucru ct mai des i pe
durate tot mai mari de timp. Insatisfacia obinerii unor rezultate rapide sau
chiar imediate este un obstacol ce poate fi depit relativ uor prin antrenarea
inteligenei pe un teren cunoscut i accesibil, adic n domeniul preferat de

interes. n acest fel exist sigurana de a fi susinut de atracia sporit pentru


acel domeniu particular ceea ce va conduce prin efort perseverent (dar susinut
de aceast dat cu pasiune!) la apariia rezultatelor ateptate i, implicit, a
satisfaciei.
6. Creativitatea este o calitate intrinsec nu numai intelectului uman ci
nsi vieii n general. Ea const, n ultim instan, n capacitatea de a face
(de a produce) ceva cu adevrat nou i original. De aceea am putea afirma c
toate organismele vii, prin capacitatea lor de a se opune entropiei, creeaz
mereu ordine din dezordine aducnd n acest fel ceva nou, neateptat. Ceea ce
se ateapt ns de la un bun programator nu este doar acest tip de creativitate
(gen: adaptare incontient i instinctiv) ci o creativitate contient,
responsabil, reflectat n adaptarea soluiilor existente sau chiar inventarea
altora noi. n acest sens trebuie s menionm c exist o legtur strns,
dovedit i verificat n practic (chiar dac pare oarecum inexplicabil la prima
vedere), ntre creativitate inteligen fluid curiozitate sublimarea
impulsurilor erotice umor i poft de via. Cultivarea i amplificarea
controlat a oricrora dintre aceste patru trsturi va conduce n mod automat
la amplificarea i dinamizarea creativitii intelectuale.
7. Talentul este singura calitate ce nu poate fi cultivat i amplificat.
n accepiunea sa obinuit, prin talent se nelege o sum de nzestrri native
sau o predispoziie personal pentru un anumit domeniu. Existena talentului
este perceput de cel n cauz ca uurin abilitate dexteritate de a nva,
asimila i aplica toate cunotinele domeniului respectiv, abilitate ce este
simit de cel talentat ca un fel de ceva n plus n comparaie cu capacitile
celor din jur. Din pcate, n accepiunea comun se crede c talentul este
calitatea suficient care permite oricui atingerea cu siguran a calificativului
bun programator, concepie este infirmat de orice programator cu experien.
Asta nu nseamn c lipsa talentului n programare este permis pentru
atingerea acestui nivel, ns efortul, tenacitatea i rbdarea existente n
cantiti mult sporite ntr-o asemenea situaie de ne-nzestrare cu talent vor
permite o apropiere sigur de acest calificativ. Din pcate, lipsa talentului va
aprea la nceput sub forma unei insatisfacii interioare i ca o impresie acut
c lipsesc rezultatele. Reamintim c nsi cuvntul facultate are la origine
sensul de capacitate, potenialitate, nzestrare. Deci, normal ar fi ca alegerea
unui student pentru frecventarea cursurilor unei Faculti s fi fost fcut
innd cont de aptitudinile i abilitile celui n cauz, descoperite n prelabil,
adic s se dovedeasc talentat pentru domeniul ales. Acest lucru este cu att
mai important n cazul optrii pentru nvarea programrii, cunoscut fiind ca
o specializare complex i solicitant.
Relund n sintez ideile prezentate, putem spune c:
Pentru a fi un bun programator trebuie s fie prezente urmtorele apte
caliti ntr-o form activ, dinamic: tehnic, experien, capacitate de
abstractizare, logic, inteligen, creativitate i talent.

Dintre toate cele apte caliti necesare programrii de nalt calitate,


numai una talentul nu este inerent unui intelect sntos. De altfel,
prezena talentului nu este absolut necesar pentru a deveni programator, dar
n timp ce absena lui ngreuneaz apropierea de calificativul bun programator,
prezena lui i amplificarea celorlalte caliti este o garanie a succesului, ce va
fi cu siguran obinut, ns nu fr efort, rbdare i perseveren!
Toate celelalte ase caliti excluznd talentul, prezente fiind ntr-o form
potenial, trebuiesc doar cultivate i amplificate. Am prezentat mai sus n
detaliu modul de amplificare a fiecreia.
Cheia secret ce conduce cu siguran la declanarea procesului de
dinamizare i amplificare a fiecreia din cele ase caliti inerente este de a
avea mereu o motivaie puternic (de a nva cu chef sau cu tragere de
inim!). Acest fapt este posibil dac se ine cont de necesitatea adaptrii
efortului la domeniul preferat al celui n cauz. La modul concret, este necesar
ca toate aplicaiile, problemele, exerciiile, ntrebrile, curiozitile, inovaiile,
descoperirile, spturile, etc., s fie fcute sau s fie alese, la nceput, din
domeniul preferat (hobby-ul), chiar dac acesta nu are la prima vedere legtur
cu programarea. Scopul ce se atinge cu siguran n acest mod n aceast
prim faz este acela de a pune la lucru inteligena, creativitatea, logica, etc.,
ceea ce va conduce cu siguran la trezirea i amplificarea rapid a acestor
caliti. Acest fapt va permite apoi trecerea la o a doua faz n care, pe baza
acumulrilor calitative obinute, se poate trece la programarea propriu-zise
narmat cu fore proaspete.
ncheiem rspunznd ntr-o singur fraz ntrebrii din titlu Ce anse am
s devin un bun programator?: dac m simt nzestrat cu talent pentru
programare (adic nu m simt inconfortabil la acest subiect) atunci,
mobilizndu-mi voina (motivaia) i amplificndu-mi capacitatea de
abstractizare, logica, inteligena i creativitatea (ce exist n mine ntr-o form
potenial), prin practic de programare voi acumula n timp tehnica i
experiena necesare pentru a deveni cu siguran un bun programator, ns nu
fr efort, rbdare i perseveren.
Legile succesului durabil (Ghidul studentului ndrtnic)
Cunoate-i Regulile de aur ale studentului mecher? Dac nu, le putei fi
afla la o bere, de la mecher la mecher. Noi le vom numi Anti-legile
succesului durabil i vi le prezentm n continuare doar pentru a putea
observa cum fiecare din aceste legi este o rsturnare (pervertire) a
adevratelor legi ale succesului.
1. Cel mai important este s termini facultatea i s te vezi cu diploma n
mn. Ce conteaz cum? Cine mai tie dup-aia.?
2. De ce s-nvei.? i aa majoritatea materiilor sunt tembele i n-o s-i
foloseasc niciodat n via. Materiile tembele trebuie s fie predate numai
pentru ca s ctige i profii o pine.
3. Pune-te bine cu profesorii pn treci examenul. Stai cu ei la o igar n
pauz. Las-l pe ei s vorbeasc. Tu pref-te c eti interesat.

4. Ai trecut examenul? Da? AtuncI. Restul nu mai conteaz.


5. Nu conteaz dac ai nvat, ce tii sau ct tii. Important este s ai
baft la examen, s ai mn bun sau s mergi bine pregtit. La puini profi
nu se poate copia!
6. Sunt examene la care, se tie bine, toat lumea copiaz. Trebuie s fi
nebun s-nvei la ele!
7. Notele bune sunt numai pentru piloi i tocilari.
Acestor studeni le sunt ns complet necunoscute Legile succesului
durabil. Ele ar putea fi intuite doar de acei puini care s-au format i s-au
educat n spiritul ideilor ce urmeaz s le explicm n continuare. Aceste legi ne
nva c bazele succesului durabil se pun nc din timpul colii i mai ales din
timpul facultii. i ne mai nva c succesul astfel start-at este destinat s
dureze o via ntreag.
1. Cel mai important n facultate este s-i faci o carte de vizit, nu-l
suficient s vnezi doar diploma. Dac vei fi apreciat i vei ajunge s fii
considerat capabil sau chiar bun de cadrele didactice cu greutate, vei ajunge
s fi cunoscut i bine cotat dup absolvire i-i vei gsi un loc bun de munc.
ntotdeauna a fost i va fi nevoie de oameni capabili pe piaa muncii, nu de
liceniai piloi, tolomaci sau papagali.
2. Cel mai important lucru n coal este c nvei cum s nvei. Cnd
vrei s te recreezi rezolvnd integrame nu prea conteaz ce din ce domeniu i leai ales. Important pentru tine nu este cum, ci faptul c te destinzi. Tot astfel, n
facultate important este nu neaprat ce nvei, ci c nvei! Multe cunotine le
vei uita n primii ani dup absolvire, mai ales cele pe care i le-ai nsuit ntr-o
stare de sforare i ncrncenare, fr plcere. Cel mai important este s nvei
de plcere cci numai aa vei nva cum s nvei. Iar aceasta nu se mai poate
uita! i nu vei mai uita nicicnd c ai resursele i puterea s treci prin fore
proprii examenele cele mai grele.
3. Succesul n via se bazeaz pe relaii umane echilibrate. (Acest fapt
era cunoscut i pe vremea regimului partidului comunist roman P. C. R. ns
datorit imoralitii generalizate a societii el a fost aplicat pe invers: astfel, a
apela de P. C. R. nsemna atunci s apelezi la Pile, Cunotine i Relaii.) Deci,
cel mai important lucru n coal este s nvei arta de a stabilii relaii umane
prietenoase i de ncredere reciproc. Ceea ce va conta cel mai mult, peste ani,
este c ai stabilit n timpul colii multe prietenii durabile i de ncredere care te
vor mbogii astfel pentru toat viaa. n plus, nu uita: i profesorii sunt
oameni. Au i ei nevoie de prieteni.
4. Colegii sunt martori i devin cei mai exigeni judectori ai trsturilor
tale de caracter. Examenul, indiferent de materie sau disciplin, cu emoiile i
peripeiile lui este n sine o lecie complet. Nu conteaz att dac l-ai luat sau
dac l-ai picat, ci conteaz cum! Conteaz ce fel de om eti n astfel de situaii,
cnd tocmai i construieti cartea de vizit sau blazonul. Nu uita c nu te afli
doar n faa profesorilor ci eti tot timpul nconjurat de colegii care te judec,
chiar dac i-e nu-i spun. Pentru c aa cum te compori acum n examen, aa
te vei comporta toat viaa.

5. Examenele grele sunt cele care i pot forma un caracter puternic. Ceea
ce este important n examen, ca i n situaiile de via, este ncrederea n
reuit i stpnirea de sine chiar dac n-ai nvat toat materia. Dac ai
nvat destul ca s te simi stpn pe tine atunci ai trecut examenul! Chiar
acesta a fost rostul lui, ce dac i-a dat not mic! Crezi c, dup ce vei trece
examenul, peste zece ani i vei mai aminti cu ce not?
6. Cei cu un caracter slab i vicios se vor da la un moment dat n vileag.
Cei care copiaz nu-i dau seama c ei i infecteaz caracterul. i nici ct de
grave sunt consecinele infectrii cu microbul ctigului imediat obinut prin
furt. Oare se vor mai putea debarasa vreodat de acest viciu tentant? Dar de
cunoscutele efecte secundare: sentimentul de nesiguran fr o fiuic n
buzunar, atracia irezistibil pentru aruncarea privirii mprejur, prerea de
ru c Ce prost sunt, puteam s copiez tot!, etc. Cnd vor mai scpa? Cei care
se obinuiesc s copieze, att ct vor tri, vor fi jumtate om-jumtate fiuic.
Ca n vechile bancuri cu miliieni.
7. Oricine este acum apt s nvee i s-i nsueasc pentru ntreaga sa
via Legea efortului. Pe profesori i impresioneaz cel mai tare efortul depus il vor aprecia cu note maxime. Ei supra-noteaz pe cei care vor, sunt bine
intenionai, dar nc nu pot. Profesorii cunosc adevrul exprimat n Legea
omului de geniu (legea lui Einstein): Geniul este compus 99% din transpiraie
i 1% din inspiraie. Profesorii adevrai se strduiesc s noteze mai ales
calitatea uman i profesional a studentului. Reinei: dac studentul a fost
prietenos, activ i deschis n timpul anului colar i a depus un efort constant
pentru a se perfeciona, fapt ce nu a scpat ochiului atent al profesorului,
examenul devine n final pentru el o formalitate.
Multe vorbe i preri pot fi auzite pe aceast tem n familie, n pauze la
coal sau la barul preferat. Ct sunt ele de adevrate? S-ar putea da oare o
definiie precis pentru succesul n via?
Noi nu cunoatem o astfel de definiie, tim doar c exist o multitudine
de preri i opinii, unele profund contradictorii. Este ns de bun sim s
credem c se poate numi de succes acea via care este plin de satisfacii,
bucurii i visuri mplinite. Acea via care s-i merite din plin exclamaia:
Asta da, via!?
Regula de aur a succesului durabil este: nva s-i construieti singur
viaa. i apoi, dac ai nvat, apuc-te fr ntrziere s-i faci viaa fericit.
Studenia, prin entuziasmul, optimismul i idealismul ei, este o perioad
optim pentru a nva cum s-i faci o via de succes! Atenie, muli i-au dat
seama prea trziu c studenia a fost pentru ei n multe privine ultimul tren.
Probleme de judecat.
Oferim n cele ce urmeaz o selecie de probleme ce nu necesit
cunotine de matematic avansate (doar nivelul gimnazial) dar care pun la
ncercare capacitatea de judecat, inspiraia i creativitatea gndirii. Rezolvarea
acestor probleme constituie un bun antrenament pentru creterea capacitii
de gndire creativ precum i a fluiditii gndirii. Credem c nu degeaba
aceste dou trsturi sunt considerate cele mai importante semne ale tinereii
minii.

Problemele, selectate din multiple surse, nu au putut fi grupate n


ordinea dificultii mai ales datorit diversitii i varietii lor. Ele au fost doar
separate n cteva categorii a cror nume vrea s sugereze un anumit mod de
gndire pe care l-am folosit i noi n rezolvarea lor. Cele cu un grad mai mare
de dificultate au fost marcate cu un semn (sau mai multe semne) de exclamare.
Criteriul principal pe baza cruia s-a fcut aceast selecie a fost
urmtorul: fiecare problem cere n rezolvarea ei un minimum de inventivitate
i creativitate. Majoritatea problemelor te pun fa n fa cu imposibilul, aa
c rezolvarea fiecrei probleme necesit depirea unor limitri ale gndirii
plus un minimum de originalitate n gndire. Tocmai de aceea, pentru
rezolvarea lor este nevoie de efort, putere de concentrare i perseveren. Zis
ntr-un singur cuvnt: este necesar i un strop de pasiune.
Considerm c eforturile consecvente ale celor care vor rezolva aceste
probleme vor fi din plin rspltite prin plcerea minii biruitoare i prin
amplificarea calitilor urmtoare: capacitate sporit de efort intelectual, putere
de concentrare mrit i prospeime n gndire.
V dorim mult succes!
Probleme de perspicacitate
1. tiind c o sticl cu dop cost 1500 lei i c o sticl fr dop cost
1000 lei, ct cost un dop?
2. tiind c un ou cost 1000 lei plus o jumtate de ou, ct cost un ou?
3.
Ce numr lipsete alturi de ultima figur:
4. Lui Popescu nici prin gnd nu-l trecea s foloseasc toate mijloacele pe
care le avea la ndemn ca s lupte mpotriva adversarilor tendinei contra
neintroducerii micrii anti-fumat. Care este poziia lui Popescu: este pentru
sau contra fumatului?
5. mprirea imposibil. S se mpart numrul 12 n dou pri astfel
nct fiecare parte s fie 7.
6. 9 puncte. S se secioneze toate cele 9 mici discuri cu o linie frnt
nentrerupt (fr a ridica creionul de pe hrtie) compus din 4 segmente. (!)
Dar din trei segmente, este posibil?
7. Trei cutii. n trei cutii identice sunt nchise trei perechi de fructe: fie o
pereche de mere, fie o pereche de pere, fie o pereche format dintr-un mr i o
par. Pe cele trei cutii sunt lipite trei etichete: dou mere, dou pere i,
respectiv, un mr i o par. tiind c niciuna din etichete nu corespunde cu
coninutul cuitei nchise pe care se afl, s se afle care este numrul minim de
extrageri a cte un fruct pentru a se stabili coninutul fiecrei cutii.
8. n ce direcie merge autobuzul din desenul alturat?
9. (!) ntreruptoarele. Pe peretele alturat uei ncuiate de la intrarea
unei ncperi, se afl trei ntreruptoare ce corespund cu cele trei becuri de pe
plafonul ncperii n care nu putem intra. Acionnd oricare din ntreruptoare,
dunga de lumin care apare pe sub u ne asigur c niciunul din cele trei
becuri nu este ars. Cum putem afla, fr a ptrunde n ncpere, care
ntreruptor corespunde cu care bec?

10. (!) Cine mut ultimul ctig. Doi juctori dispun de o mas de joc de
form circular sau ptrat i de un numr mare de monezi identice. Ei mut
plasnd pe masa de joc n spaiul neocupat, fr suprapunere, cte o moned
alternativ pn cnd unul dintre juctori, care pierde n acest caz, nu mai
poate plasa nicieri o moned. S se arate c primul juctor are o strategie
sigur de ctig.
11. (!) Iepurele i robotul-vntor. ntr-o incint nchis (un gen de aren)
se afl un iepura i un robot-vntor nzestrat cu cleti, mijloc de deplasare,
calculator de proces i ochi electronici. tiind c viteza de deplasare a
robotului-vntor este constant i de zeci de ori mai mare dect a iepuraului,
ce anse mai are iepuraul de a scpa?
12. Cntarul defect. Avnd la dispoziie un cntar gradat defect care
greete constant cu aceeai valoare (cantitate necunoscut de grame), putem
s cntrim ceva determinndu-l corect greutatea?
13. Jocul dubleilor (inventat de Carroll Lewis). tiind c trecerea de la
un cuvnt cu sens la altul cu sens este permis doar prin modificarea unei
singure litere odat (de exemplu: UNU UNI ANI ARI GRI GOI DOI) se
cere: Dovedii c IARBA este VERDE i c MAIMUA a condus la OMENIRE,
facei din UNU DOI, schimbai ROZ-ul n ALB, punei ROUGE pe OBRAZ i
facei s fie VARA FRIG.
14. mpturirea celor 8 ptrate. mpturii iniial n opt o foaie
dreptunghiular dup care desfacei-o i nsemnai fiecare din cele opt zone
dreptunghiulare obinute (marcate de pliurile de ndoire) cu o cifr de la 1 la 8.
Putei mpturi foaia astfel obinut reducnd-o de opt ori (la un singur
dreptunghi sau ptrat) astfel nct trecnd cu un ac prin cele opt pliuri
suprapuse acesta s le perforeze exact n ordinea 1, 2, 3 8? ncercai aceste
dou configuraii:
15. Problem pentru cei puternici. ncercai s mpturii de 8 ori, pur i
simplu, o coal de hrtie (de fiecare dat linia de ndoire este n cruce peste
cea dinainte). Este posibil? (!) Determinai ce dimensiuni ar trebui s aib foaia
la nceput pentru a putea fi mpturit de 8 ori.
16. Este posibil ca un cal s treac prin toate cele 64 de ptrele ale
unei table de ah, ncepnd dintr-un col i terminnd n colul diagonal opus?
17. ntr-un atelier exist 10 ldie ce conin fiecare piese cu greutatea de
100 grame, cu excepia uneia din ldie ce conine piese avnd grutatea de 90
grame. Putei preciza care este ldia cu pricina, folosind un cntar doar pentru
o singur dat?
Probleme cu chibrituri
1. (!) Eliminnd un singur b de chibrit ceea ce rmne n faa ochilor
este un elipsoid!
2. (!) 9 bee. S se aeze 9 bee de chibrit astfel nct ele s se ntlnesc
la vrf tot cte trei n ase vrfuri distincte.
3. De la 4 la 3. n figura ce conine 4 ptrate, mutnd 4 bee s se obin
o figur ce conine doar 3 ptrate.
4. 6 = 2? Mutnd doar un singur b de chibrit s se restabileasc
egalitatea:

5. Problema ariilor ntregi. Putei aeza 12 chibrituri astfel nct ele s


formeze contururile unor poligoane ce au aria ntreag egal cu 5, (!) 4, 3, 2, (!)
1? Se subnelege c un chibrit poate fi asimilat cu un segment de lungime 1 i
c nu exist nici o dificultate de a forma din ochi unghiuri drepte.
Probleme de logic i judecat
1. Substituirea literelor. Subtituii literele cu cifre astfel nct urmtoarele
adunri s fie corecte: GERALD + DONALD = ROBERT; FORTY + TEN + TEN =
SIXTY; BALON + OVAL = RUGBY.
2. Test de angajare la Microsoft. Patru excursioniti ajung pe malul unui
ru pe care doresc s-l traverseze. ntruct s-a noptat i ei dispun doar de o
singur lantern, ei pot s treac rul cel mult cte doi laolalt. tiind c,
datorit diferenelor de vrst i datorit oboselii, ei ar avea individual nevoie
pentru a traversa rul de 1, 2, 8 i 10 minute, se cere s se decid dac este
posibil traversarea rului n aceste conditii n doar 17 minute?
3. (!) Imposibil. S se taie toate cele 16 segmente ale figurii urmtoare cu
o singur linie curb continu i care nu se intersecteaz cu ea nsi.
4. (!) Problema ochilor albatri. Suntem martorii urmtorului dialog
ntre dou persoane X i Y. < X: Eu am trei copii. Produsul vrstei lor este 36
iar suma vrstei lor este egal cu numrul de etaje al blocului din vecini de
mine. l tii, nu-l aa? Y: Desigur. Dar numai din ct mi-ai spsus nu pot s
deduc care este vrsta copiilor ti. X: Bine, atunci afl c cel mare are ochi
albatrii. > Putei afla care este vrsta celor trei copii?
5. Problema clugrului budhist. ntr-o diminea, exact la rsritul
soarelui, un clugr budhist pornete de la templul de la baza muntelui pentru
a ajunge la templul din vrful muntelui exact la apusul soarelui, unde el se
roag toat noaptea. A doua zi el pornete din vrf pe aceei crare, tot la
rsritul soarelui, pentru a ajunge la templul de la baza muntelui exact la
apusul soarelui. S se arate c a existat un loc pe traseu n care clugrul s-a
aflat n ambele zile exact la aceai or.
6. Vinul n ap i apa n vin. Dintr-o sticl ce conine un litru de ap este
luat un pahar (un decilitru) ce este turnat pest un litru de vin. Vinul cu apa se
amestec bine dup care se ia cu acelai pahar o cantitate egal de vin cu ap
ce se toarn napoi peste apa din sticl. Avem acum mai mult ap n vin dect
vin n ap, sau invers?
7. (!) Cuiele n echilibru. Avem la dispoziie 7 cuie normale, cu capul
obinuit. nfigem unul vertical n podea (sau ntr-o plac de lemn). Se cere s se
aeze cele 6 cuie rmase n echilibru stabil pe capul cuiului vertical, fr ca
niciunul din cele ase cuie s ating podeaua.
8. (!) igrile tangente. Este posibil s aezm pe mas ase igri astfel
nct fiecare s se ating cu fiecare (oricare dou s fie tangente)? (!) Dar apte
igri?
9. (!) Problema celor 12 nelepi (n variant modern). Managerul unei
mari companii dorete s pun la ncercare inteligena i puterea de judecat a
celor 12 membrii ai consiliului su de conducere. Lund 12 cri de joc, unele
de pic i altele de caro, el le aeaz cte una pe fruntea fiecrui consilier astfel
nct fiecare s poat vedea crile de pe frunile celorlali dar nu i pe a sa.

Managerul le cere celor care consider c au pe frunte o carte de caro


(diamond) s fac un pas n fa, altfel ei nu vor mai putea face parte din
consiliu. Dup ce i repet cererea de apte ori, timp n care niciunul din cei
12 consilieri nu face nici o micare (ci doar se privesc unii pe alii), toi
consilierii care au ntr-adevr pe frunte o carte de caro ies deodat n fa.
Putei deduce ci au ieit i cum i-au dat ei seama ce carte este aezat pe
fruntea lor?
10. Pianjenul i musca. Pe peretele lateral al unei hale cu dimensiunile
de 40 x 12 x12 metri, pe linia median a peretelui lateral i exact la 1 metru de
tavan, se afl un pianjen. Pe peretele lateral opus, tot pe linia median i exact
la 1 metru de podea, se afl o musc amorit. Care este distana cea mai
scurt pe care pianjenul o are de parcurs de-a lungul pereilor pentru a se
nfrupta din musc?
11. Rifi i Ruf. Cei doi iubii Rifi i Ruf, din nordica ar Ufu-Rufu,
locuiesc n sate diferite aflate la distana de 20 km unul de altul. n fiecare
diminea ei pornesc exact deodat (la rsrit) unul spre cellalt spre a se
ntlni i a se sruta confrom obiceiului nordic: nas n nas. ntr-o diminea o
musc rtcit pornete exact la rsritul soarelui de pe nasul lui Rifi direct
spre nasul lui Ruf, care o alung trimind-o din nou spre nasul lui Rifi,
.a.m.d., pn cnd ea sfrete tragic n momentul srutului celor doi. tiind
c Rifi se deplaseaz cu 4 km/or, Ruf cu 6 km/or iar musca zboar cu 10
km/or, se cere s se afle ce distan a parcurs musca n zbor de la rsrit i
pn n momentul tragicului ei sfrit.
12. O anti-problem de ah. n urmtoarea configuraie a pieselor pe o
tabl de ah se cere s nu dai mat dintr-o mutare! (Albul atac de jos n sus.
Legenda: P-pion, N-nebun, R-rege, T-turn, C-cal. Alturat fiecrei piese este
scris culoarea sa, alb-a sau negru-n.)
NNa
RRa
TTa
TTn
NNa
TTa
NNn
PPn
PPn
PPa
RRn
PPa
PPn
PPa
PPn
PPa
PPa
PPa
CCa

CCa
13. Bronx contra Brooklyn. Un tnr, ce locuiete n Manhattan n
imediata apropiere a unei staii de metrou, are dou prietene, una n Brooklyn
i cealalt n Bronx. Pentru a o vizita pe cea din Brooklyn el ia metroul ce merge
spre partea de jos a oraului, n timp ce, pentru a o vizita pe cea din Bronx, el
ia din acelai loc metroul care merge n direcie opus. Metrourile spre
Brooklyn i spre Bronx intr n staie cu aceei frecven: din 10 n 10 minute
fiecare. Dar, dei el coboar n staia de metrou n fiecare smbt la
ntmplare i ia primul metrou care vine (nedorind s favorizeze pe niciuna
din prietenele sale), el a constatat c, n medie, el merge n Brooklyn de 9 ori
din 10. Putei gsi o explicaie logic a fenomenul?
14. (!) Problema celor 12 bile. n faa noastr se afl 12 bile identice ca
form, vopsite la fel, dar una este cu siguran fals, ea fiind fie mai grea, fie
mai uoar, fiind fcut dintr-un alt material. Avem la dispoziie o balan i se
cere s determinm doar prin 3 cntriri care din cele 12 bile este fals
preciznd i cum este ea: mai grea sau mai uoar. (!) Mai mult, putei
determina care este numrul maxim de bile din care prin 4 cntriri cu balana
se poate afla exact bila fals i cum este ea?
15. (!) Problema celor 2 perechi de mnui. Aflat ntr-o situaie ce implic
intervenia de urgen, un medic chirurg constat c are la dispoziie doar 2
perechi de mnui sterile dei el trebuie s intervin rapid i s opereze
succesiv 3 bolnavi. Este posibil ca cele trei operaii de urgen s se desfoare
n condiii de protecie normale cu numai cele 2 perechi de mnui? (Sngele
fiecruia din cei 3 pacieni, precum i mna doctorului nu trebuie s conduc
la un contact infecios.)
16. (!) Problema frnghiei prea scurte. O persoan ce are asupra ei doar
un briceag i o frnghie lung de 30 metri se afl pe marginea unei stnci,
privind n jos la peretele vertical de 40 metri aflat sub ea. Frnghia poate fi
legat doar n vrf sau la jumtatea peretelui (la o nlime de 20 metri de sol)
unde se afl o mic platform de sprijin. Cum este posibil ca persoana aflat n
aceast situaie s ajung teafr jos cobornd numai pe frnghie, fr a fi
nevoit s sar deloc punndu-se astfel n pericol?
17. Problema lumnrilor neomogene. Avem la dispoziie chibrite i dou
lumnri care pot arde exact 60 minute fiecare ns, ele fiind neomogene, nu
vor arde cu o vitez constant. Cum putem msura precis o durat de 45
minute?
18. (!) O jumtate de litru. Avem n faa noastr un vas cilindric cu
capacitatea de 1 litru, plin ochi cu ap. Se cere s msurm cu ajutorul lui
litru de ap, fr a ne ajuta de nimic altceva dect de minile noastre.
19. (!) S vezi i s nu crezi. Privii urmtoarele dou figuri: prin
reaezarea decupajelor interioare ale primeia se obine din nou aceeai figur
dar avnd un ptrel lips! Cum explicai minunea?
Probleme de logic i judecat cu tent informatic
1. (!) Decriptarea scrierii ncifrate. Se dau urmtoarele numere mpreun
cu denumirile lor cifrate: nabivogedu nagevogedu nabivobinaduvogedu
nabivonagevogedunaduvogedu nabivogenagevogenaduvogedu

nabivonabivobinagevogedunagevogenaduvogedu nabivodunanabivobiduvogedu
nabivonabivonabivogedunagevogenaduvogedunanabivobiduvogedu
nabivonagevogedunagevogenanabivobiduvogedu
nabivonaduvogedunagevodunanabivobiduvogedu
nabivonabivobinagevogenaduvogedunagevodunanabivobiduvogedu
Care este regula de ncifrare? Ce numere reprezint urmtoarele coduri
cifrate: nagevonagevogedunanabivobiduvogedu;
nagevonaduvogedunanabivobiduvogedu; naduvogenanabivobiduvogedu;
nanabivogeduvogedu;
nabivonabivonaduvogedunagevonagevogedunanabivobiduvogedu;
nanagevobiduvogedu?
ncifrai numerele 256 i 1024 prin acest metod.
2. (!) Altfel de codificare binar a numerelor. Descoperii metoda de
codificare binar a numerelor folosit n continuare:
Putei spune ce numere sunt codificate prin 100, 101, 1000, 1111, 10000
i 11111? Putei codifica numerele 70, 80, 90, 100, 120, 150 i 1000?
3. (!) Problema dialogului perplex. Exist dou numere m i n din
intervalul [2.99] i dou persoane P i S astfel nct persoana P tie produsul
lor, iar S tie suma lor. tiind c ntre P i S a avut loc urmtorul dialog:
Nu tiu numerele spune P.
tiam ca nu tii rspunde S, nici eu nu tiu.
Acuma tiu! zice P strlucind de bucurie.
Acum tiu i eu. optete satisfcut S.
S se determine toate perechile de numere m i n ce satisfac acest
dialog (sunt soluii ale problemei).
4. (!) mpturirea celor 8 ptrate. mpturii iniial n opt o foaie
dreptunghiular dup care desfacei-o i nsemnai fiecare ptrel obinut cu o
cifr de la 1 la 8. Proiectai un algoritm i realizai un program care, primind
configuraia (numerotarea) celor 8 ptrele, s poat decide dac se poate
mpturi foaia astfel obinut reducnd-o de opt ori (la un singur ptrat) astfel
nct trecnd cu un ac prin cele opt foi suprapuse acesta s le perforeze exact
n ordinea 1, 2, 3 8.
5. (!) Problema fetelor de la pension. Problema a aprut pe vremea cnd
fetele nvau la pension fr ca prin prezena lor bieii s le tulbure educaia.
Pedagoaga fetelor unui pension de 15 fete a hotrt ca n fiecare dup-amiaz,
la ora de plimbare, fetele s se plimbe n cinci grupuri de cte trei. Se cere s se
stabileasc o programare a plimbrilor pe durata unei sptmni (apte zile)
astfel nct fiecare fat s ajung s se plimbe numai o singur dat cu oricare
din celelalte paisprezece (oricare dou fete s nu se plimbe de dou ori
mpreun n decursul unei sptmni).
Noiuni fundamentale de programare
Programarea este disciplina informatic ce are ca scop realizarea de
programe care s constituie soluiile oferite cu ajutorul calculatorului unor
probleme concrete. Programatorii sunt acele persoane capabile s implementeze
ntr-un limbaj de programare metoda sau algoritmul propus ca soluie
respectivei probleme, ce se preteaz a fi soluionat cu ajutorul calculatorului.

Dup nivelul de implicare n efortul de rezolvare a problemelor specialitii n


programare pot fi mprii n diverse categorii: analiti, analiti-programatori,
ingineri-programatori, simpli programatori, etc. Cu toii au ns n comun
faptul c fiecare trebuie s cunoasc ct mai bine programare i s fie capabil,
nu doar s citeasc, ci chiar s scrie codul surs, adic programul propriuzis. Din acest punct de vedere cunotinele de programare sunt considerate
ABC-ul informaticii i sunt indispensabile oricrui profesionist n domeniu.
1. Cele trei etape ale rezolvrii unei probleme cu ajutorul calculatorului
n rezolvarea sa cu ajutorul calculatorului orice problem trece prin trei
etape obligatorii: Analiza problemei, Proiectarea algoritmului de soluionare i
Implementarea algoritmului ntr-un program pe calculator. n ultima etap, sub
acelai nume, au fost incluse n plus dou subetape cunoscute sub numele de
Testarea i ntreinerea programului. Aceste subetape nu lipsesc din ciclul de
via a oricrui produs-program ce se respect dar, pentru simplificare, n
continuare ne vom referi doar la primele trei mari etape.
Dac etapa implementrii algoritmului ntr-un program executabil este o
etap exclusiv practic, realizat n faa calculatorului, celelalte dou etape
au un pronunat caracter teoretic. n consecin, primele dou etape sunt
caracterizate de un anumit grad de abstractizare. Din punct de vedere practic
ns i n ultim instan, criteriul decisiv ce confer succesul rezolvrii
problemei este dat de calitatea implementrii propriuzise. Mai exact, succesul
soluionrii este dat de performanele programului: utilitate, vitez de execuie,
fiabilitate, posibiliti de dezvoltare ulterioare, lizibilitate, etc. Cu toate acestea
este imatur i neprofesional strategia programatorilor nceptori care,
neglijnd primele dou etape, sar direct la a treia fugind de analiz i de
componenta abstract a efortului de soluionare. Ei se justific cu toii prin
expresii puerile de genul: Eu nu vreau s mai pierd vremea cu teoria, am s
fac programul cum tiu eu. Ct vreme nu va face altcineva altul mai bun dect
al meu, nu am de ce s-mi mai bat capul!.
2. Cum se stabilete corectitudinea i eficiena soluionrii?
Este adevrat c ultima etap n rezolvarea unei probleme
implementarea este decisiv i doveditoare, dar primele dou etape au o
importan capital. Ele sunt singurele ce pot oferi rspunsuri corecte la
urmtoarele ntrebri dificile: Avem certitudinea c soluia gsit este corect?
Avem certitudinea c problema este complet rezolvat? Ct de eficient este
soluia gsit? Ct de departe este soluia aleas de o soluie optim?
S menionm n plus c literatura informatic de specialitate conine un
numr impresionant de probleme capcan pentru nceptori i nu numai
pentru ei. Ele provin majoritatea din realitatea imediat dar pentru fiecare
dintre ele nu se cunosc soluii eficiente. De exemplu, este dovedit teoretic c
problema, aparent banal pentru un calculator, a proiectrii Orarului optim
ntr-o instituie de nvmnt (coal, liceu, facultate) este o problem
intratabil la ora actual (toate programele care s-au realizat pn acum nu
ofer dect soluii aproximative fr a putea spune ct de aproape sau de
departe este soluia optim de orar).

Ci dintre programatorii nceptori n-ar fi surprini s afle c problema


att de simpl (ca enun), a crei soluionare tocmai au abandonat-o, este de
fapt o problem dovedit teoretic ca fiind intratabil sau chiar insolvabil
algoritmic? Partea proast a lucrurilor este c, aa cum ciupercile otrvite nu
pot fi cu uurin deosebite de cele comestibile, tot astfel problemele netratabile
pot fi cu uurin confundate cu nite probleme uoare la o privire rapid i
lipsit de experien.
Dac ar fi s sintetizm n cte un cuvnt efortul asupra cruia se
concentreaz fiecare din cele trei etape analiza, proiectarea i implementarea
cele trei cuvinte ar fi: corectitudine, eficien i impecabilitate. Etapa de analiz
este singura care permite dovedirea cu argumente riguroase a corectitudinii
soluiei, iar etapa de proiectare este singura care poate oferi argumente precise
n favoarea eficienei soluiei propuse.
n general problemele concrete din informatic au n forma lor iniial
sau n enun o caracteristic pragmatic, fiind foarte ancorate n realitatea
imediat. Totui ele conin n formularea lor iniial un grad mare de
eterogenitate, diversitate i lips de rigoare. Fiecare dintre aceste defecte este
un obstacol major pentru demonstrarea corectitudinii soluiei. Rolul esenial al
etapei de analiz este acela de a transfera problema de pe nisipurile
mictoare ale realitii imediate de unde ea provine ntr-un plan abstract,
adic de a o modela. Acest univers paralel abstract este dotat cu mai mult
rigoare i disciplin intern, avnd legi precise i poate oferi instrumentele
logice i formale necesare pentru demonstrarea riguroas a corectitudinii
soluiei problemei. Planul abstract n care sunt transportate toate problemele
de informatic este planul sau universul obiectelor matematice iar
corespondentul problemei n acest plan va fi modelul matematic abstract
asociat problemei. Demonstrarea corectitudinii proprietilor ce leag obiectele
universului matematic a fost i este sarcina matematicienilor. Celui ce
analizeaz problema din punct de vedere informatic i revine sarcina (nu tocmai
uoar) de a dovedi printr-o demonstraie constructiv c exist o
coresponden precis (o bijecie!) ntre prile componente ale problemei reale,
dezasamblat n timpul analizei i prile componente ale modelului abstract
asociat. Odat descoperit, formulat precis i dovedit, aceast perfect
oglindire a problemei reale n planul obiectelor matematice ofer certitudinea
c toate proprietile i legturile ce exist ntre subansamblele modelului
abstract se vor regsii precis (prin reflectare) ntre prile interne ale problemei
reale i invers. Atunci, soluiei abstracte descoperite cu ajutorul modelului
matematic abstract i va corespunde o soluie real concretizat printr-un
algoritm ce poate fi implementat ntr-un program executabil.
Aceasta este calea general de rezolvare a problemelor i oricine poate
verifica acest fapt. De exemplu, ca i exerciiu, ncercai s demonstrai
corectitudinea (adic s se aduc argumente precise, clare i convingtoare n
favoarea corectitudinii) metodei de extragere a radicalului nvat nc din
coala primar (cu grupare cifrelor numrului n grupuri cte dou, etc.) sau a
algoritmului lui Euclid de determinare a celui mai mare divizor comun a dou
numere prin mpriri ntregi repetate. Desigur nu pot fi acceptate argumente

copilreti de forma: Algoritmul este corect pentru c aa l-am nvat! sau


Este corect pentru c aa face toat lumea! din moment ce nu se ofer o
argumentaie matematic riguroas.
Ideea central a etapei a doua proiectarea unui algoritm de soluionare
eficient poate fi formulat astfel: din studiul proprietilor i limitelor modelului
matematic abstract asociat problemei se deduc limitele inferioare ale
complexitii minimale (efortului minimal obligatoriu) inerente oricrui
algoritm ce va soluiona problema n cauz. Complexitatea intern a modelului
abstract i complexitatea soluiei abstracte se va reflecta imediat asupra
complexitii reale a algoritmului, adic asupra eficienei de soluionare a
problemei. Acest fapt permite prognosticarea nc din aceast faz faza de
proiectare a algoritmului de soluionare a eficienei practice, msurabil ca
durat de execuie, a programului.
3. Noiunile fundamentale ale programrii: algoritm, limbaje de descriere a
algoritmilor, program, limbaje de programare
3.1. Algoritmul
Se tie c la baza oricrui program st un algoritm (care, uneori, este
numit metod de rezolvare). Noiunea de algoritm este o noiune fundamental
n informatic i nelegerea ei, alturi de nelegerea modului de funcionare a
unui calculator, permite nelegerea noiunii de program executabil. Vom oferi
n continuare o definiie unanim acceptat pentru noiunea de algoritm:
Definiie. Prin algoritm se nelege o mulime finit de operaii
(instruciuni) elementare care executate ntr-o ordine bine stabilit
(determinat), pornind de la un set de date de intrare dintr-un domeniu de
valori posibile (valide), produce n timp finit un set de date de ieire (rezultate).
Cele trei caracteristici eseniale ale unui algoritm sunt:
1. Determinismul dat de faptul c ordinea de execuie a instruciunilor
algoritmului este bine precizat (strict determinat).
Acest fapt d una din calitile de baz a calculatorului: el va face
ntotdeauna ceea ce i s-a cerut (prin program) s fac, el nu va avea iniiative
sau opiuni proprii, el nu-i permite s greeasc nici mcar odat, el nu se
va plictisi ci va duce programul la acelai sfrit indiferent de cte ori i se va
cere s repete acest lucru. Nu aceeai situaie se ntmpl cu fiinele umane
(Errare humanum est). Oamenii pot avea n situaii determinate un
comportament non-deterministic (surprinztor). Acesta este motivul pentru
care numeroi utilizatori de calculatoare (de exemplu contabilii), datorit
fenomenului de personificare a calculatorului (confundarea aciunilor i
dialogului simulat de programul ce ruleaz pe calculator cu reaciile unei
personaliti vii), nu recunosc perfectul determinism ce st la baza executrii
oricrui program pe calculator. Exprimndu-se prin propoziii de felul: De trei
ori i-am dat s fac calculele i de fiecare dat mi-a scos aceleai valori aiurea!
ei i trdeaz propria viziune personificatoare asupra unui fenomen
determinist.
2. Universalitatea dat de faptul c, privind algoritmul ca pe o metod
automat (mecanic) de rezolvare, aceast metod are un caracter generaluniversal. Algoritmul nu ofer o soluie punctual, pentru un singur set de date

de intrare, ci ofer soluie pentru o mulime foarte larg (de cele mai multe ori
infinit) de date de intrare valide. Aceasta este trstura de baz care explic
deosebita utilitate a calculatoarelor i datorit acestei trsturi suntem siguri
c investiia financiar fcut prin cumprarea unui calculator i a produsuluisoft necesar va putea fi cu siguran amortizat. Cheltuiala se face o singur
dat n timp ce programul pe calculator va putea fi executat rapid i
economicos de un numr orict de mare de ori, pe date diferite!
De exemplu, metoda (algoritmul) de rezolvare nvat la liceu a ecuaiilor
de gradul doi: ax2+bx+c=0, se aplic cu succes pentru o mulime infinit de
date de intrare: (a, b, c) A\'7b0} xAxA.
3. Finitudinea pentru fiecare intrare valid orice algoritm trebuie s
conduc n timp finit (dup un numr finit de pai) la un rezultat. Aceast
caracteristic este analog proprietii de convergen a unor metode din
matematic: trebuie s avem garania, dinainte de a aplica metoda (algoritmul),
c metoda se termin cu succes (ea converge ctre soluie).
S observm i diferena: n timp ce metoda matematic este corect
chiar dac ea converge ctre soluie doar la infinit (!), un algoritm trebuie s
ntoarc rezultatul dup un numr finit de pai. S observm deasemenea c,
acolo unde matematica nu ofer dovada, algoritmul nu va fi capabil s o ofere
nici el. De exemplu, nu este greu de scris un algoritm care s verifice
corectitudinea Conjecturii lui Goldbach: Orice numr par se scrie ca sum de
dou numere prime, dar, dei programul rezultat poate fi lsat s ruleze pn
la valori extrem de mari, fr s apar nici un contra-exemplu, totui
conjectura nu poate fi astfel infirmat (dar nici afirmat!).
3.2. Descrierea algoritmilor
Dou dintre metodele clasice de descriere a algoritmilor sunt denumite
Schemele logice i Pseudo-Codul. Ambele metode de descriere conin doar patru
operaii (instruciuni) elementare care au fiecare un corespondent att schem
logic ct i n pseudo-cod.
n cele ce urmeaz vom nira doar varianta oferit de pseudo-cod
ntruct folosirea schemelor logice s-a redus drastic n ultimii ani. Schemele
logice mai pot fi ntlnite sub numele de diagrame de proces n anumite cri de
specialitate inginereti. Avantajul descrierii algoritmilor prin scheme logice este
dat de libertatea total de nlnuire a operaiilor (practic, sgeata care descrie
ordinea de execuie, pleac de la o operaie i poate fi trasat nspre orice alt
operaie). Este demonstrat matematic riguros c descrierea prin pseudo-cod,
dei pare mult mai restrictiv (operaiile nu pot fi nlnuite oricum, ci trebuie
executate n ordinea citirii: de sus n jos i de la stnga la dreapta), este totui
perfect echivalent. Deci, este dovedit c plusul de ordine, rigoare i simplitate
pe care l ofer descrierea prin pseudo-cod nu ngrdete prin nimic libertatea
programrii. Totui, programele scrise n limbajele de asamblare, care sunt
mult mai compacte i au dimensiunile mult reduse, nu ar putea fi descrise
altfel dect prin scheme logice.
1. Atribuirea var: =expresie;
2. Intrare/Ieire Citete var1, var2, var3,.;
Scrie var1, var2, var3,.; sau Scrie expresia1, expresia2, expresia3,.;

3. Condiionala Dac <condiie_logic> atunci instruciune1 [altfel


instruciune2];
4. Ciclurile Exist (din motive de uurin a descrierii algoritmilor) trei
tipuri de instruciuni de ciclare. Ele sunt echivalente ntre ele, oricare variant
de descriere putnd fi folosit n locul celorlalte dou, cu modificri sau
adugiri minimale:
Repet instruciune1, instruciune2,. Pn cnd <condiie_logic>;
Ct timp <condiie_logic> execut instruciune;
Pentru var_contor: =val_iniial pn la val_final execut instruciune;
n cazul ciclurilor, grupul instruciunilor ce se repet se numete corpul
ciclului iar condiia logic care (asemenea semaforului de circulaie) permite
sau nu reluarea execuiei ciclului este denumit condiia de ciclare sau condiia
de scurt-circuitare (dup caz). Observm c ciclul de tipul Repet are condiia
de repetare la sfrit ceea ce are ca i consecin faptul c corpul ciclului se
execut cel puin odat, n mod obligatoriu, nainte de verificarea condiiei
logice. Nu acelai lucru se ntmpl n cazul ciclului de tipul Ct timp, cnd
este posibil ca instruciunea compus din corpul ciclului s nu poat fi
executat nici mcar odat. n plus, s mai observm c ciclul de tipul PentrU.
Pn la conine (n mod ascuns) o instruciune de incrementare a variabilei
contor.
n limba englez, cea pe care se bazeaz toate limbajele actuale de
programare acestor instruciuni, exprimate n limba roman, le corespund
respectiv: 2. Read, Write; 3. If-Then-Else; 4. Repeat-Until, Do-While, For. S
observm c, mai ales pentru un vorbitor de limb englez, programele scrise
ntr-un limbaj de programare ce cuprinde aceste instruciuni este foarte uor
de citit i de neles, el fiind foarte apropiat de scrierea natural. Limbajele de
programare care sunt relativ apropiate de limbajele naturale sunt denumite
limbaje de nivel nalt (high-level), de exemplu limbajul Pascal, spre deosebire de
limbajele de programare mai apropiate de codurile numerice ale instruciunilor
microprocesorului. Acestea din urm se numesc limbaje de nivel sczut (lowlevel), de exemplu limbajul de asamblare. Limbajul de programare C are un
statut mai special el putnd fi privit, datorit structurii sale, ca fcnd parte
din ambele categorii.
Peste tot unde n pseudo-cod apare cuvntul instruciune el poate fi
nlocuit cu oricare din cele patru instruciuni elementare. Aceast substituire
poart numele de imbricare (de la englezescul brick-crmid). Prin
instruciune se va nelege atunci, fie o singur instruciune simpl (una din
cele patru), fie o instruciune compus. Instruciunea compus este format
dintr-un grup de instruciuni delimitate i grupate n mod precis (ntre acolade
{} n C sau ntre begin i end n Pascal).
Spre deosebire de pseudo-cod care permite doar structurile noi formate
prin imbricarea repetat a celor patru instruciuni (crmizi) n modul precizat,
schemele logice permit structurarea n orice succesiune a celor patru
instruciuni elementare, ordinea lor de execuie fiind dat de sensul sgeilor.
Repetm c dei, aparent, pseudo-codul limiteaz libertatea de descriere doar la
structurile prezentate, o teorem fundamental pentru programare afirm c

puterea de descriere a pseudo-limbajului este aceeai cu cea a schemelor


logice.
Forma de programare care se bazeaz doar pe cele patru structuri se
numete programare structurat (spre deosebire de programarea nestructurat
bazat pe descrierea prin scheme logice). Teorema de echivalen a puterii de
descriere prin pseudo-cod cu puterea de descriere prin schem logic afirm c
programarea structurat (aparent limitat de cele patru structuri) este
echivalent cu programarea nestructurat (liber de structuri impuse). Evident,
prin ordinea, lizibilitatea i fiabilitatea oferit de cele patru structuri elementare
(i asta fr a ngrdi libertatea de exprimare) programarea structurat este net
avantajoas. n fapt, limbajele de programare nestructurat (Fortran, Basic) au
fost de mult scoase din uz, ele (limbajele de asamblare) sunt necesare a fi
folosite n continuare doar n programarea de sistem i n programarea
industrial (n automatizri).
3.3 Programul
Prin program se nelege un ir de instruciuni-main care sunt
rezultatul compilrii algoritmului proiectat spre rezolvarea problemei dorite ce a
fost descris ntr-un limbaj de programare (ca i cod surs).
Etapele realizrii unui program sunt:
Editarea codului surs, etap ce se realizeaz cu ajutorul unui
program editor de texte rezultatul fiind un fiier Pascal sau C, cu extensia.pas
sau. C (.cpp)
Compilarea, etapa de traducere din limbajul de programare Pascal sau
C n limbajul intern al micro-procesorului i este realizat cu ajutorul
programului compilator Pascal sau C i are ca rezultat un fiier obiect, cu
extensia.obj (n limbajul C) sau.exe (n limbajul Pascal)
Link-editarea, etap la care se adaug modului obiect rezultat la
compilare diferite module coninnd subprograme i rutine de bibliotec,
rezultnd un fiier executabil (aceast etap este comasat n Turbo Pascal sau
Borland Pascal cu etapa de compilare), cu extensia.exe
Execuia (Run), etapa de lansare n execuie propriu-zis a
programului obinut, lansare realizat de interpretorul de comenzi al sistemului
de operare (command.com pentru sistemele DOS+Windows)
Observm c aceste patru (sau trei, pentru Turbo Pascal) etape sunt
complet independente n timp unele de altele i necesit utilizarea a patru
programe ajuttoare: Editor de texte, Compilator Pascal sau C, Link-editor i
Interpretorul de comenzi al S. O. n cazul mediilor de programare integrate
(Turbo sau Borland) comandarea acestor patru programe ajuttoare precum i
depanarea erorilor de execuie este mult facilitat.
Deasemenea, merit subliniat faptul c n timp ce fiierul text Pascal sau
C, ce conine codul surs, poate fi transportat pe orice main (calculator)
indiferent de micro-procesorul acesteia urmnd a fi compilat la faa locului, n
cazul fiierului obiect acesta nu mai poate fi folosit dect pe maina
(calculatorul) pentru care a fost creat (datorit instruciunilor specifice microprocesorului din care este compus). Deci, pe calculatoare diferite (avnd microprocesoare diferite) vom avea nevoie de compilatoare Pascal sau C diferite.

n plus, s remarcm faptul c fiierele obiect rezultate n urma


compilrii pot fi link-editate (cu grij!) mpreun chiar dac provin din limbaje
de programare diferite. Astfel, un program rezultat (un fiier.exe sau.com) poate
fi compus din module obiect care provin din surse diferite (fiiere Pascal, C,
asamblare, etc.).
4. Secretul nvrii rapide a programrii
Exist posibilitatea nvrii rapide a programrii?
Desigur. Experiena predrii i nvrii programrii ne-a dovedit c
exist metode diferite de nvare a programrii, mai rapide sau mai lente, mai
temeinice sau mai superficiale. Din moment ce se dorete nvarea rapid a
programrii nseamn c, pentru cel ce dorete aceasta, problemele ce i
ateapt rezolvarea cu ajutorul calculatorului sunt importante sau stringente.
Am putea chiar presupune c soluionarea lor rapid este un deziderat mai
important dect nvarea programrii. Tocmai de aceea, fiind contieni de
acest fapt, vom prezenta n continuare una din cele mai rapide metode de
nvare a programrii.
S observm mai nti c pentru nvarea unei limbi strine este
necesar comunicarea i vorbirea intens a acelei limbi. Cu toii am putut
constata c dac exist o motivaie sau nevoie puternic de a comunica n acea
limb, cel puin pentru o perioad de timp, procesul de nvare a ei este foarte
rapid. De exemplu, dac ne aflm ntr-o ar strin sau dac dorim apropierea
de o persoan strin (mai ales dac este atrgtoare i de sex opus.) categoric
vom constata c am nvat mult mai iute limba respectiv. i aceasta datorit
faptului c efortul de nvare a fost mascat n spatele efortului (intens motivat!)
de a comunica i de a ne face cunoscute inteniile i gndurile.
La fel, pentru nvarea rapid i cu uurin a programrii efortul
trebuie ndreptat, nu spre silabisirea limbajului de programare, ci spre
rezolvarea de probleme i spre scrierea direct a programelor de soluionare a
acestora. Concentrndu-ne asupra problemelor ce le soluionm nici nu vom
observa cnd i n ce fel am nvat s scriem programe. La urma urmei,
programarea este doar un instrument, doar o unealt de scris i nu un scop
n sine. Dac vrei iute s nvei s scrii, conteaz cum sau n ce mn ii
stiloul?
Nu trebuie deloc neglijat i un al doilea factor secret. Aa cum meseria
nu se nva, ci se fur , tot astfel programarea se poate nva mult mai uor
apelnd la ajutorul unui profesor sau a unui specialist. Acesta, prin experiena
i cunotinele sale de specialitate ne poate ajuta s pim alturi de el pe
crri bttorite i ntr-un ritm susinut.
n concluzie, ntr-o descriere plastic i metaforic, metoda secret cea
mai rapid de ascensiune n programare este metoda privirii concentrate spre
vrf, cu ghidul alturi i pe crri bttorite.
Noiuni primare de programare n Pascal i C
n spiritul celor spuse mai sus, vom introduce acum ntr-un ritm alert,
prin exemple concrete, noiunile elementare de programare n limbajele Pascal
i C (n paralel). Vom pleca de la prezentarea structurii generale a unui program
iar apoi vom trece la prezentarea celor patru structuri-lnstruciuni elementare

coninute n psedo-limbajul de descriere a algoritmilor. Vom avea n plus grij


de a precede descrierea fiecrei structuri elementare de liniile de declarare a
tipului variabilelor implicate. Peste tot vor apare linii de comentariu (ignorate de
compilator). n limbajul Pascal comentariile sunt cuprinse ntre acolade
{comentariu}, pe cnd n C ele sunt cuprinde ntre construcia de
tipul/*comentariu*/sau apar la sfritul liniei precedate de dou slashuri/comentariu.
Structura unui program
Program Nume_de_Program; {aceast linie poate s lipseasc}
{Zona de declaraii constante, variabile, proceduri i funcii}
BEGIN
{Corpul programului format din instruciuni terminate cu punct-vigul;
Corpul programului poate fi privit ca o instruciune compus}
END.
Orice se va scrie dup punct va fi ignorat de ctre compilator)
/linii de incluziuni de fiiere header
/declaraii de variabile i funcii externe (globale) void main (void){
/declaraii de variabile locale
/corpul programului format din instruciuni terminate cu punct-vigul;
Exemplu:
Program Un_Simplu_Test;
Const e=2.68;
Var x: real;
BEGIN x: =1. /2+e*(1+e);
Writeln (Rezultatul este:, x);
END.
Exemplu: include <stdio. H> int e=2.68; float x; void main (void){x=1.
/2+e*(1+e); printf (Rezultatul este %f:, x);
Atribuirea: var: =expresie;
Var i, j: integer; perimetrul: real; j: =2000 div 15; {mprire ntreag
obligatorie} i: =i+(j-l)*Sqr (2*j+1); {Sqr (Square) funcia de ridicare la ptrat}
perimetrul: =2*PI*i; {PI constant real implicit} include <math. H>/declar
constanta M_PI int i, j; float perimetrul; j=2000/15; /mprire ntreag
implicit!
I+= (j-l)* (2*j+1)*(2*j+1); /n C avem operatorul
/de adunare + nainte de egal =; funcia putere n
/C este pow (x, y) perimetrul=2*M_PI*i;
Intrare/Ieire:
Citete var1, var2, var3,.;
Scrie var1, var2, var3,.;
Sau
Scrie expresia1, expresia2, expresia3,.;
Var i, j: integer; perimetrul: real;
Readln (i, j); {citirea variabilelor i i j}
Perimetrul: =2*PI*i;
Writeln (Raza=, i:4, Perimetrul=, perimetrul:6:2, Aria=, PI*Sqr (i):6:2);

{perimetrul i aria fiind valori reale, se afieaz cu descriptorul de format


de afiare:6:2 pe 6 poziii de ecran cu rotunjit la 2 zecimale} include <math.
H>/declar constanta M_PI int i, j; float perimetrul; scanf (%i %i, &i, &j); / %i
%i este descriptorul de format de citire, & este operatorul de adresare
perimetrul=2*M_PI *i; printf (Raza=%4i Perimetrul= %6.2f Aria= %6.2f, i,
perimetrul, M_PI*i*i); /%6.2f descriptorul de format de afiare a unei valori
reale (flotante) pe 6 poziii rotunjit la 2 zecimale
Condiionala:
Dac <condiie_logic> atunci instruciune1 [altfel instruciune2];
Var i, j, suma: integer;
If i <= 2*j+1 then suma: =suma+i else suma: =suma+j; int i, j, suma; if
(i<=2*j+1) suma+=i else suma+=j;
Ciclul de tipul Repeat-Until:
Repet instruciune1, instruciune2,. Pn cnd <condiie_logic>;
Var i, j, suma: integer; suma: =0; i: =1;
Repeat suma: =suma+i; i: =i+1;
Until i>100; int i, j, suma; suma=0; i=1; do suma+=i; while (i+<100);
Ciclul de tipul Do-While:
Ct timp <condiie_logic> execut instruciune;
Var i, j, suma: integer; suma: =0; i: =1;
While i<=100 do begin suma: =suma+i; i: =i+1;
End; int i, j, suma; suma=0; i=1; while (i+<100) suma+=i;
Ciclul de tipul For (cu contor):
Pentru var_contor: =val_iniial pn la val_final execut instruciune;
Var i, j, suma: integer; suma: =0;
For i: =1 to 100 do
Suma: =suma+i; int i, j, suma; for (suma=0, i=1; i<=100; i+) suma+=i;
Exemple de probleme rezolvate
Prezentm n continuare, spre iniiere, cteva exemple de probleme
rezolvate. Vom oferi programul rezultat att n limbajul de programare Pascal
ct i n limbajul C. Deasemenea, fiecare program va fi precedat de o scurt
descriere a modului de elaborare a soluiei.
1. Se citesc a, b, c coeficienii reali a unei ecuaii de gradul II. S se
afieze soluile ecuaiei.
Descrierea algoritmului:
Ecuaia de gradul II este de forma ax2+bx+c=0
Presupunnd c a 0 calculm determinantul ecuaiei delta=b*b-4*a*c
Dac delta >= 0 atunci ecuaia are soluiile reale x1,2= (-bdelta)/(2*a)
Dac delta < 0 atunci ecuaia are soluiile complexe z1= (-b/(2*a), (delta)/(2*a), z1= (-b/(2*a).
(-delta)/(2*a)
Program Ecuaie_grad_2; {varianta Pascal}
Var a, b, c, delta: real;
BEGIN
Write (Introd. A, b, c:); Readln (a, b, c); delta: =b*b-4*a*c;
If delta>=0 then

Begin
Writeln (x1=, (-b-sqrt (delta)/(2*a):6:2);
Writeln (x2=, (-b+sqrt (delta)/(2*a):6:2);
End else Begin
Writeln (z1= (.
B/(2*a):6:2, , .
Sqrt (-delta)/(2*a):6:2, ) );
Writeln (z2= (.
B/(2*a):6:2, , , sqrt (-delta)/(2*a):6:2, ) );
End
Readln;
END.
/versiunea C include <stdio. H> include <math. H> float a, b, c;
/coeficienii ecuaiei de gradul II float delta; void main (){printf (Introd. Coefic.
Ecuaiei a b c:); scanf (%f %f %f, &a, &b, &c); delta=b*b-4*a*c; if (delta>=0)
{printf (Sol. Reale: x1=%6.2f, x2=%6.2f, (-b+sqrt (delta)/2. /a, (-b-sqrt
(delta)/2. /a);
} else {printf (Sol. Complexe: x1= (%6.2f, %6.2f), x2= (%6.2f, %6.2f).
B/2. /a, sqrt (-delta)/2. /a. -b/2/a. -sqrt (- delta)/2. /a);
2. S se determine dac trei numere a, b, c reale pot reprezenta laturile
unui triunghi. Dac da, s se caculeze perimetrul i aria sa.
Descrierea algoritmului:
Condiia necesar pentru ca trei numere s poat fi lungimile laturilor
unui triunghi este ca cele trei numere s fie pozitive (condiie implicit) i suma
a oricror dou dintre ele s fie mai mare dect cel de-al treilea numr
Dup condiia este ndeplinit vom calcula perimetrul i aria triunghiului
folosind formula lui Heron s=sqrt (p (p-a)(p-b)(p-c) unde p= (a+b+c)/2.
Program Laturile_Unui_Triunghi; {Pascal}
Var a, b, c, s, p: real; function laturi_ok: boolean; begin laturi_ok: = (a>0)
and (b>0) and (c>0) and (a+b>c) and (a+c>b) and (b+c>a); end;
BEGIN write (introduceti laturile); readln (a, b, c);
IF laturi_ok then begin p: = (a+b+c)/2; s: =sqrt (p*(p-a)*(p-b)*(p-c); writeln
(Aria=, s:5:2); writeln (Perimetrul=, 2*p:5:2); end else writeln (Nu formeaz
triunghi); readln;
END.
/versiunea C include <stdio. H> include <math. H> float a, b, c, s, p; int
validare_laturi (float a, float b, float c){return (a>0) & (b>0) & (c>0) & (a+b>c) &
(b+c>a) & (a+c>b); void main (void){printf (Introd. Laturile a b c:); scanf (%f %f
%f, &a, &b, &c); if (validare_laturi (a, b, c){p= (a+b+c)/2; s=sqrt (p*(p-a)*(pb)*(p-c); printf (Aria=%6.2f, Perimetrul=%6.2f, s, 2*p);
3. Se citete n ntreg. S se determine suma primelor n numere naturale.
Descrierea algoritmului:
Vom oferi varianta n care suma primelor n numere naturale va fi
calculata cu una dintre instruciunile repetitive cunoscute (for, while, repeat)
fr a apela la formula matematic cunoscut S (n) =n*(n+1)/2
Program Suma_n; {Pascal}

Var n, s, i: word;
BEGIN
Writeln (Introduceti limita n=); Readln (n); s: =0;
For i: =1 to n do s: =s+i;
Writeln (s=, s);
Readln;
END.
/versiunea C include <stdio. H> int n, s; void main (void){printf (Introd.
N:); scanf (%i, &n); for (; n>0; n-) s+=n; printf (S (n) =%i, s);
4. Se citete valoarea ntreag p. S se determine daca p este numr
prim.
Descrierea algoritmului:
Un numr p este prim dac nu are nici un divizor nafar de 1 i p cu
ajutorul unei variabile contor d vom parcurge toate valorile intervalului [2. p];
acest interval este suficient pentru depistarea unui divizor, cci: d1 | p p =
d1*d2 (unde d1 < d2) d1 d1*d2 = p iar d2 d1*d2 = p
Program Nr_prim; {Pascal}
Var p, i: word; prim: boolean;
BEGIN write (p=); readln (p); prim: =true; for i: =2 to trunc (sqrt (p) do if
n mod i=0 then prim: =false; prim: =true; if prim then write (p, este nr prim)
else write (p, nu e nr prim);
END.
/versiunea C (optimizat!) include <stdio. H> include <math. H> int p, i,
prim; void main (void){printf (Introd. P:); scanf (%i, &p); for (i=3, prim=p % 2;
(i<=sqrt (p) & (prim); i+=2) prim=p % i; printf (%i %s nR. Prim, p, (prim? este:
nu este);
5. Se citete o propoziie (ir de caractere) terminat cu punct. S se
determine cte vocale i cte consoane conine propoziia.
Program Vocale;
Var sir: string [80];
Vocale, Consoane, i: integer;
BEGIN
Write (Introd. Propoziia terminata cu punct:); Realn (sir); i: =1; Vocale:
=0; Consoane: =0;
While sir [i] <>. do begin
If Upcase (sir [i]) n [A, E, I, O, U] then Inc (Vocale) else If Upcase (sir
[i]) n [A.Z] then Inc (Consoane);
Inc (i); end;
Writeln (Vocale:, Vocale, Consoane:, Consoane, Alte caractere:, iVocale-Consoane);
END.
/versiunea C include <stdio. H> include <ctype. H> int i, vocale=0,
consoane=0; char c, sir [80]; void main (void){printf (Introd. Propoziia
terminata cu punct:); gets (sir); for (i=0; sir [i]! =.; i+) switch (toupper (sir
[i]){case A: case E: case I: case O: case U: vocale+; break; default: if (isalpha

(sir [i]) consoane+; printf (Vocale: %i, Consoane: %i, Alte car.: %i, vocale,
consoane, i-vocale-consoane);
Metoda practic de nvare ce garanteaz rezultate imediate
Dac cele spuse mai sus cu privire la secretul nvrii rapide a
programrii, acum nu ne mai rmne dect s ncepem s aplicm practic
ideile prezentate. Pentru aceasta, avem la dispoziie urmtoarea metod care
garanteaz cu siguran rezultate. Iat-o, pe pai:
1. Se citete i se nelege ct mai bine exemplul de problem rezolvat
(se poate ncepe chiar cu primul exemplu de mai sus)
2. Se acoper (se ascunde) soluia i se ncearc reproducerea ei din
memorie (reinventarea soluiei) pe calculator
3. Numai n cazuri excepionale se poate apela (se poate trage cu ochiul)
la soluie
Oricare dintre noi poate recunoate aici metoda pe care o aplic copiii din
primele clase primare: metoda trasului cu ochiul la rezultatul aflat la spatele
manualului sau al culegerii de probleme. Din moment ce metoda este verificat
i garantat (am folosit-o i noi cndva), de ce ne-ar fi ruine s-o aplicm acum
din nou?
Iat n continuare o list de probleme de antrenament care au majoritea
rezolvarea ntr-unul din capitolele urmtoare. Este numai bine pentru a ncepe
s aplicm metoda oferit chiar acum!
Probleme selecionate Enunuri
Probleme propuse spre rezolvare (probleme de antrenament)
1. Se citesc a, b, c trei variabile reale.
S se afieze maximul i minimul celor trei numere.
S se afieze cele trei numere n ordine cresctoare.
S se determine dac cele trei numere pot reprezenta laturile unui
triunghi. Dac da, s se determine dac triunghiul respectiv este isoscel,
echilateral sau oarecare.
S se determine dac cele trei numere pot reprezenta laturile unui
triunghi. Dac da, s se determine mrimile unghiurilor sale i dac este
ascuit-unghic sau obtuz-unghic.
S se afieze media aritmetic, geometric i hiperbolic a celor trei
valori.
2. Se citete n o valoare ntreag pozitiv.
S se determine dac n este divizibil cu 3 dar nu este divizibil cu 11.
S se determine dac n este ptrat sau cub perfect.
S se afieze primele n ptrate perfecte.
S se determine numrul cuburilor perfecte mai mici dect n.
S se gseasc primul numr prim mai mare dect n.
S se afieze primele n numere prime: 2, 3, 5, 7 pn.
S se determine toate numerele de 4 cifre divizibile cu n.
S se determine suma cifrelor lui n.
S se afieze rsturnatul lui n. (Ex: n=1993 => n_rsturnat =3991).
S se afieze urmtorul triunghi de numere:
12 3. N

3. Se citesc m, n dou variabile ntregi pozitive.


S se determine toate ptratele perfecte cuprinse ntre m i n, inclusiv.
S se determine toate numerele prime cuprinse ntre m i n.
S se determine toate numerele de 4 cifre care se divid att cu n ct i
cu m.
S se determine c.m.m.d.C. Al celor dou numere folosind algoritmul
lui Euclid.
4. S se calculeze u20, u30, u50 ai irului cu formula recursiv
un=1/12un-l+1/2un-2 pentru n>=2 i u0=1, u1=1/2.
5. Se citete n gradul unui polinom i irul an, an-l a1, a0 coeficienilor
unui polinom P.
Se citete x, s se determine P (x).
Se citesc x i y, s se determine dac polinomul P schimb de semn de
la x la y.
Se citete a, s se determine restul mpririi lui P la x-a.
6. Se citesc m, n gradele a dou polinoame P i Q i coeficienii acestora.
S se determine polinomul produs R=PxQ.
7. Se citete o propoziie (ir de caractere) terminat cu punct.
S se determine cte vocale i cte consoane conine propoziia.
S se afieze propoziia n ordine invers i cu literele inversate (mari
cu mici).
S se afieze fiecare cuvnt din propoziie pe cte o linie separat.
S se afieze propoziia rezultat prin inserarea n spatele fiecrei
vocale v a irului pv (vorbirea gineasc).
8. Se citete m, n dimensiunea unei mtrici A= (ai, j) mxn de valori reale.
Se citesc l, c. S se afieze matricea obinut prin eliminarea liniei l i a
coloanei c.
Se citete n ntreg pozitiv, s se afieze matricea obinut prin
permutarea circular a liniilor mtricii cu n poziii.
S se determine suma elementelor pe fiecare linie i coloan.
S se determine numrul elementelor pozitive i negative din matrice.
S se determine linia i coloana n care se afl valoarea maxim din
matrice.
S se determine linia care are suma elementelor maxim.
9. Se citesc m, n, p i apoi se citesc dou mtrici A= (ai, j) mxn i B= (bj,
k) nxp. S se determine matricea produs C=AxB.
10. Se citete un fiier ce conine mai multe linii de text.
S se afieze linia care are lungime minim.
S se afieze liniile care conin un anumit cuvnt citit n prealabil.
S se creeze un fiier care are acelai coninut dar n ordine invers.
Probleme de examen
1. Se citete x o valoarea real. S se determine radical (x) cu 5 zecimale
exacte pe baza irului convergent xn=1/2 (xn-l+x/xn-l) cu x0>0 arbitrar ales.
2. Se citete x o valoarea real i k un numr natural. S se determine
radical de ordinul k din x cu 5 zecimale exacte pe baza irului convergent
xn=1/k (k-l) xn-l+x/xn-lk-l) cu x0>0 arbitrar ales.

3. S se determine c.m.m.m.C. A dou numere m, n citite.


4. Se citete n, s se determine toate perechile (x, y) care au cmmmc (x, y)
=n.
5. Se citesc a, b, c ntregi pozitive, s se determine toate perechile ntregi
(x, y) care conduc la egalitatea c=ax+by.
6. Se citete n o valoare ntreag pozitiv. S se determine toate
descompunerile n diferen de ptrate a lui n.
7. S se determine toate tripletele (i, j, k) de numere naturale ce verific
relaia i2+j2+k2=n unde n se citete.
8. Se citete n, s se afieze toate numerele pitagoreice mai mici sau egale
cu n.
9. Se citete n, s se determine toate numerele perfecte mai mici dect n.
(Un numr este perfect dac este egal cu suma divizorilor si, ex. 6=1+2+3.)
10. Se citete n, s se afieze toate numerele de n cifre, formate numai cu
cifrele 1 i 2 i care se divid cu 2n.
11. Se citete n, s se afieze toate numerele de n cifre care adunate cu
rsturnatul lor dau un ptrat perfect.
12. Se citete n ntreg pozitiv, s se afieze n transcris n baza 2.
13. Se citete n ntreg pozitiv scris n baza 2, s se afieze n transcris n
baza 10.
14. Se citete n ntreg pozitiv, s se afieze n n transcripia roman. (Ex:
1993=MCMXCIII, unde M=1000, D=500, C=100, L=50, X=10, V=5, I=1.)
15. Se citete n, s se afieze descompunerea acestuia n factori primi.
16. Se citesc m, n numrtorul i numitorul unei fracii. S se simplifice
aceast fracie.
17. Se citete n, s se afieze toate posibilitile de scriere a lui n ca sum
de numere consecutive.
18. Se citete n i k, s se afieze n ca sum de k numere distincte.
19. Se citete n, s se determine o alegere a semnelor + i astfel nct s
avem relaia 12. (n+1) n=0, dac ea este posibil.
20. Se citete n i irul de valori reale x1, x2 x n-l, xn ordonat
cresctor. S se determine distana maxim ntre dou elemente consecutive
din ir.
21. Se citete n gradul unui polinom i irul xn, xn-l x1 soluiilor reale
a unui polinom P. S se determine irul an, an-l a1, a0 coeficienilor
polinomului P.
22. Se citesc dou iruri de valori reale x1, x2 x n-l, xn i y1, y2 y ml, ym ordonate cresctor. S se afieze irul z1, z2 z n+m-l, zn+m rezultat prin
interclasarea celor dou iruri.
23. Un ir de fracii ireductibile din intervalul [0,1] cu numitorul mai mic
sau egal cu n se numete ir Farey de ordinul n. De exemplu irul Farey de
ordinul 5 (ordonat cresctor) este: 0/1, 1/5, , 1/3, 2/5, , 3/5, 2/3, , 4/5,
1/1. S se determine irul Farey de ordinul n, cu n citit.
24. Se citete n i S o permutare a mulimii {1, 2 n}. S se determine
numrul de inversiuni i signatura permutrii S.

25. Se citete n i S o permutare a mulimii {1, 2 n}. S se determine cel


mai mic numr k pentru care Sk= {1, 2 n}.
26. Fie M= {1, 3, 4,.} mulimea numerelor obinute pe baza regulii R1 i a
regulii R2 aplicate de un numr finit de ori: R1) 1M R2) Dac xM atunci
y=2x+1 i z=3x+1 aparin lui M. Se citete n, s se determine dac n aparine
mulimii M fr a genera toate elementele acesteia mai mici dect n.
27. Se citete n, k i o matrice A= (ai, j) nxn ptratic. S se determine
Ak.
28. Se citete n i o matrice A= (ai, j) nxn ptratic. S se determine d
determinantul mtricii A.
29. Se citete n i cele n perechi (xi, yi) de coordonate a n puncte Pi n
plan. S se determine care dintre cele n puncte poate fi centrul unui cerc
acoperitor de raz minim.
30. S se determine, cu 5 zecimale exacte, rdcina ecuaiei x3+x+1=0
care exist i este unic n intervalul [-l,1].
31. Se citete n i irul de valori reale x1, x2 x n-l, xn. S se determine
poziia de nceput i lungimea celui mai mare subir de numere pozitive.
32. Se citete n, s se afieze binomul lui Newton: (x+y) n.
33. Se citete n, s se afieze binomul lui Newton generalizat: (x1+x2+.
+xp) n=Sn! /(n1! N2! np!) x1n1x2n2. Xpnp pentru n1+n2+. +np=n i ni>0, i=1,
p.
34. Se citete n, s se determine descompunerea lui n ca sum de
numere Fibonacci distincte. (Fn=Fn-l+Fn-2 pentru n>1 i F1=1, F0=0).
35. Avem la dispoziie urmtoarele trei operaii care se pot efectua asupra
unui numr n: O1) i se adaug la sfrit cifra 4; O2) i se adaug la sfrit cifra
0; O3) dac n este par se mparte la 2. S se afieze irul operaiilor care se
aplic succesiv, pornind de la 4, pentru a obine un n care se citete.
36. Fie funcia lui Ackermann definit astfel: A (i, n) =n+1 pentru i=0; A
(i, n) =A (i-l,1) pentru i>0 i n=0; A (i, n) =A (i-l, A (i, n-l) pentru i>0 i n>0. Care
este cea mai mare valoare k pentru care se poate calcula A (k, k)?
37. S se determine suma tuturor numerelor formate numai din cifre
impare distincte.
38. Scriei o funcie recursiv pentru a determina c.m.m.d.C. A dou
numere m i n.
39. Scriei o funcie recursiv pentru a calcula an pe baza relaiei an=
(ak)2 pentru n=2k i an=a (ak)2 pentru n=2k+1.
40. Scriei o funcie recursiv pentru a determina prezena unui numr x
ntr-un ir de valori reale x1, x2 x n-l, xn ordonate cresctor folosind
algoritmul cutrii binare.
41. Scriei o funcie recursiv pentru a determina o aezare a 8 turnuri
pe o tabl de ah astfel nct s nu se atace ntre ele. (Tabla de ah va fi
reprezentat printr-o matrice ptratic de 8x8).
42. S se determine peste ci ani data de azi va cdea n aceeai zi a
sptmnii.
43. Avem la dispoziie un fiier ce conine numele, prenumele i media
tuturor studenilor din grup.

S se afieze studentul cu cea mai mare medie.


S se afieze toi studenii bursieri.
S se afieze studentul care are media cea mai apropiat de media
aritmetic a mediilor pe grup.
S se afieze toi studenii din prima jumtate a alfabetului.
S se afieze toi studenii n ordine invers dect cea din fiier.
S se creeze un fiier catalog care s conin aceleai informaii n
ordinea alfabetic a numelui.
44. Avem la dispoziie dou fiiere ce conin numele, prenumele i media
tuturor studenilor din cele dou grupe ale anului n ordinea descresctoare a
mediilor.
S se afieze toi studenii din ambele grupe care au media mai mare
dect media anului.
S se creeze prin interclasare un fiier totalizator care conine toi
studenii anului n ordinea descresctoare a mediilor.
Probleme dificile
Dup cum se poate bnui, informatica conine i ea, la fel ca matematica,
o mulime de probleme foarte dificile care i ateapt nc rezolvarea.
Asemnarea cu matematica ne intereseaz mai ales n privina unui aspect
capcan asupra cruia dorim s atragem atenia aici.
Enunurile problemelor dificile sau foarte dificile de informatic este, n
99% din cazuri, foarte simplu i poate fi citit i neles de orice student. Acest
fapt consituie o capcan sigur pentru cei ignorani. Dac n matematic
lucrurile nu stau aa, asta se datoreaz numai faptului c studiul matematicii
are vechime i problemele, mpreun cu dificultile lor, sunt ceva mai bine
cunoscute. n informatic nu avem ns aceeai situaie. Ba chiar se ntmpl
c probleme foarte dificile sunt amestecate n culegerile de probleme de
informatic printre probleme uoare, mai ales datorit lipsei de cultur de
specialitate a autorilor.
Acest capitol i propune s pun n gard n privina dificultii
problemelor oferind o mic iniiere n acest domeniu (mai multe se pot afla
studiind Complexitatea algoritmilor i dificultatea problemelor). Deasemeni el
i propune s umple lacuna ce mai exist nc la ora actual n cultura de
specialitate.
Dificultatea problemelor de programare a cror enunuri urmeaz este
considerat maxim de teoreticienii informaticii (ele se numesc probleme NPcomplete). Nu v lsai pclii de faptul c le-ai ntlnit n unele culegeri de
programare. Ele sunt depite n dificultate doar de problemele insolvabile
algoritmic! Dar n ce const dificultatea lor?
Spre deosebire de matematic, dificultatea problemelor de informatic nu
este dat de faptul c nu se cunoate un algoritm de rezolvare a lor, ci datorit
faptului c nu se cunoate un algoritm eficient (!) de rezolvare a lor. Existena
unei metode de proiectare a algoritmilor att de general valabil, cum este
metoda back-tracking, face ca prea puine probleme cu care ne putem ntlni
s nu aib o soluie. Dar, ntruct n cazul metodei back-tracking, cutarea
soluiei se face ntr-un mod exhaustiv (se caut peste tot, pentru ca s fim

siguri c nu lsm nici o posibilitate neexplorat), durata cutrii are o cretere


exponenial-proporional cu dimesiunea datelor de intrare. De exemplu,
timpul de cutare care depinde de valoarea de intrare n poate avea o expresie
de forma T (n) =c2n secunde, unde c este un factor de proporionalitate ce
poate varia, s zicem, de la c=12.5 cnd algoritmul este executat pe un
calculator sau c=62.8 cnd el este rulat pe un calculator de cinci ori mai
performant. Dar, indiferent de calculator, pentru n=100 avem 2100= (210)10
(103)10=1030, deci timpul msurat n secunde are ordinul de mrime mai mare
de 30. Cea mai larg estimare pentru vrsta Universului nostru nu depete
20 mild. Ani ceea ce transformat n secunde conduce la un ordin de mrime
mai mic de 20. Deci, chiar i pentru valori mici ale lui n (de ordinul sutelor) am
avea de ateptat pentru gsirea soluiei de 10 miliarde de ori mai mult dect a
trecut de la Big Bang ncoace! Pot fi n aceast situaie considerate astfel de
programe ca rezolvri rezonabile, doar pentru c ele gsesc soluia n cazurile
n care n=2, 3, 4 10?
Exemplele urmtoare sunt doar cteva, uor de ntlnit din greeal,
dintr-o list cunoscut ce conine la ora actual peste ase sute de astfel de
probleme. Pentru fiecare din aceste probleme nu li se cunosc alte soluii dect
inutilii algoritmi de gen back-tracking. n list apare des noiunea de graf, aa
c o vom introduce n continuare ct mai simplu cu putin: printr-un graf se
nelege o mulime de vrfuri i o mulime de muchii care unesc unele vrfuri
ntre ele. Orice hart (schematizat) rutier, feroviar sau de trafic aerian
reprezint desenul unui graf.
1. Problema partiionrii sumei. Fie C un ntreg pozitiv i d1, d2 dn o
mulime de n valori ntregi pozitive. Se cere s se gseasc o partiionare a
mulimii d1, d2 dn astfel nct suma elementelor partiiei s fie exact C.
2. Problema rucsacului. Avem un rucsac de capacitate ntreag pozitiv C
i n obiecte cu dimensiunile d1, d2 dn i avnd asociate profiturile p1, p2
pn (n caz c ajung n rucsac). Se cere s se determine profitul maxim ce se
poate obine prin ncrcarea rucsacului (fr ai depi capacitatea).
3. Problema colorrii grafului. S se determine numrul minim de culori
(numrul cromatic) necesar pentru colorarea unui graf astfel nct oricare dou
vrfuri unite printr-o muchie (adiacente) s aib culori diferite.
4. Problema mpachetrii. Presupunnd c dispunem de un numr
suficient de mare de cutii fiecare avnd capacitatea 1 i n obiecte cu
dimensiunile d1, d2 dn, cu 0<di<1, se cere s se determine numrul optim
(cel mai mic) de cutii necesar pentru mpachetarea tutror celor n obiecte.
5. Problema comisului voiajor. (varianta simplificat) Dndu-se un graf (o
hart), se cere s se gseasc un circuit (un ir de muchii nlnuite) care trece
prin fiecare vrf o singur dat.
Majoritatea acestor probleme apar ca probleme centrale la care se reduc
n ultim instan problemele concrete ale unor domenii capitale ale economiei
i industriei, cum sunt de exemplu planificarea investiiile, planificarea
mprumuturilor i ealonarea plii dobnzilor, alocarea i distribuirea
resurselor primare (mai ales financiare), etc. Pentru niciuna din aceste
probleme strategice nu se cunoate un algoritm optim de rezolvare, ci doar

soluii aproximative. Dac s-ar cunoate algoritmii de soluionare optim atunci


majoritatea sectoarelor i proceselor macroi micro-economice ar putea fi
conduse n timp real i optim (!) cu calculatorul, fr a mai fi necesar prezena
uman.
Un exemplu cert de domeniu care s-a dezvoltat extraordinar i n care
rolul soft-ului a fost esenial este chiar domeniul construciei de calculatoare,
mai ales domeniul proiectrii i asamblrii de micro-procesoare. Dac ai vzut
c schema electronic intern de funcionare a unui microprocesor din familia
Pentium, dac ar fi desenat clasic, ar ocupa o plan de dimensiuni 5x5 metri
(!), nu mai avei cum s v ndoii de faptul c numai un soft de proiectare i
cablare performant mai poate controla i stpni super-complexitatea rezultat.
Puin lume tie ns c astfel de programe de proiectare performante au putut
s apar numai datorit faptului c problema ce st n spatele funcionrii lor,
problema desenrii grafurilor planare, nu se afl pe lista de mai sus a
problemelor foarte dificile ale informaticii!
Probleme nesoluionate nc
Aa cum s-a putut constata n capitolul anterior, exist multe probleme
n informatic pentru care nc nu se cunosc soluii eficiente. n continuare
vom oferi o list de probleme nesoluionate nc. De fapt, ele apar mai ales n
matematic, fiind cunoscute sub numele de conjecturi i au toate ca specific un
fapt care este de mare interes pentru programatori. Incertitudinea asupra lor ar
putea fi definitiv nlturat nu numai prin demonstraie matematic ci i cu
ajutorul formidabilei puteri de calcul a computerelor. Astfel, fiecare din aceste
conjecturi numerice ar putea fi infirmat (concluzia ar fi atunci c conjectura
este fals) dac i s-ar gsi un contraexemplu. Este necesar doar s se gseasc
un set de numere pentru care propoziia respectiv s fie fals. Ori, acest efort
nu este la ndemna niciunui matematician dar este posibil pentru un
programator nzestrat i pasionat. El nu are dect s scrie un program eficient
i s pun calculatorul s caute un contra-exemplu.
Atragem atenia asupra unui aspect important. Fiecare problem conine
aceeai capcan ca i n problemele capitolului anterior: algoritmii de cutare a
contra-exemplelor pot fi concepui rapid, relativ simpli i cu efort de
programare redus (de exemplu, prin trei-patru cicluri for imbricate sau printr-o
soluie gen back-tracking) dar ei vor deveni n scurt timp total ineficieni i vor
conduce la programe mari consumatoare de timp. De aceea, v sugerm s
tratai cu mult atenie problemele din acest capitol. Dup prerea noastr,
abordarea acestui tip de probleme cere din partea programatorului un anumit
grad de miestrie!
Rezolvnd numai una dintre ele vei fi recompensai pe msur: riscai s
devenii celebri!
1. Conjectura lui Catalan. Singurele puteri naturale succesive sunt 8=23
i 9=32.
Observaie: ntr-o exprimare matematic riguroas, singura soluie n
numere naturale m, n, p, q a ecuaiei nm+1=pqeste n=2, m=3, p=3 i q=2.
Comentariu: avem irul numerelor naturale 1, 2, 3, 4, 5,.; ncercuind
toate puterile de gradul 2: 1, 4, 9, 16, 25,. Apoi toate cele de gradul 3: 1, 8, 27,

64, 125,. Apoi cele de grad 4, 5,. Vom constata c singurele dou numere
ncercuite alturate sunt 8 i 9! Adic puterile obinute, cu ct sunt mai mari,
cu att au tendina s se mprtie i s se distaneze unele de altele tot mai
tare. n mod misterios, ele nu-i suport vecintatea unele cu altele!
2. Conjectura cutiei raionale. Nu se cunoate existena unei cutii
paralelipipedice avnd lungimile celor trei laturi, ale celor trei diagonale ale
feelor i a diagonalei principale ntregi.
Observaie: ntr-o exprimare matematic riguroas, nu se cunoate s
existe trei ntregi a, b, c astfel nct a2+b2, b2+c2, c2+a2i a2+b2+c2s fie toate
patru ptrate perfecte.
Comentariu: n multe subdomenii ale construciilor, de exemplu s ne
gndim la stlpii de nalt tensiune ridicai pe vrfuri nalte de munte i
asamblai n ntregime la faa locului numai din bare mbinate cu uruburi
(fr sudur), este de mare interes ca dintr-un numr ct mai mic de
subansamble simple (un fel de crmizi) s se asambleze obiecte mari cu ct
mai multe configuraii. Evident, dimensiunile obiectelor rezultate vor avea
mrimea ca o combinaie ntreag ale dimensiunilor subansamblelor iniiale.
Dup cum rezult ns din conjectur, se pare c este imposibil s se
construiasc scheletul ntrit (pe diagonale) al unei cutii paralelipipedice din
bare de lungimi tipizate. Cel puin una din diagonale necesit ajustarea
lungimii unei bare!
3. Problema umplerii ptratului unitate. ntrebare: este posibil ca
mulimea dreptunghiurilor de forma 1/k x 1/(k+1), pentru fiecare k ntreg
pozitiv, s umple n ntregime i fr suprapuneri ptratul unitate, de latur
1x1?
Observaie: este evident c suma infinit a ariilor dreptunghiurilor este
egal cu aria ptratului unitate. Avem Sk>01/(k (k+1) =Sk>0(1/k-l/(k+1) =1.
Comentariu: aparent, descoperirea dezvoltrilor n serie pare s fi plecat
de la unele evidente propieti geometrice, uor de sesizat chiar din desene
simple n care valorilor numerice li se asociaz segmente de lungimi
corespunztoare. Iat ns o surpriz n aceast situaie: suma seriei numerice
este evident analitic ns reprezentarea geometric a fenomenului este
imposibil!
4. Conjectura fraciilor egiptene (atribuit lui Erds i Graham). Orice
fracie de forma 4/n se descompune ca sum de trei fracii egiptene (de forma
1/x).
Observaie: ntr-o exprimare matematic riguroas, pentru orice n natural
exist trei valori naturale, nu neaprat distincte, x, y i z astfel nct
4/n=1/x+1/y+1/z.
Comentariu: este nc un mister motivul pentru care egiptenii preferau
descompunerea faciilor numai ca sum de fracii egiptene. Descoperiser ei
aceast descompunere minimal a fraciilor de forma 4/n? Dar mai ales, ce
procese fizice reale erau astfel mai bine modelate? nclinm s credem c exist
o legtur ntre fenomenele fizice ondulatorii, transformata Fourier i fraciile
egiptene!

5. Problema punctului raional. Exist un punct n plan care s se afle la


o distan raional de fiecare din cele patru vrfuri ale ptratului unitate?
Observaie: dac considerm un ptrat unitate avnd vrfurile de
coordonate (0,0), (1,0), (0,1) i (1,1) atunci se cere gsirea unui punct (x, y)
astfel nct x2+y2, (x-l)2+y2, x2+(y-l)2i (x-l)2+(y-l)2 s fie toate patru ptrate
perfecte. Atenie, x i y nu este obligatoriu s fie ntregi! Acest fapt ridic foarte
serioase probleme la proiectarea unui algoritm de cutare a unui astfel de
punct (x, y).
Comentariu: la fel ca i n cazul cutiei raionale, se pare c exist limitri
serioase i neateptate n ncercarea de optimizare a numrului de
subansamble necesare pentru construierea scheletelor sau cadrelor de
susinere. Se pare c cele dou dimensiuni pe care geometria plan se bazeaz
conduce la o complexitate inerent neateptat de mare!
6. Problema sumei de puteri. Care este suma seriei de inverse de puteri
1/1+1/23+1/33+1/43+1/53+.?
Observaie: se cere s se spun ctre ce valoare converge seria Sk>01/k3
sau Sk>0k-3. Se tie c n cazul n care n locul puterii a 3-la (cu minus)
punem puterea a 2-a (cu minus) seria converge la p 2/6, n cazul n care n
locul puterii a 3-la punem puterea a 4-a seria converge la p 4/90.
Comentariu: dei pare a fi o problem de analiz matematic pur
deoarece ni se cere s gsim expresia sintetic i nu cea numeric aproximativ
a sumei seriei, exist ns uluitoare descoperiri asemntoare ale unor formule
de analiz numeric sau chiar dezvoltri n serie (cea mai celebr fiind cea a lui
cifrelor hexazecimale ale lui p) fcute cu ajutorul calculatorului prin calcul
simbolic! Mai multe amnunte gsii la adresa corespunztoare de Internet pe
care am trecut-o n ultimul capitol.
7. Problema ecuaiei diofantice de gradul 5. Exist a, b, c, and d ntregi
pozitivi astfel nct a5+b5=c5+d5?
Observaie: Se cunoate c n cazul n care puterea este 3 avem soluia:
13+123=93+103 iar n cazul n care puterea este 4 avem soluia:
1334+1344=594+1584.
Comentariu: cutarea unor algoritmi generali de rezolvare a ecuaiilor
diofantice a condus la importante descoperiri n matematic dar i n
informatic. De exemplu, celebrul matematician Pierre Fermat, strnit fiind de
problemele coninute n lucrarea Arithmetika a matematicianului antic Diofant
din Alexandria (de unde i numele ecuaiilor diofantice), a descoperit n 1637
faimoasa sa teorem: Ecuaia diofantic xn+yn=zn nu admite soluie pentru
n>2. Dar tot n aceeai perioad a descoperit i faptul c cea mai mic soluie a
ecuaiei diofantice x2 109*y2 = 1 este perechea x=158070671986249 i y=
15140424455100. Dumneavoastr ncercai doar s verificai aceast soluie
fr ajutorul calculatorului i v vei putea da seama de performanele pe care
le-a realizat Fermat! n informatic este acum cunoscut i demonstrat c este
imposibil s se construiasc un algoritm general pentru rezolvarea ecuaiilor
diofantice!

8. Problema celor 13 orae. Putei localiza 13 orae pe o planet sferic


astfel nct distana minim dintre oricare dou dintre ele s fie ct mai mare
cu putin?

Observaie: de fapt nu se cunoate ct de mult


poate fi mrit distana minimal ce se obine dintre cele 78 de distane (date
de cele 78=C213 de mperecheri posibile de orae).
Comentariu: dac s-ar cere localizarea a doar 12 puncte pe sfer, nu este
greu de artat c aezarea care ndeplinete condiia cerut este n vrfurile
unui icosaedru (vezi figura alturat). n acest caz, distana minim maximizat
este egal cu latura icosaedrului. Este greu de crezut c n cazul descoperirii
aezrii a 13 puncte pe sfer se poate porni tocmai de la icosaedru! Evident c
n rezolvarea aplicativ-practic a acestui tip de probleme nesoluionate
geometric pn n prezent rolul programatorului poate fi capital. La ora actual
pentru astfel de situaii se ofer soluii aproximative. Acestea constau din
algoritmi care ncearc s aproximeze ct mai exact soluia optim ntr-un timp
rezonabil de scurt. Evident c n aceste condiii algoritmii de cutare
exhaustiv (gen back-tracking) sunt cu totul exclui!
9. Conjectura lui Collatz. Se pleac de la un n ntreg pozitiv. Dac n este
par se mparte la doi; dac n este impar se nmulete cu trei i i se adun unu.
Repetnd n mod corespunztor doar aceti doi pai se va ajunge ntotdeauna
la 1 indiferent de la ce valoare n se pornete?
Observaie: de exemplu, pornind de la n=6 obinem n 8 pai irul
valorilor: 6, 3, 10, 5, 16, 8, 4, 2, 1.
Comentariu: valoarea final 1 este ca o gaur neagr care absoarbe n
final irul obinut. Raza de-a lungul creia are loc cderea n gaura neagr 1
este dat mereu de irul puterilor lui 2: 2, 4, 8, 16, 32, 64,. Cu ultima valoare
de forma 3k+1, adic 4, 16, 64, 256,. Se pare c valorile obinute prin cele dou
operaii nu pot s nu dea nicicum peste acest ir care le va face apoi s cad
n gaura neagr 1!
10. Problema nscrierii ptratului. Dndu-se o curb simpl nchis n
plan, vom putea ntotdeauna gsi patru puncte pe curb care pot s constituie
vrfurile unui ptrat?
Observaie: n cazul curbelor nchise regulate (ce au axe de simetrie: cerc,
elips, ovoid) nu este greu de artat prin construire efectiv c exist un ptrat
ce se sprijin pe curb. Pare ns de nedovedit acelai fapt n cazul unor
curbe nchise foarte neregulate! Gsirea celor patru puncte, ntr-o astfel de
situaie, este de neimaginat fr ajutorul calculatorului!

Comentariu: o consecin surprinztoare a acestei conjecturi este faptul


c pe orice curb de nivel (curb din teren care unete punctele aflate toate la
aceai altitudine) am putea gsi patru puncte de sprijin pentru o platform
ptrat (un fel de mas) perfect orizontal, de mrime corespunztoare. Acest
fapt ar putea s explice ampla rspndire a meselor cu patru picioare (?!) n
detrimentul celor cu trei: dac i caui poziia, cu siguran o vei gsi i o vei
putea aeza pe toate cele patru picioare, astfel masa cu patru picioare va oferi o
perfect stabilitate i va sta perfect orizontal, pe cnd cea cu trei picioare dei
st acolo unde o pui din prima (chiar i nclinat) nu ofer aceeai stabilitate.
n sperana c am reuit s v strnim interesul pentru astfel de
probleme nesoluionate nc i care sunt grupate pe Internet n liste cuprinznd
zeci de astfel de exemple (vezi adresa oferit n ultimul capitol), ncheiem acest
capitol cu urmtoarea constatare: descoperirile deosebite din matematica
actual au efecte rapide i importante nu numai n matematic ci i n
informatic. S oferim doar un singur exemplu de mare interes actual:
algoritmii de ncriptare/decriptare cu cheie public, att de folosii n
comunicaia pe Internet, se bazeaz n ntregime pe proprietile matematice ale
divizibilitii numerelor prime.
Ceea ce este interesant i chiar senzaional este faptul c n informatic
nevoia de programe performante a condus la implementarea unor algoritmi care
se bazeaz pe cele mai noi descoperiri din matematic, chiar dac acestea sunt
nc n stadiul de conjecturi! De exemplu, pentru acelai domeniu al criptrii cu
cheie public exist deja algoritmi de primalitate senzaional de performani
care se bazeaz pe Ipoteza (conjectura) lui Riemman. (Mai multe amnunte
putei gsi la adresele de Internet pe care le oferim n ultimul capitol.)
Este acest fapt legitim? Ce ncredere putem avea n astfel de programe?
Dup prerea noastr putem acorda o total ncredere acestor algoritmi dar
numai n limitele orizontului atins de programele de verificare a conjecturii
folosite. Dac programul de verificare a verificat conjectura numeric pe
intervalul l- 1030 atunci orizontul ei de valabilitate este 1030. Domeniile
numerice pe care le pot acoperi calculatoarele actuale sunt oricum foarte mari
i implicit ofer o precizie suficient pentru cele mai multe calcule cu valori
extrase din realitatea fizic.
Probleme insolvabile algoritmic
Am introdus acest capitol special din dou motive. Primul motiv, pentru a
trezi interesul i pasiunea pentru informatic celor care pot acum s vad ct
de deosebite sunt descoperirile i rezultatele din acest domeniu. Al doilea motiv,
pentru ai pune n gard pe cei care, n entuziasmul lor exagerat, i nchipuie
c pot programa calculatorul s fac orice treab sau s rezolve orice problem.
Aa cum am vzut i n capitolul ce trateaz despre problemele dificile ale
informaticii, enunurile problemelor foarte dificile sau chiar insolvabile sunt
foarte simple i pot uor constitui o capcan pentru necunosctori.
n continuare vom oferi spre edificare doar cteva exemple, urmnd ca
prin studiul Complexitii algoritmilor i a dificultii problemelor s se
aprofundeze acest domeniu fascinant dar att de uor de confundat (poi s dai

de aceste probleme chiar i din greeal?!) i care este pcat s fie tratat ntrun mod superficial.
1. Problema Stopului. Nu exist un algoritm universal valabil prin care s
se poat decide dac execuia oricrui algoritm se oprete vreodat sau nu.
Comentariu: acesta este cel dinti i cel mai celebru exemplu de
problem insolvabil. Demonstraia riguroas a acestui fapt a fost dat pentru
prima dat n 1936 de inventatorul calculatorului actual matematicianul englez
Alan Mathison Turing. Odat existnd aceast demonstraie, multe din
urmtoarele probleme insolvabile algoritmic s-au redus la aceasta. Implicaiile
practice, teoretice i filosofice ale problemei Stopului sunt foarte importante
att pentru informatic ct i pentru matematic. Astfel, dou consecine
strategice ale problemei Stopului sunt: 1. Nu poate exista un calculator orict
de puternic cu ajutorul cruia s se poat decide asupra comportamentului
viitor al oricrui alt calculator de pe glob; 2. Nu poate s existe n matematic o
metod general de demonstrare inductiv-logic a propoziiilor matematice (se
nchide n acest fel o mai veche cutare a matematicienilor i logicienilor
cunoscut sub numele de Entscheidungs Problem sau Problema deciziei).
2. Problema ecuaiilor diofantice. Nu exist o metod general (un
algoritm) de aflare a soluiilor ntregi ale unui sistem de ecuaii diofantice.
Comentariu: sistemele de ecuaii diofantice sunt sistemele de ecuaii
algebrice de mai multe variabile cu coeficieni ntregi i crora li se caut soluii
ntregi. De exemplu, a fost nevoie de ajutorul calculatorului pentru a se
descoperi cea mai mic soluie a ecuaiei diofantice p4+q4+r4=s4 i care este
cvadrupletul p=95600, q=217519, r=414560, s=422461 (infirmndu-se n acest
fel conjectura lui Leonard Euler care n 1796 a presupus c aceast ecuaie
diofantic nu are soluii ntregi). Aceast problem ce cere o metod general de
rezolvare a ecuaiilor diofantice este cunoscut sub denumirea de Problema a
10-a a lui Hilbert.
3. Problema acoperirii planului (Problema pavajului sau Problema croirii).
Fiind dat o mulime de forme poligonale, nu exist o metod general (un
algoritm) care s decid dac cu aceste forme este posibil acoperirea complet
a planului (fr suprapuneri i goluri).
Comentariu: n practic este mult mai important problema croirii care
cere s se decupeze fr pierderi un set ct mai mare de forme date (croiuri)
dintr-o bucat iniial de material orict de mare. Este deasemenea demonstrat
c problema rmne insolvabil algoritmic chiar i atunci cnd formele
poligonale sunt reduse la poliomine (un fel de mozaicuri) care se formeaz
doar pe o reea rectangular caroiat. Iat cteva exemple de mulimi formate
dintr-o singur poliomin i, alturat, rspunsul la ntrebarea dac cu ele se
poate acoperi planul sau nu:
DA NU DA
4. Problema irurilor lui Post. Se dau dou mulimi egale de iruri finite
de simboluri ce sunt mperecheate astfel: un ir dintr-o mulime cu irul
corespunztor din a doua mulime. Nu exist un algoritm general prin care s
se decid dac exist o ordine de concatenare a irurilor (simultan din cele

dou mulimi) astfel nct cele dou iruri lungi pereche rezultate s fie
identice.
Comentariu: de exemplu, fie A= {101, 010, 00} i B= {010, 10, 001} cele
dou mulimi de iruri de simboluri (pentru uurin au fost alese simbolurile
binare 1 i 0). Perechile corespunztoare de iruri sunt 1. (101,010), 2. (010,10)
i 3. (00,001). Observm c irurile pereche pot avea lungimi diferite (ca n
perechile 2 i 3). n continuare, pentru a vedea cum se procedeaz, cele dou
iruri pereche rezultante prin concatenare le vom scrie unul deasupra celuilalt
sesiznd cum avanseaz procesul de egalizare a lor. Punctele sunt intercalate
doar pentru a evidenia perechile, ele nu contribuie la egalitate, iar comentariile
ne aparin:
Concatenarea poate ncepe doar cu
Obligatoriu urmeaz perechea l-a perechea a 3-a, 00 de sus 001 de
jos singura care ncepe cu 1 sus.
Dac am continua cu perechea
. Nu s-ar obine rezultatul final a 3-a.
001.010.10 oferit de perechea 2-a!
5. Problema cuvintelor egale. Se d un anumit numr de egaliti ntre
cuvinte. Bazndu-ne pe aceste egaliti se pot obine unele noi substituind
apariiile cuvintelor dintr-o parte a egalului cu cele din cealalt parte. Nu exist
un algoritm general de a decide dac un cuvnt oarecare A poate fi egal cu un
altul B.
Comentariu: de exemplu, fie urmtoarele cinci egaliti (citii-le n limba
englez) EAT=AT, AE=A, LATER=LOW, PAN=PILLOW i CARP=ME. Este
CATERPILLAR egal cu MAN? Iat irul egalitilor iterate care ne poate oferi
rspunsul: CATERPILLAR = CARPILLAR =CARPILLATER =CARPILLOW=
CARPAN= MEAN= MEATEN= MATEN= MAN.
Dar de la CARPET putem ajunge la MEAT? ntruct se vede c numrul
total de A-uri plus W-uri i M-uri nu se poate modifica prin nici o substituie i
ntruct CARPET are un A (adic numrul asociat este 1) iar MEAT are un A i
un M (deci 2), rezult c aceast egalitate nu este permis.
Mai mult, se tie c exist liste particulare de cuvinte pentru care nu
poate exista un algoritm ce decide dac dou cuvinte sunt egale sau nu. Iat o
astfel de list de apte egaliti: AH=HA, OH=HO, AT=TA, OT=TO, TAI=IT,
HOI=H i THAT=ITHT.
Numrul problemelor cunoscute ca fiind insolvabile algoritmic este destul
de mare. Cele mai multe probleme provin din matematic, subdomeniul
matematicii care studiaz aceste probleme se numete Matematica nerecursiv.
De aceea ele pot fi ntlnite mai ales sub numele de probleme nedecidabile sau
probleme nerecursive, n enunul lor cuvntul algoritm fiind nlocuit mai ales
cu cuvintele metod general.
Studierea acestui domeniu a creat condiii pentru apariia de noi direcii
de cercetare prin care se ncearc explicarea raionamentelor matematice ba
chiar se ncearc descoperirea limitelor raiunii umane n general. Unii oameni
de tiin contemporani, cum este celebrul matematician-fizician englez Roger
Penrose, depun eforturi mari pentru a oferi o demonstraie matematic

riguroas pentru ipoteza c, n cele din urm i n esen, raionamentele


umane nu sunt algoritmice, nici mcar cele matematice. Dup prera lui
Penrose mintea uman nu poate fi asimilat cu un calculator ci este mai mult
dect att i nu vor putea exista vreodat calculatoare sau roboi mai inteligeni
dect oamenii! n ultimul capitol oferim titlurile crilor recent aprute ce
trateaz despre acest fascinant subiect.
Noiuni aprofundate de programare
Metode i strategii de proiectare a algoritmilor (alias tehnici de programare)
n rezolvarea sa cu ajutorul calculatorului orice problem trece prin trei
etape obligatorii: Analiza problemei, Proiectarea algoritmului de soluionare i
Implementarea algoritmului ntr-un program pe calculator. n ultima etap, sub
acelai nume, au fost incluse n plus dou subetape cunoscute sub numele de
Testarea i ntreinerea programului. Aceste subetape nu lipsesc din ciclul de
via a oricrui produs-program ce se respect dar, pentru simplificare, n
continuare ne vom referi doar la cele trei mari etape.
Dac etapa implementrii algoritmului ntr-un program executabil este o
etap exclusiv practic, realizat n faa calculatorului, celelalte dou etape
au un caracter teoretic pronunat. n consecin, primele dou etape sunt
caracterizate de un anumit grad de abstractizare. Din punct de vedere practic i
n ultim instan criteriul decisiv ce confer succesul rezolvrii problemei este
dat de calitatea implementrii propriuzise. Mai precis, succesul soluionrii este
dat de performanele programului: utilitate, vitez, fiabilitate, manevrabilitate,
lizibilitate, etc. Este imatur i neprofesional strategia programatorilor
nceptori care neglijnd primele dou etape sar direct la a treia, fugind de
analiz i de componenta abstract a efortului de soluionare. Ei ofer cu toii
aceeai justificare: Eu nu vreau s mai pierd vremea cu., am s fac programul
cum tiu eu. Pn cnd nu o s fac cineva altul mai bun dect al meu, pn
atuncI. Nu am cu cine sta de vorb!.
Este adevrat c ultima etap n rezolvarea unei probleme
implementarea este ntr-adevr decisiv i doveditoare, dar primele dou
etape au o importan capital. Ele sunt singurele ce pot oferi rspunsuri la
urmtoarele ntrebri dificile: Avem certitudinea c soluia gsit este corect?
Avem certitudinea c problema este complet rezolvat? Ct de eficient este
soluia gsit? Ct de departe este soluia aleas de o soluie optim?
S menionm n plus c literatura de specialitate conine un numr
impresionant de probleme capcan pentru nceptori i nu numai. Ele sunt
toate inspirate din realitatea imediat dar pentru fiecare dintre ele nu se cunosc
soluii eficiente n toat literatura de profil. Exist printre ele chiar unele
probleme extrem de dificile pentru care s-a demonstrat riguros c nu admit
soluie cu ajutorul calculatorului. (Mai precis, s-a demonstrat c ele nu admit
soluie prin metode algoritmice, n spiritul tezei Turing-Church). Ci dintre
programatorii nceptori n-ar fi surprini s afle c problema att de simpl
(ca enun) a crei soluionare tocmai au abandonat-o este de fapt o problem
dovedit ca fiind intratabil sau chiar insolvabil algoritmic? Partea proast a
lucrurilor este c, aa cum ciupercile otrvite nu pot fi cu uurin deosebite de

cele comestibile, tot astfel problemele netratabile pot fi cu uurin confundate


cu nite probleme uoare la o privire rapid i lipsit de experien.
S nelegem mai nti care este cheia ce conduce la rspunsuri pentru
ntrebrile de mai sus iar apoi vom trece la prezentarea metodelor clasice de
proiectare a soluiilor. Aceste metode de proiectare a algoritmilor-soluie sunt
cunoscute n literatura de specialitate sub numele de tehnici de programare i
sunt considerate metode sau instrumente soft eficiente i cu arie larg de
aciune.
Dac ar fi s sintetizm n cte un cuvnt efortul asupra cruia se
concentreaz fiecare din primele dou etape analiza i proiectarea acestea ar
fi: corectitudine i eficien. Etapa de analiz este singura care permite
dovedirea cu argumente riguroase a corectitudinii soluiei, iar etapa de
proiectare este singura care poate oferi argumente precise n favoarea eficienei
soluiei propuse.
n general problemele de informatic au n forma lor iniial sau n enun
o caracteristic pragmatic. Ele sunt foarte ancorate n realitatea imediat i
aceasta le confer o anumit asemnare. Totui ele au n forma iniial un grad
mare de eterogenitate, diversitate i lips de rigoare. Fiecare dintre aceste
atribute negative este un obstacol major pentru demonstrarea corectitudinii
soluiei. Rolul esenial al etapei de analiz este deci acela de a transfera
problema de pe nisipurile mictoare ale realitii imediate de unde ea provine
ntr-un plan abstract, adic de a o modela. Acest univers paralel este dotat cu
mai mult rigoare i disciplin intern, avnd legi precise i poate oferi
instrumentele logice i formale necesare pentru demonstrarea riguroas a
corectitudinii soluiei problemei.
Planul abstract n care sunt transportate toate problemele este planul
sau universul obiectelor matematice. Acest univers al matematicii este unanim
acceptat (de ce?!) iar corespondentul problemei n acest plan va fi modelul
matematic abstract asociat problemei. Demonstrarea corectitudinii
proprietilor ce leag obiectele universului matematic a fost i este sarcina
matematicienilor. Celui ce analizeaz problema din punct de vedere informatic
i revine sarcina (nu tocmai uoar) de a dovedi printr-o demonstraie
constructiv c exist o coresponden precis (bijectiv) ntre prile
componente ale problemei reale, dezasamblat n timpul analizei i prile
componente ale modelului abstract asociat. Odat descoperit, formulat precis
i dovedit, aceast perfect oglindire a problemei reale n planul obiectelor
matematice ofer certitudinea c toate proprietile i legturile ce exist ntre
subansamblele modelului abstract se vor regsii precis (prin reflectare) ntre
prile interne ale problemei reale i invers. Atunci, soluiei abstracte
descoperit cu ajutorul modelului matematic abstract i va corespunde o soluie
real concretizat printr-un algoritm ce poate fi implementat ntr-un program
executabil.
Aceasta este calea general de rezolvare a problemelor i orice poate
verifica. Ca i exerciiu, s se demonstreze corectitudinea (s se aduc
argumente precise, clare i convingtoare n favoarea corectitudinii) metodei de
extragere a radicalului nvat nc din coala primar sau a algoritmului lui

Euclid de determinare a celui mai mare divizor comun a dou numere prin
mpriri ntregi repetate. Argumentele elevilor de forma: Este corect pentru c
aa ne-a nvat doamna profesoar! sau Este corect pentru c aa face toat
lumea! sunt normale att timp ct nu li se ofer o argumentaie matematic
riguroas.
Ideea central a etapei a doua proiectarea uni algoritm de soluionare
eficient poate fi formulat astfel: din studiul proprietilor i limitelor modelului
matematic abstract asociat problemei se deduc limitele inferioare ale
complexitii minimale (efortului minimal obligatoriu) inerente oricrui
algoritm ce va soluiona problema n cauz. Complexitatea intern a modelului
abstract i complexitatea soluiei abstracte se va reflecta imediat asupra
complexitii reale a algoritmului, adic asupra eficienei, de soluionare a
problemei. Acest fapt permite prognosticarea nc din aceast faz faza de
proiectare a algoritmului de soluionare a eficienei practice, msurabil ca
durat de execuie, a programului.
Aceast coresponden exact ntre complexitatea modelului abstract i
complexitatea algoritmului de soluionare ofer cheia unor demonstraii
riguroase a imposibilitii existenei soluiei prin metode algoritmice pentru o
list ntreag de probleme (cum ar fi de exemplu Problema a 10-a a lui Hilbert,
formulat nc din 1900).
Detailnd cele prezentate deja, vom construi n continuare cadrul teoretic
general pentru nelegerea strategiilor de proiectare a algoritmilor.
Creterea impresionant a puterii de calcul a calculatoarelor i-a obligat
pe informaticienii ultimilor treizeci de ani s nu se mai eschiveze de la
abordarea problemelor dificile cu caracter algoritmic din diverse domenii care
au intrat n atenia matematicienilor nc de la nceputul acestui secol. De
altfel, astfel de probleme cu soluii algoritmice nu constituiau neaprat o
noutate pentru matematicienii nceputului de secolul. nc de pe vremea lui
Newton matematicienii i-au pus, de exemplu, problema descoperirii unor
metode precise (adic algoritmi!) de determinare n pai de aproximare
succesiv a soluiei unei ecuaii ce nu poate fi rezolvat prin radicali. Dar
boom-ul dezvoltrii tehnicii de calcul din a doua jumtate a secolului a creat
posibilitatea abordrii unor probleme cheie pentru anumite domenii strategice
(de exemplu, controlul i dirijarea sateliilor pe orbit, probleme de planificare
sau optimizare n economie, etc.) care se reduc n fapt la soluionarea eficient
a unor probleme de optimizare matematic prin metode iterative (algoritmi).
Spre deosebire de aceste probleme a cror succes n soluionare a fost
total i cu consecinele ce se vd, exist ns o serie de probleme dificile
inspirate din realitate care se cer imperios rezolvate eficient cu ajutorul
calculatorului.
Principal caracteristic a acestora este c, datorit generalitii lor sau
datorit dificultii ascunse, n literatura de specialitate nu exist metode
iterative eficiente de rezolvare a lor i nu se tie dac ele admit astfel de soluii.
Singurul fapt ce poate fi stabilit dinainte n cazul soluionrii unor astfel de
probleme este spaiul n care soluia trebuie cutat. Ceea ce trebuie atunci

construit este o strategie corect i ct mai general de cutare a soluiei


(soluiilor) n acel spaiu de cutare a soluiilor.
Exemplu concret: exist o clas ntreag de probleme ce cer implicit s se
genereze toate obiectele unei mulimi (cum ar fi problema generrii tuturor
permutrilor unei mulimi cu n elemente). n acest caz este cunoscut dinainte
proprietatea ce trebuie s o ndeplineasc fiecare soluie ca s fie un obiect al
spaiului de cutare a soluiilor. Efortul de soluionare va fi redus atunci la
aflarea, cutarea sau generarea pe baza proprietii respective a tuturor
obiectelor posibile, fr ns a lsa vreunul pe dinafar.
Modelul matematic abstract cel mai general care permite modelarea
acestui tip de probleme este graful. Un graf este un obiect matematic riguros
care, simplificat, poate fi privit ca fiind o diagram format din noduri unite
prin sgei (muchii). De exemplu, orice hart feroviar sau rutier poate fi
privit ca un graf cu mulimea nodurilor format din localiti iar mulimea
muchiilor format din rutele de transport directe dintre localitile respective.
Graful permite descrierea legturilor i a relaiilor ce exist ntre diferite obiecte
abstracte reprezentate prin noduri. Experiena arat c acest model matematic
abstract este cel mai general i cel mai potrivit pentru descrierea unui spaiu de
cutare a soluiilor unei probleme. n cazul spaiului de cutare, nodurile sunt
soluiile posibile (ipotetice). Dou noduri n graf vor fi unite prin sgei (muchii)
dac cele dou soluii posibile au n comun o aceeai proprietate. Muchiile
grafului sunt punile ce vor permite algoritmului trecerea de la un nod la
altul, de la o soluie ipotetic la alta, n timpul procesului de cutare a soluiei
(sau a tuturor soluiilor). Rezult c strategiile cele mai generale de cutare a
soluiei (soluiilor) pe modelul abstract asociat problemei sunt reductibile la
metodele generale de traversare a unui graf.
Ordinea de traversare a grafului determin precis arborele de traversare a
grafului. Acest arbore este de fapt un subgraf particular al grafului iniial,
avnd acelai numr de noduri i ca rdcin vrful iniial de pornire. Cele
dou metode clasice de traversare a unui graf (cutare ntr-un graf) poart n
literatura de specialitate numele: BreathFirstsearch (BFS) i DepthFirstsearch
(DFS), respectiv Traversarea n lime (sau traversarea pe nivele) i Traversarea
n adncime (traversarea labirintic) a grafului. Ambele metode stau la baza
celei mai cunoscute strategii de proiectare a algoritmilor (impropriu denumit
tehnic de programare): BackTracking respectiv cutare (traversare) n spaiul
de cutare a soluiilor (a grafului) cu revenire pe urma lsat.
Iat un exemplu de graf (7 noduri i 10 arce-sgei) i ordinea sa de
traversare prin cele dou metode:
Ordinea de parcurgere a celor 7 vrfuri ale grafului, innd cont i de
sensul dat de sgei, este n cazul DFS (n adncime): 1,2,4,5,6,3,7 aa cum se
vede din arborele parcurgerii n adncime. Din fiecare nod se continu cu nodul
(nevizitat nc) dat de prima alegere posibil: de exemplu, din 4 se continu cu
5 (ales n favoarea lui 7). Se poate observa cum din nodul 3, nemaiexistnd
continuare, are loc o revenire pe pista lsat pn n nodul 6 de unde se
continu parcurgerea n adncime cu prima alegere posibil. n cazul BFS (n
lime) ordinea de traversare este: 1,2,3,4,5,7,6 aa cum se poate vedea n

arborele parcurgerii n lime. n aceast situaie, dintr-un nod sunt vizitai toi
vecinii (nevizitai nc), iar apoi se face repet acelai lucru pentru fiecare nod
vecin, n ordinea vizitrii. Se observ cum nodul 7 este vizitat naintea nodului
6, fiind vecin cu nodul 4. (De fapt, aceasta se explic prin faptul c distana de
la 1 la 7 este mai mic cu o unitate dect distana de la 1 la 6.) Putem spune c
n cazul traversrii n lime ordinea de traversare este dat de deprtarea
nodurilor fa de nodul de start.
Iat cum arat procedura general DepthFirstsearch (DFS) de traversare
a unui graf descris n pseudo-cod n varianta recursiv:
Procedura DFS (v: nod);
Viziteaz v;
Marcheaz v; /v devine un nod vizitat/
Ct timp (exist w nemarcat nod adiacent lui v) execut DFS (w);
S nu uitm c aceast procedur poate fi privit ca scheletul pe care
se construiete orice procedur backtracking recursiv.
BackTracking.
Pentru a preciza mai exact n ce const aceast metod, vom relua pe un
exemplu concret cele spuse deja. Avem urmtoarea problem: se cere generarea
tuturor permutrilor unei mulimi de n elemente ce nu conin elementul x (dat
dinainte) pe primele dou poziii. Conform celor afirmate, este suficient s
construim modelul abstract graful (mai precis arborele) tuturor
permutrilor celor n elemente. Apoi, printr-o parcurgere exhaustiv a nodurilor
sale, prin una din metodele BFS sau DFS, s pstrm numai acele noduri ce
verific n momentul vizitrii condiia impus (lipsa lui x de pe primele dou
poziii).
Observm c aceast metod necesit folosirea n scopul memorrii
dinamice a drumului parcurs (n timpul cutrii soluiei) a mecanismului de
stiv, fapt sugerat chiar de numele ei: tracking, adic nregistrarea pistei
parcurse. Acest mecanism de stiv, care permite att memorarea pistei ct i
revenirea back-tracking-ul, este unul din mecanismele de baz ce este folosit
pe scar larg n procedurile de gestiune dinamic a datelor n memorie. n
plus, exist unele cazuri particulare de probleme n care soluia cutat se
obine n final prin vrsarea ntregului coninut al stivei i nu doar prin
nodul ultim vizitat, aflat n vrful stivei.
Exemplul cel mai potrivit de problem ce necesit o strategie de rezolvare
backtracking este Problema Labirintului: se cere s se indice, pentru o
configuraie labirintic dat, traseul ce conduce ctre ieirea din labirint. Iat
un exemplu sugestiv:
L
15
Observai cum, dup 15 pai, este necesar o revenire (backtracking)
pn la csua 6, de unde se continu pe o alt pist. Pista fals a fost
memorat n stiv, element cu element, iar revenirea se va realiza prin
eliminarea din stiv tot element cu element. Cnd n vrful stivei reapare
csua cu numrul 6, stiva ncepe din nou s creasc memornd elementele

noului drum. n final stiva conine n ntregime soluia: drumul corect ctre
ieirea din labirint.
J
n consecin, indiferent de forma particular ce o poate lua sau de
modul n care este citit n final soluia, esenialul const n faptul c
backtracking-ul este o metod de programare ce conine obligatoriu gestiune de
stiv. Lipsa instruciunilor, explicite sau transparente, de gestionare a stivei
ntr-un program (de exemplu, lipsa apelului recursiv), este un indiciu sigur de
recunoatere a faptului c acel algoritm nu folosete metoda sau strategia de
rezolvare BackTracking.
Tot o metod back-tracking este i metoda de programare cunoscut sub
numele programare recursiv. Ea este mai utilizat dect metoda clasic
BackTracking, fiind mai economicoas din punctul de vedere al minimizrii
efortului de programare. Aceast metod se reduce la construirea, n mod
transparent pentru programator, a arborelui apelurilor recursive, traversarea
acestuia prin apelarea recursiv (repetat) i efectuarea aciunilor
corespunztoare n momentul vizitrii fiecrui nod al arborelui. Apelarea
recursiv constituie motorul vehiculului de traversare i are doar rolul de a
permite traversarea arborelui. Gestionarea stivei apelurilor recursive i
revenirea back-tracking-ul rmne n sarcina mediului de programare folosit
i se efectueaz ntr-un mod mascat pentru programator. Din acest punct de
vedere, programatorului i revine sarcina scrierii corecte a instruciunii de apel
recursiv i a instruciunii ce scurt-circuiteaz bucla infinit a apelurilor
recursive. Singurele instruciuni care fac treab, n sensul rezolvrii
propriuzise a problemei respective, sunt cele cuprinse n corpul procedurii.
De exemplu, iat cum arat n limbajul de programare Pascal procedura
general de generare a permutrilor n varianta recursiv i arborele de
generare a permutrilor mulimii {1,2,3} (n=3), pe nivele:
Procedure Permut (k: byte; s: string); {k nivelul n arbore, s irul}
Var i: byte; tmp: char;
Begin
If k=n then begin {scurt-circuitarea recursivitii}
For i: =1 to n do Write (s [i]); {prin afiarea permutrii}
Write (;); {urmat de un punct-virgul} end else
For i: =k to n do begin {singurele instruciuni ce fac treab} tmp: =s [i]; s
[i]: =s [k]; s [k]: =tmp; {sunt for-ul i cele trei atribuiri}
Permut (k+1, s); {apelul recursiv ce permite parcugerea} end; {arboR. De
generare a celor n! Permutri}
End;
Nivelele arborelui (rsturnat pe orizontal)
Fiecare nivel al arborelui corespunde unei poziii n irul permutrilor.
Astfel, pe prima
2 poziie (nivelul 1) pot fi oricare din cele trei elemente: 1, 2, 3. Pe poziia
urmtoare pot
3 fi oricare din celelalte dou elemente rmase: 2, 3; 1, 3; 1, 2. Pe al
treilea nivel i ultimul

Start 2 <
1 vor fi numai elementele rmase (cte unul). Generarea permutrilor
const n construirea
\par
2 i parcurgerea arborelui permutrilor: odat ajuni cu parcurgerea la
un capt din dreapta
1 vom afia de fiecare dat drumul de la rdcin la frunza
terminal.
Observm c arborele permutrilor este identic cu arborele apelurilor
recursive i c controlul i gestiunea stivei se face automat, transparent fa de
programator. Instruciunilor de control (din background) le revine sarcina de a
pstra i de a memora, de la un apel recursiv la altul, string-ul s ce conine
permutrile. Dei aceast procedur recursiv de generare a permutrilor pare o
variant de procedur simpl din punctul de vedere al programatorului, n
realitate, ea conine ntr-un mod ascuns efortul de gestionare a stivei:
ncrcarea-descrcarea stringului s i a ntregului k. Acest efort este preluat n
ntregime de instruciunile incluse automat de mediul de programare pentru
realizarea recursivitii.
Avantajul metodei back-tracking este faptul c efortul programatorului se
reduce la doar trei sarcini:
1. construirea grafului particular de cutare a soluiilor
2. Adaptarea corespunztoare a uneia din metodele generale de
traversare-vizitare a grafului n situaia respectiv (de exemplu, prin apel
recursiv)
3. Adugarea instruciunilor ce fac treab care, fiind apelate n mod
repetat n timpul vizitrii nodurilor (grafului soluiilor posibile), rezolv gradat
problema, gsind sau construind soluia.
Aciunea de revenire ce d numele metodei, backtracking revenire pe
pista lsat, este inclus i este efectuat de subalgoritmul de traversare a
grafului soluiilor posibile. Acest subalgoritm are un caracter general i face
parte din zestrea oricrui programator. n cazul particular n care graful
soluiilor este arbore, atunci se poate aplica ntotdeauna cu succes metoda
programrii recursive care conduce la un cod-program redus i compact.
Prezentm din nou procedura general DepthFirstsearch (DFS) de
traversare a unui graf n varianta recursiv (ce construiete de fapt arborele
de traversare a grafului avnd ca rdcin nodul de pornire) pentru a pune n
eviden cele spuse.
Procedura DFS (v: nod);
Viziteaz v; {aici vor fi acele instruciuni care fac treab}
Marcheaz v; /v devine un nod vizitat/ {poate s lipseasc n anumite
implementri}
Ct timp (exist w nemarcat nod adiacent lui v) execut DFS (w); {apelul
recursiv este motorul vehiculului}
{ce permite parcurgerea grafului i gestiunea stivei de revenire}
Exist situaii n care, la unele probleme, putem ntlni soluii tipbacktracking fr ns a se putea sesiza la prima vedere prezena grafului de

cutare asociat i aciunea de traversare a acestuia, ci doar prezena stivei. O


privire mai atent ns va conduce obligatoriu la descoperirea arborelui de
cutare pe graful soluiilor, chiar dac el exist doar ntr-o form mascat.
Acest fapt este inevitabil i constituie esena metodei cutare (generare) cu
revenire pe pista lsat.
Back-tracking-ul, metod general i cu o larg aplicabilitate, fiind
reductibil n ultim instan la traversarea spaiului grafului de cutarea
soluiilor, are marele avantaj c determin cu certitudine toate soluiile posibile,
cu condiia ca graful asociat de cutare a soluiilor s fie corect. Dar ea are
marele dezavantaj c necesit un timp de execuie direct proporional cu
numrul nodurilor grafului de cutare asociat (sau numrul cazurilor posibile).
n cele mai multe cazuri acest numr este exponenial (en) sau chiar mai mare,
factorial (n!), unde n este dimensiunea vectorului datelor de intrare. Acest fapt
conduce la o durat de execuie de mrime astronomic fcnd ntr-un astfel
de caz algoritmul complet inutilizabil, chiar dac el este corect teoretic. (De
exemplu, dac soluionarea problemei ar necesita generarea tuturor celor 100!
Permutri (n=100), timpul de execuie al algoritmului depete orice
imaginaie.) n astfel de situaii, n care dimensiunea spaiului de cutaregenerare a soluiilor are o astfel de dependen n funcie de n (fiind o funcie
de ordin mai mare dect funcia polinomial), este absolut necesar
mbuntirea acestei metode sau nlocuirea ei. Nu este ns necesar (i de
multe ori nici nu este posibil!) abandonarea modelului abstract asociat
graful soluiilor posibile, cu calitile i proprietile sale certe ci este necesar
doar obinerea unei durate de execuie de un ordin de mrime inferior printr-o
alt strategie de parcurgere a spaiului de cutare.
Greedy.
n strategia backtracking cutarea soluiei, adic vizitarea secvenial a
nodurilor grafului soluiilor cu revenire pe urma lsat, se face oarecum
orbete sau rigid, dup o regul simpl care s poat fi rapid aplicat n
momentul prsirii unui nod vizitat. n cazul metodei (strategiei) greedy apare
suplimentar ideea de a efectua n acel moment o alegere. Dintre toate nodurile
urmtoare posibile de a fi vizitate sau dintre toi paii urmtori posibili, se alege
acel nod sau pas care asigur un maximum de ctig, de unde i numele
metodei: greedy = lacom. Evident c n acest fel poate s scad viteza de vizitare
a nodurilor adic a soluiilor ipotetice sau a soluiilor pariale prin
adugarea duratei de execuie a subalgoritmului de alegere a urmtorului nod
dup fiecare vizitare a unui nod. Exist ns numeroi algoritmi de tip greedy
veritabili care nu conin subalgoritmi de alegere. Asta nu nseamn c au
renunat la alegerea greedy ci, datorit scurtturii descoperite n timpul etapei
de analiz a problemei, acei algoritmi efectueaz la fiecare pas o alegere fr
efort i n mod optim a pasului (nodului) urmtor. Aceast alegere, dedus n
etapa de analiz, conduce la maximum de profit pentru fiecare pas i
scurteaz la maximum drumul ctre soluia cutat.
Aparent aceast metod de cutare a soluiei este cea mai eficient, din
moment ce la fiecare pas se trece dintr-un optim (parial) ntr-altul. Totui, ea
nu poate fi aplicat n general ci doar n cazul n care exist certitudinea

alegerii optime la fiecare pas, certitudine rezultat n urma etapei anterioare de


analiz a problemei. Ori, dezavantajul este c, la majoritatea problemelor
dificile, etapa de analiz nu poate oferi o astfel de pist optim ctre soluie.
Un alt dezavantaj al acestei strategii este c nu poate s conduc ctre toate
soluiile posibile ci doar ctre soluia optim (din punct de vedere a alegerii
efectuate n timpul cutrii soluiei), dar poate oferi toate soluiile optime
echivalente.
Programarea dinamic.
Este o metod sau strategie ce i propune s elimine dezavantajele
metodei recursive care, n ultim instan, am vzut c se reduce la
parcurgerea n adncime a arborelui apelurilor recursive (adic backtracking).
Aceast metod se apropie ca idee strategic de metoda Greedy, avnd ns
unele particulariti.
Pentru a o nelege este necesar evidenierea dezavantajului major al
recursivitii. El const din creterea exagerat i nerentabil a efortului de
execuie prin repetarea ineficient a unor pai. Urmrind arborele apelurilor
recursive se observ repetarea inutil a unor cazuri rezolvate anterior, calculate
deja nainte pe alt ramur a arborelui. Metod eminamente iterativ,
programarea dinamic elimin acest dezavantaj prin rsturnarea procedeului
de obinere a soluiei i implicit a arborelui apelurilor recursive. Printr-o
abordare bottom-up (de la baz spre vrf) ea reuete s elimine operaiile
repetate inutil n cazul abordrii top-down (de la vrf spre baz).
Cu toii am nvat c, dac vrem s calculm cu mna o combinare
sau un tabel al combinrilor, n loc s calculm de fiecare dat combinri de n
luate cte k pe baza definiiei recursive: C (n, k) =C (n-l, k-l)+C (n-l, k) cnd n,
k>0, sau, C (n, k) =1 cnd k=0 sau n=k, este mult mai eficient s construim
Triunghiul lui Pascal, pornind de la aceeai definiie a combinrilor.
C (4,2)
C (3,1) + C (3,2)
C (2,0) + C (2,1) C (2,1) + C (2,2)
1 C (1,0) + C (1,1) C (1,0) + C (1,1) 1
Observai cum n arborele apelurilor recursive apar apeluri n mod
repetat pentru calculul aceleai combinri. Acest efort repetat este evitat prin
calcularea triunghiului lui Pascal n care fiecare combinare va fi calculat o
singur dat.
n mod asemntor, aceeai diferen de abordare va exista ntre doi
algoritmi de soluionare a aceleai probleme, unul recursiv backtracking i
altul iterativ proiectat prin metoda programrii dinamice.
Dezavantajele acestei metode provin din faptul c, pentru a ine minte
paii gata calculai i a evita repetarea calculrii lor (n termeni de grafuri,
pentru a evita calcularea repetat a unor noduri pe ramuri diferite ale arborelui
apelurilor recursive), este nevoie de punerea la dispoziie a extra-spaiului de
memorare necesar i de un efort suplimentar dat de gestiunea de memorie
suplimentar.
Branch & Bound.

Este strategia cea mai sofisticat de proiectare a algoritmilor. Ea a aprut


datorit existenei problemelor pentru care soluia de tip backtracking poate
necesita un timp astronomic de rulare a programului. n rezolvarea acestor
probleme apare o asemenea penurie de informaii nct modelul abstract
asociat problemei graful de cutare a soluiilor nu poate fi precizat n avans,
din etapa de analiz. Singura soluie care rmne este includerea unui
subalgoritm suplimentar ce permite construirea acestui graf pe parcurs, din
aproape n aproape. Apariia acelui subalgoritm suplimentar d numele
metodei: branch&bound.
Este posibil compararea algoritmului branch&bound cu un robot ce
nva s se deplaseze singur i eficient printr-un labirint. Acel robot va fi
obligat s-i construiasc n paralel cu cutarea ieirii o hart (un graf!) a
labirintului pe care va aplica apoi, pas cu pas, metode eficiente de obinere a
drumului cel mai scurt.
La strategia de cutare a soluiei n spaiul (graful) de cutare
backtracking, fiecare pas urma automat unul dup altul pe baza unei reguli
ncorporate, n timp ce la strategia greedy alegerea pasului urmtor era fcut
pe baza celei mai bune alegeri. n cazul acestei strategii branch&bound,
pentru pasul urmtor algoritmul nu mai este capabil s fac vreo alegere
pentru c este obligat mai nti s-i determine singur nodurile vecine ce pot fi
vizitate. Numele metodei, branch=ramific i bound=delimiteaz, provine de la
cele dou aciuni ce in locul aciunii de alegere de la strategia Greedy. Prima
aciune este construirea sau determinarea prin ramificare a drumurilor de
continuare, iar a doua este eliminarea continurilor (ramurilor) ineficiente sau
eronate. Prin eliminarea unor ramuri, poriuni ntregi ale spaiului de cutare a
soluiei rmnnd astfel dintr-o dat delimitate i izolate. Aceast strategie de
delimitare din mers a anumitor regiuni ale spaiului de cutare a soluiilor
este cea care permite reducerea ordinului de mrime a acestui spaiu. Soluia
aceasta este eficient doar dac ctigul oferit prin reducerea spaiului de
cutare (scznd efortul suplimentar depus pentru determinarea i eliminarea
din mers a continurilor ineficiente) este substanial.
Soluiile de tip backtracking, avnd la baz un schelet att de general
(algoritmul de traversare a grafului de cutare a soluiilor) sunt relativ simplu
de adaptat n rezolvarea unor probleme. Poate acesta este motivul care a
condus pe unii programatori lipsii de experien la convingerea fals c Orice
este posibil de rezolvat prin backtracking.
La ora actual, lista problemelor pentru care nu se cunosc dect soluii
exponeniale, total nerezonabile ca durat de execuie a programului de
soluionare, cuprinde cteva sute de probleme, una mai celebr ca cealalt.
Reamintim doar de banala (dar agasanta) Problem a Orarului unei instituii
de nvmnt care nu admite o soluie backtracking datorit duratei
astronomice de ateptare a soluiei.
Datorit totalei lor ineficiene n execuie, soluiile backtracking obinute
dup o analiz i o proiectare la prima mn (brute-force approach, n limba
englez) ajung s fie reanalizate din nou cu mai mult atenie. Se constat
atunci c modelul abstract asociat problemei, fie este prea srac n informaii

pentru determinarea grafului de cutare a soluiilor, fie conduce la un graf de


cutare avnd dimensiunea nerezonabil (exponenial sau factorial, fa de
dimensiunea n a vectorului de intrare). Singura soluie care rmne n aceast
situaie la dispoziie este ca aceste soluii s fie reproiectate prin metoda
branch&bound.
Un exemplu uor de neles de problem branch&bound l ofer
Problema General a Labirintului. Spre deosebire de Problema Labirintului
prezentat anterior (care admitea o soluie de tip backtracking), n varianta
extins a acestei probleme, numrul direciilor posibile de urmat la fiecare pas
poate fi orict de mare, iar obstacolele pot avea orice form i dimensiune. n
acest caz, singura posibilitate este construirea din mers a spaiului de cutare
a soluiei. Astfel, pentru determinarea unui drum de ieire din labirint sau a
drumului cel mai scurt (dac este posibil determinarea acestuia n timp
rezonabil!) este obligatorie adoptarea strategiei branch&bound.
Oferim n continuare o situaie concret, ilustrat. Sesizai c obstacolele,
avnd forme i dimensiuni diferite, nu pot fi ocolite dect pe un traseu razant
sau pe un traseu ce urmeaz contorul exterior al acestora. Acest fapt complic
mult problema i impune luarea unor decizii la faa locului, n momentul
ntlnirii i ocolirii fiecrui obstacol, ceea ce impune o strategie de rezolvare de
tip branch&bound ramific i delimiteaz:
Jnl
&u
Dei aceast strategie poate s creasc uneori surprinztor de mult
eficiena algoritmilor de soluionare (din nerezonabili ca timp de execuie ei pot
ajunge rezonabili, datorit reducerii dimensiunii exponeniale a spaiului de
cutare a soluiei), aplicarea ei este posibil doar printr-un efort suplimentar n
etapa de analiz i n cea de proiectare a algoritmului. Dezavantajul major al
acestei metode const deci n efortul major depus n etapa de analiz a
problemei (analiz care ns se va face o singur dat i bine!) i efortul
suplimentar depus n etapa proiectrii algoritmului de soluionare.
Din experiena practic este cunoscut faptul c, pentru a analiza o
problem dificil un analist poate avea nevoie de sptmni sau chiar luni de
zile de analiz, n timp ce algoritmul de soluionare proiectat va dura, ca timp
de execuie, doar cteva zeci de minute. Dac programul obinut nu este
necesar a fi rulat dect o dat, aceasta este prea puin pentru a se amortiza
costul mare al analizei i proiectrii sale. n acea situaie, soluia
branch&bound este nerentabil i, probabil c ar fi mai ieftin strategia
backtracking de soluionare, chiar i cu riscul de a obine o execuie (singura
de altfel) a programului cu durata de o sptmn (ceea ce poate s nsemne
totui economie de timp).
Recursivitatea
Aa cum am amintit deja, aceast metod de programare poate fi privit
ca form particular de exprimare a metodei Back-Tracking. Cu toate acestea,
cei ce cunosc istoria informaticii i originile programrii tiu c aceast metod
are totui un caracter special. Aceste lucruri dorim s le evideniem n
continuare.

nc nainte de apariia primului calculator i, deci implicit a oricrei


tehnici de programare, unii matematicieni erau profund preocupai de noiunea
de calculabilitate. Aceast noiune i putea ajuta n efortul lor deosebit de a
fundamenta noiunea elementar de algoritm sau metod automat de calcul.
n paralel, cele mai valoroase rezultate le-au obinut latino-americanul Alonso
Church i englezul Alan Turing. n timp ce Turing a introdus pentru algoritm
modelul matematic abstract cunoscut sub numele de Maina Turing (care st
la bazele modelului actual de calculator), Church a fundamentat noiunea de
metod de calcul sau calculabilitatea pe funciile recursive. Astfel, teza lui
Church afirma c orice funcie definit pe domeniul numerelor naturale este
calculabil dac i numai dac ea este recursiv. Dei aparatul teoretic folosit
de Church era n ntregime matematic (se baza numai pe funcii numerice
naturale), lui nu i-a fost greu s demonstreze c orice algoritm nenumeric se
reduce la funcii recursive i la mulimi recursive de numere naturale (pe baza
unor codificri riguros alese).
Acest din urm rezultat este cel care ne intereseaz pe noi i noi l vom
reformula fr ai afecta valabilitatea: orice algoritm poate fi rescris printr-un
algoritm recursiv (limbajul de programare Lisp se bazeaz n ntregime pe acest
fapt). Chiar dac nu constituie o demonstraie riguroas, urmtoarea
echivalen practic (descris n pseudo-cod) este deosebit de convingtoare:
orice instruciune de ciclare este echivalent cu un apel recursiv de
subprogram sau funcie.
Varianta iterativ-cu ciclu
Varianta cu apel recursiv contor: =val_init;
Repet
Corp_ciclu;
Incrementeaz (contor);
Pn cnd contor=val_final;
Funcie_Recursiv (contor){
Dac contor<val_final atunci
Corp_ciclu;
Funcie_Recursiv (contor+1);
Funcie_Recursiv (val_init); /apelul iniial al funciei
Observm c n cazul variantei recursive condiia de scurt-circuitare a
recursivitii este echivalenta condiiei de scurt-circuitare a ciclului. Gestiunea
contorului se face n acest caz n back-ground, prin mecanismul de stiv
sistem.
Putem astfel concluziona: toi algoritmii iterativi pot fi nlocuii prin
algoritmi recursivi. Avantajul celor recursivi este dat de scderea dimensiunilor
programelor i de creterea lizibilitii. Avantajul celor iterativi este viteza
mrit de execuie prin gestionarea local a parametrilor de ciclare
(eliminndu-se astfel toate instruciunile push i pop pentru gestionarea stivei).
Spre edificare, v oferim n continuare cteva probleme clasice (simple)
rezolvate n C prin metoda recursiv. n capitolul cu probleme ce necesit backtracking vei gsi i alte soluii recursive (n C) ale unor probleme ceva mai
dificile; astfel se vor putea sesiza mai bine avantajele acestei metode naturale

de programare. (ntruct am considerat acest capitol ca fiind destul de tehnic,


prezentm n continuare doar variantele de program n limbajul C, ce este
considerat mai tehnic dect limbajul Pascal.)
1. S se copieze un ir de caractere ntr-altul.
Include <stdio. H> char *sir1=primul, *sir2=al doilea; void strcopy
(char *sursa, char *det){if (*det+=*sursa+) =NULL) return; else strcopy (sursa,
det);
} void main (void){printf (, sirul sursa: %s, sirul destinaie: %s, sir1,
sir2); strcopy (sir1, sir2); printf (dup, sirul sursa: %s, sirul destinaie: %s,
sir1, sir2);
2. S se afieze primele n ptrate perfecte.
Include <stdio. H> include <math. H> int n; void ptrat (int m){if (m>n)
return; else {printf (%i: %i , m, m*m); ptrat (m+1);
} void main (void){printf (n=); scanf (%i, &n); ptrat (1);
3. Algoritmul lui Euclid.
Include <stdio. H> int cmmdc (int m, int n){if (n=0) return (m); else
cmmdc (n, m%n); void main (void){int m, n; printf (m, n=); scanf (%i, %i, &m,
&n); printf (cmmdc (%i, %i) =%i, m, n, cmmdc (m, n);
4. Se citete n, s se gseasc primul numr prim mai mare dect n. (Se
presupune cunoscut demonstraia faptului c exist p-prim mai mare dect
oricare n. Suntem astfel siguri c algoritmul se oprete!) include <stdio. H>
include <math. H> int n; int are_divizor (int p, int d){if (d>sqrt (p) return 0; else
if (p%d=0) return 1; else are_divizor (p, d+1);
} void prim (int p){if (! Are_divizor (p, 2){printf (%i, p); return;
} else prim (p+1);
} void main (){printf (n=); scanf (%i, &n); prim (n+1);
5. S se afieze primele n numere prime.
Include <stdio. H> include <math. H> int n; int are_divizor (int p, int d){if
(d>sqrt (p) return 0; else if (p%d=0) return 1; else are_divizor (p, d+1);
} void prim (int p, int i){if (i>n) return; if (! Are_divizor (p, 2){printf (%i,,
p); prim (p+1, i+1);
} else prim (p+1, i);
} void main (){printf (n=); scanf (%i, &n); prim (2,1);
6. Se citete n gradul unui polinom P i a [0], a [1] a [n] coeficienii reali
ai acestuia. Se citete o valoare real x, s se calculeze P (x).
Include <stdio. H> int n; float a [20], x; float P (int i){if (i=1) return a [0];
else return P (i-l)*x+a [i-l];
} void citete_coef (int i){if (i>n) return; else {printf (%i:, i); scanf (%f, &a
[i]); citete_coef (i+1);}
} void main (){printf (n=); scanf (%i, &n); citete_coef (0); printf (x=);
scanf (%f, &x); printf (P (%f) =%f, x, P (n+1);
7. Se citesc m i n gradele a dou polinoame P i Q i a [0], a [1] a [m]
respectiv b [0], b [1] b [n] coeficienii reali ai acestora. S se afieze coeficienii
c [0], c [1] c [m+n] ai polinomului produs R=PxQ.
Include <stdio. H> int m, n; float a [20], b [20], c [40]; float suma_prod
(int i, int j){if (j=i) return a [i]*b [0]; else return a [i-j]*b [j]+suma_prod (i, j+1);

} void calc_coef (int i){if (i>m+n) return; else c [i] =suma_prod (i, 0);
} void citete_coef (float a [], int i){if (i>n) return; else {printf (%i:, i); scanf
(%f, &a [i]); citete_coef (a, i+1);}
} void afis_coef (float a [], int i){if (i>n) return; else {printf (%f , a [i]);
afis_coef (a, i+1);}
} void main (){printf (m (gradul polinomului P) =); scanf (%i, &m); printf
(Introd. Coef. Polinomului P:); citete_coef (a, 0); printf (n (gradul polinomului
Q) =); scanf (%i, &n); printf (Introd. Coef. Polinomului Q:); citete_coef (b, 0);
calc_coef (0); afis_coef (c, 0);
8. Se citete n, o valoarea ntreag pozitiv, s se determine suma cifrelor
lui n.
Include <stdio. H> int n; int suma (int n){if (n<10) return n; else return
n%10+suma (n/10);
} void main (){printf (n=); scanf (%i, &n); printf (suma cifrelor=%i,
suma (n);
Probleme rezolvate i exerciii de programare
Vom ncepe prin a face o observaie important: exist totdeauna un
pericol n oferirea pe tav a soluiilor la probleme. n urmtoarele
subcapitolele nu am fost deloc zgrcii i se pot gsi destule probleme
rezolvate att n Pascal ct i n C, dei pentru unele vei putea gsi rezolvarea
doar ntr-unul din limbaje. Pericolul const n faptul c, nceptorilor lenei,
lipsii de voin i nclinai ctre a copia mereu, li se ofer posibilitatea s nu-i
mai bat capul cu rezolvarea problemelor acum cnd au totul de-a gata.
Desigur, cei care ies n pierdere sunt tot ei. Ne-am asumat acest risc gndindune nu att la cei lenei ct mai ales la programatorii nceptori bine-lntenionai
crora aceste probleme, cu rezolvrile lor tipice, le poate fi de un real folos.
Putem spune c urmat astfel exemplul autorilor mediilor de programare Turbo
Pascal i Turbo C (sau Borland) care prin help-urile lor generoase au contribuit
decisiv la formarea multor generaii de programatori.
V avertizm c, n practica concret de programare, programatorul (care
nu este i analist) primete de la cel care a analizat nainte problema doar
indicaii de programare. Rareori analistul pune la dispoziia programatorului i
o descriere n pseudocod a algoritmilor ce trebuiesc implementai. Deci, nici un
programator nceptor nu trebuie s-i fac iluzia c generozitatea din acest
capitol o va mai ntlni vreodat n practica concret de programare sau c va
avea vreodat la dispoziie surse abundente de inspiraie. Este cert c n
practic lipsa inspiraiei va trebui compensat prin transpiraie.
Probleme elementare. Exerciii de programare
Oferim n continuare o mulime de probleme de programare clasice
rezolvate ntr-un mod didactic. Am adugat naintea celor dou versiuni de
soluionare n cele dou limbaje de programare, Pascal i C, cteva rnduri ce
cuprind elementele de baz ale analizei probleme.
Ne-am strduit s aezm problemele n ordinea dificultii lor, de la cele
elementare spre cele mai dificile. De aceea este recomandat ca ele s fie
parcurse n aceast ordine.

Atragem atenia nceptorilor: una din trsturile specifice ale


programrii este c o problem admite mai multe rezolvri corecte. Dei pot fi
diferite n unele detalii, fiind echivalente prin rezultatele pe care le ofer, noi le
vom numi variante. Aa c, ceea ce se ofer n continuare este doar o variant
de rezolvare pentru fiecare problem, ea fiind pasibil de mbuntiri, att
pentru versiunea Pascal ct i pentru versiunea C. Se zice c o variant de
program (algoritm) este mai eficient dect alta dac cantitatea de resursecalculator folosit este mai redus: memorie-calculator (necesarul de spaiu)
mai puin i timp-calculator (necesarul de timp sau durata de execuie) mai
mic.
Este cunoscut c n nvarea unei limbi strine ajut mult exersarea
traducerilor dintr-o limb ntr-alta. Evident, pentru realizarea retroversiunii
(termenul de specialitate folosit) este necesar cunoaterea temeinic a uneia
din cele dou limbaje. La fel, n cazul programrii, nvarea celui de-al doilea
limbaj de programare este mult uurat de faptul c am asimilat deja primul
limbaj de programare. n finalul capitolului vor apare, pentru exerciiu, mai
multe probleme avnd varianta de rezolvare doar ntr-unul din limbaje, Pascal
sau C i v propunem s scriei programul corespondent n cellalt limbaj.
Astfel, cei care au nvat deja Pascal vor putea astfel s nvee C-ul foarte rapid
i reciproc.
S se afieze soluiile reale ale ecuaiei de gradul al doilea.
Analiza problemei elaborarea algoritmului:
Fie ecuaia de gradul II ax2+bx+c=0
Daca toi coeficienii ecuaiei sunt egali cu 0 atunci avem o ecuaie
nedeterminata care are o infinitate de soluii (S=R).
Daca a, b=0, iar c<>0 atunci avem o ecuaie care nu are soluii.
Daca a=0, b, c <>0 atunci ecuaia se reduce la o ecuaie de gradul I care
are o singura soluie x=-c/b.
Daca a, b, c <>0 atunci trebuie calculat discriminantul (delta) ecuaiei
d=b*b-4*a*c
Daca d>=0 atunci ecuaia are soluii reale x1,2= (-b+-sqrt (d)/(2*a)
Daca d<0 atunci ecuaia nu are soluii reale.
Program ecuaie; var a, b, c, d: real;
BEGIN write (a=); readln (a); write (b=); readln (b); write (c=); readln (c);
if a=0 then if b=0 then if c=0 then writeln (Ecuatie nedeterminata, S=R) else
writeln (Ecuatia nu are soluii.) else writeln (Ecuatie de gradul I cu soluia x=.
C/b:6:2) else begin d: =b*b-4*a*c; if d>=0 then begin writeln (x1=, (-bsqrt (d)/(2*a):6:2); writeln (x2=, (-b+sqrt (d)/(2*a):6:2); end else writeln
(Ecuatia nu are soluii reale.); end; readln;
END.
Include <stdio. H> include <math. H> float a, b, c; /coeficienii ecuaiei de
gradul II float delta; void main (){printf (Introd. Coefic. Ecuaiei a b c:); scanf
(%f %f %f, &a, &b, &c); delta=b*b-4*a*c; if (delta>=0) {printf (Sol. Reale:
x1=%6.2f, x2=%6.2f, (-b+sqrt (delta)/2. /a, (-b-sqrt (delta)/2. /a);
} else {printf (Sol. Complexe: x1= (%6.2f, %6.2f), x2= (%6.2f, %6.2f).
B/2. /a, sqrt (-delta)/2. /a. -b/2/a, -l. /2. /a*sqrt (-delta);

S se determine dac trei numere reale pot reprezenta laturile unui


triunghi. Dac da, s se calculeze perimetrul i aria sa.
Analiza problemei elaborarea algoritmului:
Trebuie sa vedem cnd trei numere pot fi lungimile laturilor unui
triunghi: cele trei numere trebuie sa fie pozitive i suma a oricare doua dintre
ele sa fie mai mare dect a treia latura.
Algoritmul poate fi implementat folosind o funcie care sa verifice daca
cele trei numere ndeplinesc condiiile enumerate mai sus.
Dupa verificarea celor trei numere calculam perimetrul i aria
triunghiului folosind formula lui Heron s=sqrt (p (p-a)(p-b)(p-c), unde
semiperimetrul este p= (a+b+c)/2.
Program arie; var a, b, c: integer; s, p: real; function laturi_ok: boolean;
begin laturi_ok: = (a>0) and (b>0) and (c>0) and (a+b>c) and (a+c>b) and
(b+c>a); end;
BEGIN write (introduceti laturile); readln (a, b, c);
P: = (a+b+c)/2;
IF laturi_ok then begin s: =sqrt (p*(p-a)*(p-b)*(p-c); writeln (s=, s:5:2);
writeln (p=, p*2:5:2); end else writeln (laturi negative sau prea mari); readln;
END.
/soluia n limbajul C include <stdio. H> include <math. H> float a, b, c;
float s, p; int laturi_ok (void){return (a>0) & (b>0) & (c>0) & (a+b>c) & (a+c>b) &
(b+c>a); void main (void){printf (introducei laturile a b c:); scanf (%f %f %f,
&a, &b, &c); p= (a+b+c)/2; if (laturi_ok (){s=pow (p*(p-a)*(p-b)*(p-c), 0.5); printf
(s=%6.2f p=%6.2f, s, p);
} else printf (laturi negative sau prea mari);
S se afieze media aritmetic, geometric i hiperbolic a trei valori
reale.
Analiza problemei elaborarea algoritmului:
Trebuie aplicate formulele pentru calculul celor trei medii i trebuie
analizate cazurile:
cand nu putem calcula media geometrica a trei numere (cnd produsul
lor este negativ, deci cnd avem unul sau trei numere negative)
cand nu putem calcula media hiberbolica a numerelor (cnd unul
dintre numere este egal cu 0 i nu poate fi fcut mprirea cu 0).
n TurboPascal exista o funcie pentru calculul radicalului de ordinul 2
(sqrt), dar pentru calculul radicalului de ordinul n nu este implementata o
funcie de aceea pentru calculul radicalului de ordinul n folosim funcia
exponenial (exp) pentru a calcula o puterea a lui: an =exp (n*ln (a), iar pentru
a calcula radical de ordinul n din a: a1/n=exp (1/n*ln (a). Program medii; var a,
b, c, ma, mg, mh: real;
BEGIN write (a=); readln (a); write (b=); readln (b); write (c=); readln (c);
writeln (ma=, (a+b+c)/3:6:2); if (a=0) or (b=0) or (c=0) then writeln (mg=0) else
if a*b*c>0 then writeln (mg=, exp (1/3*ln (a*b*c):6:2) else writeln (Nu putem
calcula media geometrica, nr negative.); if (a=0) or (b=0) or (c=0) then writeln
(Nu putem calcula media hiperbolica) else writeln (mh=,
3/(1/a+1/b+1/c):6:2); readln;

END.
/soluia n limbajul C include <stdio. H> include <math. H> float a, b, c,
ma, mg, mh; void main (void){printf (a=); scanf (%f, &a); printf (b=); scanf
(%f, &b); printf (c=); scanf (%f, &c); printf (ma=%6.3f, (a+b+c)/3.); if (a=0
|| b=0 || c=0){printf (mg=0); printf (Nu putem calcula media hiperbolica);
} else {if (a*b*c>0) then writeln (mg=%6.3f, pow (a*b*c, 1. /3.); else printf
(Nu putem calcula media geometrica, nr negative.); printf (mh=%6.3f, 3.
/(1/a+1/b+1/c);
S se determine suma primelor n numere naturale.
Analiza problemei elaborarea algoritmului:
Suma primelor n numere naturale poate fi calculata, fr a folosi formula
cunoscut, cu una dintre instruciunile repetitive cunoscute (for, while, repeat)
Indiferent de instruciunea repetitiva folosita trebuie iniializata suma cu
0 (s=0)
Folosim un contor i (1, n) care la fiecare pas se incrementeaz cu 1 i se
aduna la s
Ciclul se ncheie cnd valoarea lui i>n
Daca folosim instruciunea for, numrul pailor este cunoscut, valoarea
iniial a contorului fiind 1, iar cea finala fiind n.
Program suma; var s, i: word;
BEGIN writeln (Introduceti limita n=); readln (n); s: =0; for i: =1 to n do s:
=s+i; writeln (s=, s); readln;
END.
/soluia n limbajul C include <stdio. H> unsigned s, i; void main
(void){printf (Introducei n=); scanf (%u, &n); for (s=0, i=1; i<=n; i+) s+=i;
printf (s=%u, s);
S se determine dac n este ptrat sau cub perfect.
Analiza problemei elaborarea algoritmului:
Pentru a verifica daca un numr este ptrat perfect calculam rdcina
ptrat a numrului
Daca numrul este ptrat perfect rdcina lui este un numr ntreg altfel
este un numr cu zecimale
Verificam daca ptratul partii ntregii a rdcinii numrului este egal cu
numrul dat, daca da numrul este ptrat perfect altfel numrul nu este ptrat
perfect
La fel procedam pentru a verifica daca un numr este cub perfect.
Program ptrat_i_cub_perfect; var n: longint;
BEGIN write (n=); readln (n); if n=trunc (sqrt (n)*trunc (sqrt (n) then
writeln (n, este ptrat perfect) else writeln (n, nu este ptrat perfect); if
n=trunc (exp (1/3*ln (n)*trunc (exp (1/3*ln (n)*trunc (exp (1/3*ln (n) then
writeln (n, este cub perfect) else writeln (n, nu este cub perfect); readln;
END.
/soluia n limbajul C include <stdio. H> include <math. H> unsigned
long n, m; void main (void){printf (n=); scanf (%lu, &n); m=pow (n, 0.5); if
(n=m*m) printf (n este ptrat perfect.); m=pow (n, 1. /3.); if (n=m*m*m) printf
(n este cub perfect.);

S se determine toate numerele de 4 cifre divizibile cu n.


Analiza problemei elaborarea algoritmului:
Observam ca daca abordam soluia la prima mn numrul pailor n
cadrul ciclului for este de 8999, pentru ca valoarea de intrare n ciclul for este
1000 iar valoarea de ieire este 9999.
Re-analiznd problema putem stabili un numr foarte mic de pasi care
este egal cu numrul de numere formate din patru cifre divizibile cu n.
Program nr_divizibile; var n, i: word;
BEGIN write (n=); readln (n); for i: =1000 to 9999 do if (i mod n=0) then
write (i, ); writeln;} if 1000 mod n =0 then for i: = (1000 div n) to 9999 div n do
write (i*n, , ) else for i: = (1000 div n)+1 to 9999 div n do write (i*n, , ); readln;
END.
/soluia n limbajul C include <stdio. H> unsigned n, i; void main
(void){printf (n=); scanf (%u, &n); if (1000 % n =0) for (i=1000/n; i<=9999/n;
i+) pritnf (%4u,, i*n); else for (i=1000/n+1; i<= 9999/n; i+) printf (4u,, i*n);
S se determine suma cifrelor lui n.
Analiza problemei elaborarea algoritmului:
Suma cifrelor numrului citit se obine adunnd de fiecare data ultima
cifra ce este restul mpririi lui n la 10 (n mod 10) iar ceea ce rmne
eliminnd ultima cifra este dat de mprirea lui n la 10 (n div 10).
Program suma_cifre; var n, s: word;
BEGIN write (n=); readln (n); s: =0; while n<> 0 do begin s: =s+n mod 10;
n: =n div 10; end; writeln (s=, s); readln;
END.
/soluia n limbajul C include <stdio. H> unsigned n, s; void main
(void){printf (n=); scanf (%u, &n); s=0; while (n! =0) {s+=n % 10; n/=10;
} printf (s=%u, s);
S se afieze urmtorul triunghi de numere:
12 3. N program triunghi; var i, j, n: word;
BEGIN write (n=); readln (n); for i: =1 to n do begin for j: =1 to i do write
(j, ); writeln; end; readln;
END.
/soluia n limbajul C include <stdio. H> int n, i, j; void main (void){printf
(n=); scanf (%u, &n); for (i=1; i<=n; i+) {for (j=1; j<=i; j+) printf (%i , j);
putchar ();
Se citete o valoare real. S se determine radical din x cu 5 zecimale
exacte pe baza irului convergent xn=1/2(xn-l+x/xn-l), cu x0>0 arbitrar ales.
Analiza problemei elaborarea algoritmului:
Pentru rezolvarea problemei folosim sirul convergent dat (metoda lui
Newton) care consta n etapele:
Pornind cu x0=1 se genereaz recursiv urmtorul sir de numere reale
xn=1/2(xn-l+x/xn-l)
Cand diferena intre xn i xn-l este foarte mica (mai mica dect o limita
data) procesul de generare a lui xn nceteaz
La sfrit xn reprezint rdcina ptrat a lui x.
Var x, xn, xn_1: real;

BEGIN write (Introduceti valoarea:); readln (x); xn: =1; repeat xn_1: =xn;
xn: =0.5*(xn_1+x/xn_1); until abs (xn-xn_1) <1e-5; writeln (radical din , xn:6:2,
=, sqrt (x):10:5); readln;
END.
/soluia n limbajul C include <stdio. H> include <math. H> float x, xn,
xn_1; void main (void){printf (Introducei valoarea:); scanf (%f, &x); xn=1; do
{xn_1=xn; xn=0.5*(xn_1+x/xn_1);
} while abs (xn-xn_1) <1e-5; printf (radical obinut =%7.5f, comparativ cu
%7.5, x, pow (x, 0.5);
Se citete n, s se determine toate numerele perfecte mai mici dect n.
Un numr este perfect dac este egal cu suma divizorilor si (de ex. 6=1+2+3).
Analiza problemei elaborarea algoritmului:
Pentru a verifica daca un numr este ptrat perfect trebuie sa i
determinam divizorii i sa verificam daca suma acestora este egala cu n
Se observa ca ultimul divizor nu trebuie luat n calcul pentru ca este egal
cu n
Pentru a afia toate numerele perfecte < n folosim un ciclu while n care il
decrementam pe n i verificam daca noul n este un numr perfect, daca da il
afiam program nr_perfecte; var n, d, i: word;
BEGIN write (n=); readln (n); while n>1 do begin dec (n); d: =0; for i: =1
to n-l do if n mod i=0 then d: =d+i; if n=d then writeln (n); end; readln;
END.
/o varianta C include <conio. H> include <stdio. H> main () long int i, n,
j, sum, k; clrscr (); printf (n=); scanf (%ld, &n); k=0; i=0; do
{k=k+1; do
{sum=1; i=i+1; for (j=2; j<=i/2; j+) if (i%j=0) sum=sum+j;
} while (sum! =i); printf (%ld , i);
} while (k<n);
Se citete n un numr ntreg pozitiv, s se afieze n transcris n baza 2.
Analiza problemei elaborarea algoritmului:
Folosim algoritmul cunoscut: ct timp n <>0 executa
mparte n la 2
n urma mpririi n retine catul i restul
Numrul n baza doi se obine scriind resturile n ordinea inversa n care
le-am obinut
Pentru a retine aceste resturi care trebuie tiprite n ordine inversa am
folosit un sir (n2inv) n care am reinut resturile pe care dup aceea l-am afiat
n ordine inversa.
Program transf_in_baza_2; var n, n2, i, j: word; n2inv: array [1.20] of
word;
BEGIN write (n=); readln (n); i: =1; while n>0 do begin n2: =n mod 2;
n2inv [i]: =n2; n: =n div 2; i: =i+1; end; for j: =i-l downto 1 do write (n2inv [j]);
readln;
END.
/o varianta C putin diferita include <stdio. H> typedef unsigned char
pointer [4]; void afieaz (pointer px, int dim, char* format){int i, j; for (j=dim-l;

j>=0; j-){for (i=8; i>=0; i-) printf (%c, px [j] & (1<i)? 1:0); putchar (.); printf (
adic ); printf (format, *px); float y; long x; void main (void){printf (. ntregul x
i realul y:); scanf (%d %f, &x, &y); printf (= ); afieaz (&x, sizeof (x),%d);
printf (= ); afieaz (&y, sizeof (y),%f);
Se citete n i irul de valori reale x1, x2 xn ordonate cresctor. S se
determine distana maxim ntre dou elemente consecutive din ir.
Analiza problemei elaborarea algoritmului:
Este o problema maxim
Distanta dintre primele valori consecutive din sir se noteaz cu max
Dup care facem o comparaie cu urmtoarele distante dintre valori
n momentul n care se ntlnete o valoare mai mare dect max atunci
aceasta valoare va deveni noul max
Algoritmul se oprete n momentul n care se face comparaia dintre max
i distanta dintre ultimele doua valori ale irului.
Program dist_elem; var n, i: word; max: real; x: array [1.50] of real;
BEGIN write (n=); readln (n); for i: =1 to n do begin write (x [, i, ] =);
readln (x [i]); end; max: =x [2]-x [1]; for i: =2 to n-l do if x [i+1]-x [i] >max then
max: =x [i+1]-x [i]; writeln (max=, max:6:2); readln;
END.
Se citete n gradul unui polinom i irul coeficienilor an a0. Se citete
x, s se determine P (x).
Program polinom; var n, i: integer; p, x: real; a: array [0.20] of integer;
BEGIN write (n=); readln (n); for i: =0 to n do begin write (a [, i, ] =);
readln (a [i]); end; write (x=); readln (x); p: =a [0]; for i: =1 to n do p: =p+a
[i]*exp (i*ln (x); writeln (P (, x, ) =, p:6:2);} p: =0; for i: =n downto 0 do p:
=p*x+a [i]; writeln (P (, x, ) =, p:6:2); readln;
END.
Se citete o propoziie (ir de caractere) terminat cu punct. S se
determine cte vocale i consoane conine propoziia.
Analiza programului elaborarea algoritmului:
Citim propoziia caracter cu caracter pana la ntlnirea caracterului .
Folosim instruciunea case (selecie multipla) care daca la ntlnirea unei
vocale din sir incrementeaz nr de vocale, iar la ntlnirea unei consoane
incrementeaz nr de consoane. Program nr_consoane_i_vocale; var c: char; i,
nv, ne: word; sir: string [25];
BEGIN write (Introduceti propoziia:); readln (sir); i: =1; nv: =0; ne: =0;
repeat case sir [i] of a, e, i, o, u: nv: =nv+1; b, c, d, f, g, h, j, k, l,
m, n, p, r, s, t, x, y, w: ne: =ne+1; end; i: =i+1; until sir [i] =.; writeln
(Nr de vocale=, nv); writeln (Nr de consoane=, ne); readln;
END.
/varianta C include <stdio. H> include <ctype. H> int i, vocale=0,
consoane=0; char c, sir [80]; void main (void){printf (Introd. Propoziia
terminata cu punct:); gets (sir); for (i=0; sir [i]! =.; i+) switch (toupper (sir
[i]){case A: case E: case I: case O: case U: vocale+; break; default: if (isalpha
(sir [i]) consoane+; printf (Vocale: %i, Consoane: %i, Alte car.: %i, vocale,
consoane, i-vocale-consoane);

Se citete m, n dimensiunea unei mtrici A= (a [i, j]) mxn de valori reale.


S se determine suma elementelor pe fiecare linie i coloan.
Program matrice3; var m, n, i, j: word; a: array [1.50,1.50] of real; i, se:
array [1.50] of real;
BEGIN write (Introduceti nr de linii m=); readln (m); write (Introduceti nr
de coloane n=); readln (n); for i: =1 to m do begin for j: =1 to n do begin write (a
[, i, , , j, ] =); read (a [i, j]); end; writeln; end; for i: =1 to m do i [i]: =0; for j: =1
to n do se [j]: =0; for i: =1 to m do begin for j: =1 to n do i [i]: =i [i]+a [i, j];
writeln (suma elementelor de pe linia , i, =, i [i]:6:2); end; for j: =1 to n do
begin for i: =1 to m do se [j]: =se [j]+a [i, j]; writeln (suma elementelor de pe
coloana , j, =, se [j]:6:2); end; readln;
END.
/varianta C include <stdio. H> unsigned m, n, i, j; float a [50][50]; float i
[50], se [50]; void main (void){printf (Introducei nr de linii m=); scanf (%u,
&m); pritnf (Introducei nr de coloane n=); scanf (%u, &n); for (i=0; i<m;
i+){for (j=0; j<n; j+){printf (a [%u, %u] =, i, j); scanf (%f, &a [i][j]);
} putchar ();
}; for (i=0; i<m; i+) i [i] =0; for (j=0; j<n; j+) se [j] =0; for (i=0; i<m; i+) {for
(j=0; j<n; j+) i [i]+=a [i][j]; printf (suma elementelor de pe linia %u =%f, i, i
[i]);
} for (j=0; j<n; j+) {for (i=0; i<m; i+) se [j]+=a [i][j]; pritnf (suma elementelor
de pe coloana %u=%f, j, se [j]);
Se citete n i k i o matrice A=a [i, j] nxn ptratic. S se determine Ak.
Analiza problemei elaborarea algoritmului:
Algoritmul consta de fapt n calcularea elementelor mtricii produs
Elementul c [i, j] =suma (k=1. N) a [i, k]*b [i, k].
Ak=A*A*. *A
Matricea fiind ptratica atunci cnd k=2 termenii b [i, k] =a [i, k], iar cnd
k>2 termenii b [i, k] pstreaz elementele produsului anterior A*A, folosim
pentru aceasta atribuire procedura aribuire.
Program matrice1; type matrice= array [1.3,1.3] of real; var a, b, p:
matrice; n, i, j, k, l: word; procedure atribuire (a: matrice); begin for i: =1 to n do
for j: =1 to n do b [i, j]: =a [i, j]; end; procedure nmulire; begin for i: =1 to n do
for j: =1 to n do p [i, j]: =0; for i: =1 to n do for j: =1 to n do for l: =1 to n do p [i,
j]: =p [i, j]+a [i, l]*b [l, j]; end;
BEGIN write (Introduceti puterea lui A, k=); readln (k); write (Introduceti
dimensiunea mtricii n=); readln (n); for i: =1 to n do begin for j: =1 to n do
begin write (a [, i, , , j, ] =); readln (a [i, j]); end; writeln; end; if k=1 then for i:
=1 to n do for j: =1 to n do p [i, j]: =a [i, j] else if k=2 then begin atribuire (a);
nmulire; end else begin atribuire (a); nmulire; k: =k-l; while k>1 do begin
atribuire (p); nmulire; k: =k-l; end; end; for i: =1 to n do begin for j: =1 to n do
write (p [, i, , , j, ] =, p [i, j]:6:2, ); readln; end; readln;
END.
Iat un program Pascal care gestioneaz cu ajutorul unui fiier un
catalog de note i persoane.

Type Persoana=Record Nume: String [20]; Nota: Array [1.4] of integer;


End;
Var f: File of Persoana;
Perstemp: Persoana;
Procedure Creare;
Begin
Writeln (Introd.);
Assign (f, Test. Jo);
Rewrite (f);
Repeat
With PersTemp do begin
Write (Numele:); Readln (Nume);
If Nume= then break;
Write (Notele:); Readln (Nota [1], Nota [2], Nota [3], Nota [4]); end;
Write (f, PersTemp);
Until False;
Close (f);
End;
Procedure Citire;
Begin
Writeln (Introd.);
Assign (f, Test. Jo);
Reset (f);
Repeat
Read (f, PersTemp);
With PersTemp do begin
Writeln (Numele:, Nume);
Writeln (Notele:, Nota [1], Nota [2], Nota [3], Nota [4]); end;
Until Eof (f);
Close (f);
End;
BEGIN
Creare;
Citire;
END.
Iat trei programe care exemplific modul de lucru cu fiiere n limbajul
C.
/Copierea unui fiier text sursa ntr-un fiier destinaie include <stdio.
H> void main (void)
FILE *in, *out; char numfin [20], numfout [20]; long contor=0; printf
(Nume fiier sursa:); gets (numfin); printf (Nume fs. Destinaie:); gets
(numfout); if (in = fopen (numfin, rt) = NULL){fprintf (stderr, Eroare: %s fiier
inexistent., numfin); return;
} out = fopen (numfout, wt); while (! Feof (in){fputc (fgetc (in), out);
contor+;

} fclose (in); fclose (out); printf (Lungimea fs. Destinaie este de %ld
octei., contor);
/Copierea unui fiier text sursa ntr-un fiier destinaie
/cu substituirea unor cuvinte date prin linia de comanda include <stdio.
H> void main (int argc, char *argv [])
FILE *in, *out; char numfin [20], numfout [20], c; unsigned i=0, contor=0;
printf (Nume fiier sursa:); gets (numfin); printf (Nume fs. Destinaie:); gets
(numfout); if (in = fopen (numfin, rt) = NULL){fprintf (stderr, Eroare: %s fiier
inexistent., numfin); return;
} out = fopen (numfout, wt); while (! Feof (in){if (c=fgetc (in) =argv [1][i]){if
(argv [1][+i] =0) /s-a detectat sfritul irului de caractere fputs (argv [2], out),
i=0; /se scrie sirul de caractere nlocuitor
} else fputc (c, out); contor+;
} fclose (in); fclose (out); printf (Lungimea fs. Destinaie este de %d
octei., contor);
/prelucrarea unul fiier C ce conine o agenda telefonica include <stdio.
H> include <ctype. H> include <conio. H> struct articol char nume [10], adresa
[10], tel [7];
} inreg;
FILE *fagenda, *ftemp; char mod [3] =wb; void creare (void){char temp;
puts (agendei:); do {printf (:); gets (inreg. Nume); printf (Adresa:); gets
(inreg. Adresa); printf (Tel:); gets (inreg.tel); fwrite (&inreg, sizeof (inreg), 1,
fagenda); /* write struct inreg to file */printf (Continuai [D/N]?); temp=getch
();
} while (toupper (temp)! =N); /ciclu infinit? NU!
Fclose (fagenda); /* close file */void listare (void){int contor=0; puts
(agendei:); mod [0] =r; if (fagenda= fopen (agenda.jo, mod) = NULL) /* open
file agenda */fprintf (stderr, Cannot open output file.); while (fread (&inreg,
sizeof (inreg), 1, fagenda)! =0) /* write struct inreg to file */printf (%d: %s, %s,
%s, +contor, inreg. Nume, inreg. Adresa, inreg.tel); fclose (fagenda); /* close file
*/void main (void) if (fagenda= fopen (agenda.jo, mod) = NULL) /* open file
agenda */fprintf (stderr, Cannot open output file.); creare (); listare ();
Probleme ce necesit back-tracking
Am explicat pe larg aceast metod de programare ntr-un capitol
separat. n acest capitol vom oferi doar cteva exemple de probleme rezolvate.
Majoritatea dintre ele sunt de maxim dificultate i nu li se cunoate o altfel de
rezolvare dect prin aceast metod. Din fericire, aceast metod de proiectare
a soluiei are un caracter foarte general i funcioneaz n fiecare caz. Din
nefericire, n practic, atunci cnd dimensiunea datelor de intrare este
consistent (avnd valori cel puin de ordinul sutelor) programul rezultat
devine, prin durata astronomic de execuie, total inutilizabil.
Atragem atenia c doar simpla lecturare a acestor exemple de probleme
de back-tracking rezolvate nu permite nicidecum nsuirea acestei metode de
proiectare a soluiilor. Este necesar mai nti implicarea i participare
personal, a celui ce-i propune s nvee aceast metod, ncercnd direct
soluionarea lor i abia apoi comparnd soluia rezultat cu cea propus de noi.

Problema clasic de programare care necesit back-tracking (revenirea pe


urma lsat) este problema ieirii din labirint.
Iat o soluie simpl care iniializeaz labirintul n mod static, ca o
matrice de caractere include <stdio. H> include <stdlib. H> include <conio. H>
define XMAX 6 define YMAX 6 char a [XMAX+1][YMAX+1] = {
}; int x0=1, y0=2; void print (void){int i, j; for (i=0; i<=XMAX; i+){for (j=0;
j<=YMAX; j+) putchar (a [i][j]); putchar ();
} getchar (); clrscr (); void escape (int x, int y){if (x=XMAX || y=YMAX){puts
(Succes!); exit (1);} a [x][y] =*; print (); if (a [x][y+1] = ){puts (la dreapta);
escape (x, y+1);} if (a [x+1][y] = ){puts (in jos ); escape (x+1, y);} if (a [x][y-l] =
){puts (la stnga ); escape (x, y-l);} if (a [x-l][y] = ){puts (in sus ); escape (x-l,
y);} return; void main (void){escape (x0, y0); puts (Traped!);
S se genereze toate irurile de lungime n formate numai din caracterele
a, b i c a.. S nu existe dou subiruri identice alturate.
De exemplu, dac n=3 putem avea iruri de forma abc, cab, bcb, etc. Dar
nu i iruri de forma aab; pentru n=4 nu putem genera iruri de forma abab,
baac, etc. Include <stdio. H> include <stdlib. H> include <string. H> define byte
unsigned char char car [4] = abc; unsigned int n, contor; int Valid (char *s,
char c, byte k){/funcia de validare a irului generat byte i, j, ok, Val=1; /prin
concatenarea unui singur caracter for (i=k-l; i>= (k+1)/2; i-) if (s [i] =c){ok=1; for
(j=1; j<=k-l-l; j+) if (s [i-j]! =s [k-j]){ok=0; break;} if (ok) {Val=0; break;}
} return Val; void Concatsir (char *s, byte k){/funcia ce implementeaz
back-tracking-ul byte i; /n varianta recursiva if (k<=n){for (i=1; i<=3; i+) if
(Valid (s, car [i], k) {s [k] =car [i]; s [k+1] =;
Concatsir (s, k+1);
} else {contor+; printf (%4i: %s, contor, s);} void main (void){printf (n:);
scanf (%i, &n); contor=0;
Concatsir ( , 1); exit;
S se afieze toate descompunerile unei sume s ntr-un numr minim de
monezi ale unui sistem monetar de n valori.
De exemplu, n cazul unui sistem monetar de forma 10, 5, 3, 1 putem
descompune suma 18 n diverse moduri dar soluia minimal necesit doar 3
monezi: 18=1 x 10+1 x 5+1 x 3; descompunerea minimal poate s nu fie
unic; sistemul monetar trebuie s fie astfel ales nct s permit
descompunerea oricrei sume ncepnd de la o valoare minimal n sus (orice
sistem monetar conine de obicei moneda unitar 1) include <stdio. H> int m
[10], a [10], a_final [10], s, n, nrmin=32000, kmin; void descompune (int s, int
k, int contor){register int i; if (s=0) if (contor<nrmin){nrmin=contor; kmin=k-l; for
(i=1; i<=k; i+) a_final [i] =a [i]; for (i=k+1; i<=n; i+) a_final [i] =0; return;
} else return; if (k>n) return; if (k=n){a [k] =s/m [k]; descompune (s-a [k]*m
[k], k+1, contor+a [k]);
} else for (i=s/m [k]; i>=0; i-){a [k] =i; descompune (s-l*m [k], k+1,
contor+i);
} void main (void){int i; printf (Introd.nr.de valori n a sistemului
monetar:); scanf (%i, &n); printf (Introd.in ordine descresc. Cele %i valori
monetare:, n); for (i=1; i<=n; i+) scanf (%i, &m [i]); printf (Introd. Suma s:);

scanf (%i, &s); descompune (s, 1,0); if (nrmin>0) for (i=1; i<=kmin; i+) printf
(%i * %i,, a_final [i], m [i]); else puts (Nu se poate descompune!);
S se afieze toate descompunerile unui numr s ca sum de n elemente.
De exemplu, pentru s=13 i n=3 avem urmtoarele 14 descompuneri 13=
1+1+11= 1+2+10= 1+3+9=. = 1+6+6= 2+2+9= 2+3+8= 2+4+7= 2+5+6= 3+3+7=
3+4+6= 3+5+5= 4+4+5
Dei este cu totul alt problem dect cea dinainte, putem observa
asemnarea dintre cele dou soluii (ambele sunt date n varianta recursiv)
include <stdio. H> int a [10], s, n, contor=0; void descompune (int s, int
k){register int i; if (k=1){a [n] =s; printf (%3i:, +contor); for (i=1; i<=n; i+) printf
(%i , a [i]); puts (); return;
} else for (i=1; i<s; i+){a [n+l-k] =i; descompune (s-l, k-l);} void main
(void){printf (Introd. Suma s i n ct se descompune n:); scanf (%i %i, &s,
&n); descompune (s, n); getchar ();
S se afieze toate descompunerile unui numr s ca sum de n elemente
distincte.
Aceasta este o variant a problemei dinainte; putei sesizai unde apare
diferena n rezolvare?
Include <stdio. H> int a [10], s, n, contor=0; void descompune (int s, int
k){register int i; if (k=0){printf (%3i:, +contor); for (i=1; i<=n; i+) printf (%4i, a
[i]); puts (); return;
} else for (i=a [n-k]+1; i<s; i+){a [n+l-k] =i; descompune (s-l, k-l);} void main
(void){printf (Introd. Suma s i n ct se descompune n:); scanf (%i %i, &s,
&n); a [0] =0; descompune (s, n); if (contor=0) puts (Nu se poate
descompune!); getchar ();
Probleme cu soluie surprinztoare
n rezolvarea fiecreia din problemele urmtoare este foarte uor de czut
n capcana soluionrii de genul la prima mn sau brute-force-approach n
limba englez (abordare n for brut). Este cea mai des ntlnit capcan
pentru programatorii lipsii de subtilitate, experien sau cultur de
specialitate. Este i aceasta o rezolvare, desigur, dar lipsa ei de eficien i de
elegan este evident. Tocmai de aceea, considerm foarte util prezentarea
ctorva exemple elocvente, mpreun cu soluiile lor. Unele dintre probleme au
fost selecionate dintre problemele date la concursurile i olimpiadele colare de
programare.
Prin acest capitol nu urmrim doar nsuirea unor cunotine practice de
programare ci, mai ales, aprofundarea capacitii de analiz i proiectare a
soluiilor. Aceasta presupune un salt calitativ n nvarea programrii i de
aceea acest capitol devine cu adevrat util numai pentru acei programatori
inteligeni i dornici de auto-perfecionare. Sau pentru cei care se pregtesc
pentru participarea la concursurile i olimpiadele de informatic.
Soluiile oferite de noi sunt, pentru fiecare problem, eficiente i
elegante. Acest fapt se datoreaz accentului pus pe aprofundarea i
mbuntirea primei analize a problemei.
Putem atunci spune, c motto-ul acestui capitol este: Nu te mulumi
niciodat cu soluia la prima mn!.

S se afieze numrul cuburilor perfecte mai mici dect n.


Analiza problemei elaborarea algoritmului:
Capcana problemei const n tentativa de a parcurge printr-un ciclu for
toate numerele de la 1 la n i de a contoriza cele care sunt cuburi perfecte.
La o a nou privire, mai atent, observm c partea ntreag a radicalului
de ordinul 3 din n ne ofer acel numr care ridicat la a 3-a este cel mai
apropiat cub de n. Deci, partea ntreagp a radicalului de ordinul 3 din n este
egal chiar cu numrul cuburilor mai mici dect n.
Este suficient s calculm radical de ordinul 3 din n pentru a afla cte
cuburi mai mici dect n exist.) program cuburi_perfecte; var n, i, nr_cub:
word;
BEGIN write (n=); readln (n); nr_cub: =trunc (exp (1/3*ln (n); writeln
(numarul cuburilor perfecte < , n, este = , nr_cub); readln;
END.
Se citesc m, n numrtorul i numitorul unei fracii. S se simplifice
aceast fracie.
Analiza problemei elaborarea algoritmului:
Capcana const n a efectua simplificarea pas cu pas, cutnd pe rnd
fiecare divizor comun al numrtorului i numitorului. n plus, ar trebui s
avem grij c, pentru unii divizori comuni, este nevoie de o simplificare
repetat. Deci, dou cicluri imbricate!
Pentru a obine o fracie ireductibil este suficient s o simplificm o
singur dat cu cmmdc al numitorului i al numrtorului, eliminndu-se
astfel simplificrile succesive
Vom folosi subalgoritmul (Euclid) care calculeaz cmmdc al
numrtorului i al numitorului.
Program simplificare; var m, n: word; function cmmdc (m, n: word): word;
begin while m<>n do if m>n then m: =m-n else n: =n-m; cmmdc: =m; end;
BEGIN write (numaratorul fraciei m= ); readln (m); write (numitorul
fraciei n= ); readln (n); if n=0 then writeln (Fractie inexistenta.) else if m=0
then writeln (m, /, n, =, 0) else writeln (m, /, n, = , m div cmmdc (m, n), /,
n div cmmdc (m, n); readln;
END.
Se citesc a, b, c ntregi. S se determine toate perechile ntregi (x, y)
soluii ale ecuaiei ax+by=c.
Analiza problemei elaborarea algoritmului;
Problema a fost dat la olimpiada colar de informatic. Ea pare la
prima vedere imposibil. Exist ecuaii, de exemplu: 3x+2y=1 care are o
infinitate de soluii., (1, -l), (3, -4), (5, -7), (7, -l0),. Cum ar putea fi afiat
atunci pe ecran o mulime infinit de perechi? Soluia este de a afia aceast
mulime printr-o descriere sintetic a ei (afind formula care poate genera
toate perechile ce o compun).
1. Daca c=1 atunci exista (x0, y0) a.. Ax0+by0=1 doar daca [a, b] =1;
restul soluiilor (x, y) au forma x=x0+kb, y=y0-ka, cu k ntreg.
2. Daca c>1 atunci exista soluiile (x0, y0) doar daca [a, b] |c; restul
soluiilor se construiesc la fel; prin [a, b] se nelege cmmdc (a, b)

Programul trebuie doar s determine x0 i y0.


Program ax_plus_by_egal_c;
Var a, b, c, x0, y0, y: integer;
BEGIN
Write (a, b, c=); Readln (a, b, c); x0: =0;
For y: =0 to a do
If abs (c-b*y) mod a=0 then begin y0: =y; x0: = (c-b*y) div a; break; end;
If x0<>0 then Writeln (Sol. (x, y) ale ec. , a, x+, b, y=, c, sunt (, x0,
+k*, b, , , y0, -k*, a, ) ) else Writeln (Nu exista soluii pentru ecuaia , a,
x+, b, y=, c);
END.
/*Varianta C de soluionare:
1. Daca c=1 atunci exista (x0, y0) a.I. Ax0+by0=1 doar daca cmmdc [a, b]
=1; restul soluiilor (x, y) au forma x=x0+kb y=y0-ka, cu k ntreg.
2. Daca c>1 atunci exista soluiile (x0, y0) doar daca cmmdc [a, b] | c;
restul soluiilor se construiesc la fel.
3. Exista posibilitatea ca, pornind de la perechi (x0, y0) distincte, sa se
obin soluii noi diferite (mulimi infinite de perechi distincte).
4. Toate soluiile (mulimi infinite de perechi) pleac de la o pereche x0,
y0) aflata n dreptunghiul (-b. a) x (b, a).
Un bun exemplu este ecuaia 18x+42y=6. */include <stdio. H> include
<math. H> int a, b, c, x0=0, y0=0, y, k; void main (void){printf (a, b, c:); scanf
(%i %i %i, &a, &b, &c); printf (Ecuaia %ix+%iy=%i are sol.de forma:, a, b, c);
for (y=0; y<=a; y+) if (abs (c-b*y) % a=0){y0=y; x0= (c-b*y) /a; if (x0! =0){printf
(%i*k%+i, -(%i*k-%i), de ex. , b, x0, a, y0); for (k=-2; k<=2; k+) printf ((%i, %i)
, x0+k*b, y0-k*a);
} if (! X0 &! Y0 & c) printf (Nu exista soluii pentru ecuaia %ix+%iy=%i,
a, b, c);
Se citete n o valoare ntreag pozitiv. S se determine toate
descompunerile n diferen de ptrate ale lui n.
Analiza problemei elaborarea algoritmului:
Artm n continuare cum se poate evita soluia banal-capcan ce-ar
consta n dou cicluri for imbricate. Soluia urmtoare efectueaz doar radical
din n pai, fa de n2pai ai soluiei la prima mn.
Pentru a determina toate descompunerile n diferena de ptrate ale lui n
pornim de la formula a2-b2= (a+b)(a-b) =n
Observam ca produsul termenilor a+b i a-b este produsul a doi dintre
divizorii lui n, unul din termeni este divizor (d) a lui n celalalt este tot divizor a
lui n i il aflam mprindu-l pe n la d (n div x)
Notam cu x primul divizor a lui n (x=d) i cu y=n div x i obinem relaiile
a+b=x deci un sistem de doua ecuaii cu doua necunoscute, pe care il rezolvam
a-b=y prin metoda reducerii, i avem 2a=x+y => a= (x+y)/2, b= (y-x)/2.
Pentru ca (x+y)/2 sa fie o soluie a ecuaiei a2-b2= (a+b)(a-b) =n trebuie
ca x+y sa fie un numr par i y-x sa fie un numr par
Daca aceasta condiie este ndeplinit afiam soluia care ndeplinete
condiia ceruta.

Program descompunere_ptrate; var n, d, a, b, x, y: integer;


BEGIN write (n=); readln (n); for d: =1 to trunc (sqrt (n) do if n mod d =0
then begin x: =d; y: =n div x; if (x+y) mod 2 =0 then begin a: = (x+y) div 2; b: =
(y-x) div 2; writeln (n, =, a*a, -, b*b); end; end; readln;
END.
Se citete n i x1, x2 xnrdcinile ntregi ale unui polinom de gradul n.
Se cere s se determine pe baza relaiilor lui Viete coeficienii an, an-l a1, a0.
Analiza problemei elaborarea algoritmului;
Cea mai des ntlnit rezolvare este cea de tip back-tracking, aparent mai
uoar, dar n fapt extrem de ineficient pentru n nu mare ci doar mricel!
Urmtoarea soluie de tip iterativ este o mic bijuterie de program iterativ i
de aceea v lsm plcerea de a-l nelege singuri.
Include <stdio. H> void main (void){int a [100], x [100], n, i, k; printf
(n=); scanf (%d, &n); printf (Rdcinile:); for (i=0; i<n; i+){printf (x [%d] =,
i); scanf (%d, &x [i]); a [i] =0;
} a [0] =1; a [n] =0; for (k=1; k<=n; k+){for (i=k; i>0; i-) a [i] =a [i-l]-a [i]*x [kl]; a [0]*=-x [k-l];
} for (i=n; i>=0; i-) printf (a [%d] =%d , i, a [i]);
Se citete n. S se afieze toate numerele de n cifre, formate numai cu
cifrele 1 i 2, divizibile cu 2n.
Analiza problemei elaborarea algoritmului:
Problema a fost dat la olimpiada colar de informatic. Abordarea n
for a acestei probleme nu duce la nici un rezultat:
Daca s-ar alege varianta de rezolvare la prima mina ar trebui verificate
toate cele 2n posibiliti, adic toate cele 2n numere de n cifre ce se pot forma
numai cu cifrele 1 i 2 (cte 2 posibiliti pentru fiecare poziie). n acest caz,
programul avnd o complexitate exponenial, ar dura un timp exponenial, pT.
N=50 ar dura ct vrsta sistemului nostru solar!
PT. N=1 avem unica soluie numrul 2; pT. N=2 avem deasemenea unica
soluie 12; observam ca 2-ul este folosit pT. N=3 avem deasemenea unica
soluie 112; observam ca 12 este din nou folosit
n general, se deduce ca numerele de n cifre, ce trebuie sa se divid cu
2n, se divid cu 2n-l; ele se pot scrie sub forma c*10(n-l)+M=c*2n-l*5n-l+M=
Multiplu (2n-l)+M; nseamn ca M (cele n-l cifre ramase) trebuie sa se divid cu
2n-l; nseamn ca M este unul din numerele gsite ca soluie la pasul n-l.
Daca exista o singura soluie M pT. Cazul n-l (M se divide cu 2n-l) acest
nr.se poate scrie M=2(n-l)*par sau 2(n-l)*impar, rezulta ca M mod 2n=0 sau M
mod 2n=2(n-l). Deci, n cazul a n cifre din cele doua posibiliti (1M sau 2M) se
va alege astfel unica soluie: daca M mod 2n=0 atunci soluia este 2M=2*10(nl)+M=Multiplu (2n) daca M mod 2n=2(n-l) atunci soluia este 1M=10(nl)+M=2(n-l)*5(n1)+M=Multiplu (2n)!
Soluia propusa este una iterativa i face maximum n pai!
Program 1_2_i_2_la_n;
Var nr, zece_la_n: longint; n, i: byte;
BEGIN
Writeln (Se citete n. Sa se afieze toate numerele de n cifre, );

Writeln (formate numai cu cifrele 1 i 2 i divizibile cu 2^n.);


Write (Introduceti n (max.10):); Readln (n); nr: =2; zece_la_n: =1;
For i: =2 to n do begin zece_la_n: =10*zece_la_n;
If nr mod (1 shl i) =0 then nr: =2*zece_la_n+nr else nr: =zece_la_n+nr;
end;
Writeln (Solutia este:, nr); readln;
END.
Se citete n. S se determine o alegere a semnelor + i astfel nct s
avem relaia 12. n=0.
Analiza problemei elaborarea algoritmului:
Problema a fost dat la olimpiada colar de informatic. Daca se
ncearc o abordare in for i la prima mina vor trebui verificate 2n
posibiliti de aezare a semnelor + i Adic se obine un algoritm exponenial,
total ineficient. Soluia elegant ce rezult printr-o analiz mai aprofundat:
Mai nti se va mpri suma n doua parti: cea cu plus i cea cu minus.
Privindu-se atent se observa ca se pot deosebi trei cazuri:
1. Cnd avem intre cele n numere un numr impar de numere impare (de
ex. N=3,5,6.) caz n care numerele impare nu pot fi repartizate n cele doua
parti (plus i minus) dect astfel: un nR. Par de numere impare ntr-o parte i
un nR. Impar de nr impare n cealalt; implica ca cele doua parti au pariti
diferite, deci suma lor nu poate fi 0!
Acest caz apare cnd n=4k+1, 4k+2.
2. Cnd n=4k atunci numerele de la 1 la n pot fi grupate cte patru
astfel:
3+4 (4i+1)-(4i+2)-(4i+3)+(4i+4),. i vor avea suma 0 pe fiecare grupa
de patru!
3. Altfel, n=4k+3, putem grupa numerele asemntor ca la cazul dinainte
cu excepia primei grupe: -l-2+3, 4-5-6+7 (4i)-(4i+1)-(4i+2)+(4i+3),. Reazultind
din nou suma 0 pe fiecare grupa!
Program Plus_Minus;
Var n, i, c: byte;
BEGIN
Writeln (Se citete n. Sa se determine o alegere a semnelor + i );
Writeln (astfel incit sa avem relaia 12. n=0.);
Write (n:); Readln (n); c: =n mod 4; case c of
1,2: Writeln (Nu exista soluie.);
0: For i: =1 to n div 4 do write (+, 4*(i-l)+1, -, 4*(i-l)+2, -, 4*(i-l)+3, +,
4*(i-l)+4);
3: begin
Write (-l-2+3);
For i: =1 to n div 4 do write (+, 4*i, -, 4*i+1, -, 4*i+2, +, 4*i+3); end;
end;
Readln;
END.
Elemente de programare a PC urilor

Oferim n continuare cteva exemple de programe, unele n Pascal, altele


n C, pentru a permite celor pasionai s-i nsueasc cunotinele minimale
de programare a PC-urilor: lucrul cu tastatura, accesul direct la memorie,
lucrul n modul grafic, etc. Pentru cei ce doresc s aprofundeze acest subiect
sau doresc ct mai multe detalii le recomandm, pe lng citirea atent a helpului Turbo Pascal-ului sau a Turbo C-ului, folosirea utilitarului TechHelp
specializat n descrierea programrii PC-urilor.
Ideea care ar defini cel mai bine acest tip de cunotine de programare
este coninut n cunoscuta expresie: Secrete mici, efecte mari!.
/Un simplu program muzical include <stdio. H> include <dos. H> include
<conio. H> main (){/* Do do# Re re# Mi Fa fa# sOl sol# La la# i */int octava [] =
{65, 69, 73, 78, 82, 87, 92, 98, 104, 110, 116, 123}; int i, j, nr_octava, i_nota,
timp=500; float msura, durata, durata_msura; char
*linia=42$2R2R4M4F2O2L1R2R2S2S4L4O2O2; /$4D2D4$3S4L2; do
{msura= (float)(linia [0]-0)/(linia [1]-0); durata_msura=0; for (i=2; linia [i]! =;
i+){if (i%2=0){switch (linia [i]){case $: {nr_octava=1; for (j=linia [+i]-0; j>0; j-)
nr_octava*=2;} break; case D: i_nota=0; break; case d: i_nota=1; break; case
R: i_nota=2; break; case r: i_nota=3; break; case M: i_nota=4; break; case F:
i_nota=5; break; case f: i_nota=6; break; case O: i_nota=7; break; case o:
i_nota=8; break; case L: i_nota=9; break; case l: i_nota=10; break; case S:
i_nota=11; break;
} else {if (linia [i] =6) durata=1/16; else durata=1/(float)(linia [i]-0);
durata_msura+=durata; if (durata_msura>msura) {nosound ();
durata_msura=0;} sound (nr_octava*octava [i_nota]); delay (durata*timp);
} /* else */
} /* for */
} /* do */while (! Kbhit (); nosound ();
Program Citite_Taste; uses crt; var c: char; shift: byte absolute $40: $17;
{adresa octetului de stare a tastaturii} begin repeat c: =readkey; if (shift and
$3>0) then write ( shift , c, :, Ord (c) else write ( , c, :, Ord (c); until c=#27;
end.
/Program C pT. Afiarea Tabelului codurilor ASCII; include <stdio. H>
void main (){unsigned short c; for (c=0; c<=255; c+) switch (c){case 7: printf
(b%3u, c); break; /beep case 8: printf (B%3u, c); break; /back space case
9: printf (T%3u, c); break; /tab case 10: printf (L%3u, c); break; /line feed
case 13: printf (R%3u, c); break; /return case 27: printf (E%3u, c); break;
/escape default: printf (%c%3u, c, c); /caractere afiabile
Program Tenis;
{Joc demonstrativ al posibilitilor de folosire a accesului direct la
memoria ecran. Paletele sunt acionate de tastele A i W, respectiv sgeata
sus i sageata jos.}
Uses Crt;
Const viteza=1500;
Type Ecran=Record car: char; atrib: byte;
End;

Var scr: array [1.25,1.80] of Ecran absolute $b800: $0; {Adresa de


memoriei ecran n mod text} x, y, x0, y0: byte; i, d, s: integer; u: real; ok:
boolean; tasta: char; yP1: array [1.5] of byte; yP2: array [1.5] of byte; uP: array
[1.5] of real;
Procedure Paleta1(tip: char);
Begin {generare paleta 1} for i: =1 to 5 do scr [yP1[i], 76]. Car: =tip; end;
Procedure Paleta2(tip: char);
Begin {generare paleta 2} for i: =1 to 5 do scr [yP2[i], 5]. Car: =tip;
End;
Procedure Mutapaleta1;
Begin
Paleta1( ); if (tasta=#80) and (yP1[i] <24) then {micarea paletei 1} for i:
=1 to 5 do Inc (yP1[i]); if (tasta=#72) and (yP1[i] >6) then for i: =1 to 5 do Dec
(yP1[i]);
End;
Procedure Mutapaleta2;
Begin
Paleta2( ); {micarea paletei 2} if (tasta=#122) and (yP2[i] <24) then for i:
=1 to 5 do Inc (yP2[i]); if (tasta=#119) and (yP2[i] >6) then for i: =1 to 5 do Dec
(yP2[i]);
End; procedure cntec; {genereaz cntecul final} begin sound (400);
delay (800); sound (500); delay (800); sound (600); delay (800); sound (650);
delay (800); sound (600); delay (800); sound (700); delay (800); sound (650);
delay (1000); end;
Begin {program principal-generare cadru}
Clrscr; d: =0; s: =0;
{writeln (_ _ _ _ _ ); write (char (179), , char (179), , char (179), );
writeln (char (179), , char (179); readln;} clrscr;
For x: =1 to 80 do begin scr [1, x]. Car: =#219; scr [25, x]. Car: =#219;
end;
For y: =2 to 9 do begin {poarta} scr [y, 1]. Car: =#219; scr [y, 80]. Car:
=#219; end;
For y: =17 to 24 do begin scr [y, 1]. Car: =#219; scr [y, 80]. Car: =#219;
end; x0: =40; y0: =13; u: =20*PI/180; {iniializare micare minge} x: =x0; y: =y0;
for i: =1 to 5 do begin yP1[i]: =10+i; yP2[i]: =10+i; uP [i]: = (i/3*PI-PI)/15;
{unghiul de dispersie a paletei} end; tasta: = ; repeat {micare minge} if (u>=0)
and (u<PI/2) or (u > 3*PI/2) and (u<2*PI) then inc (x) else dec (x); y: =y0+Trunc
(Abs (x-x0) * Sin (u)/Cos (u); if scr [y, x]. Car<> then begin if (y=1) or (y=25)
then begin {ciocniri} u: =2*PI-u; x0: =x; if y=1 then y0: =2 else y0: =24; end; {-de
perei} if (x=1) or (x=80) then begin u: =PI+u; if u>2*Pi then u: =u-2*PI; y0: =y; if
x=1 then x0: =2 else x0: =79; end; if x=76 then begin {-de palete} for i: =1 to 5
do if y=yP1[i] then begin sound (1000); u: =PI+u+uP [i]; if u>2*Pi then u: =u2*PI; x0: =x; y0: =y; end; nosound; end; if x=5 then begin {-de palete} for i: =1 to
5 do if y=yP2[i] then begin sound (600); u: =PI+u+uP [i]; if u>2*Pi then u: =u2*PI; x0: =x; y0: =y; end; nosound; end; end else if not (x=1) or (x=80) and
(y<17) and (y>8) then begin {gol} scr [y, x]. Car: =0; i: =1; ok: =false; repeat ok:

=keypressed; inc (i); until (i=viteza) or ok; if ok then begin tasta: =readkey; if
tasta = #0 then tasta: =readkey; mutapaleta1; mutapaleta2; end;
Paleta1(#219);
Paleta2(#219); scr [y, x]. Car: = ; scr [y, x]. Car: = ; end else begin sound
(800); if (x>=80) and (y>9) and (y<17) then d: =d+1; if (x<=1) and (y>9) and
(y<17) then s: =s+1; textcolor (2); textbackground (7); gotoxy (39,2); write
(SCOR); gotoxy (38,3); write ( , d, : , s); if (d=5) or (s=5) then begin gotoxy
(35,10); write ( G A M E O V E R ); cntec; nosound; halt; end; delay (1500);
paleta1( ); paleta2( ); x0: =40; y0: =13; u: =20*PI/180; {reiniializare micare
minge} x: =x0; y: =y0; for i: =1 to 5 do begin yP1[i]: =10+i; yP2[i]: =10+i; uP [i]: =
(i/3*PI-PI)/5; end; tasta: = ; nosound; end; until tasta=#27;
End.
Program Biliard; {demonstrativ pentru folosirea modului grafic} uses
Graph, Crt;
Const nr_obiecte=10; raza=25; pasx=3; pasy=2; viteza=10; {de la 0 la 10}
var grDriver, grMode, ErrCode: Integer; i, xMax, yMax, xtmp, ytmp: word; x, y:
Array [1. Nr_obiecte] of word; sensx, sensy: Array [1. Nr_obiecte] of shortint;
Procedure Deseneaz (x, y, color: word);
Const buci=12;
Var x1, y1, unghi, Xasp, Yasp: word;
Begin
SetWriteMode (XORPut); SetColor (color);
GetAspectRatio (Xasp, Yasp); unghi: =0; x1: =x+Trunc (raza*cos
(unghi*2*PI/buci); y1: =y+Trunc (raza*sin (unghi*2*PI/buci)*Xasp/Yasp);
For unghi: =1 to buci do begin xtmp: =x+Trunc (raza*cos
(unghi*2*PI/buci); ytmp: =y+Trunc (raza*sin (unghi*2*PI/buci)*Xasp/Yasp);
Line (x1, y1, xtmp, ytmp); Line (x, y, x1, y1); x1: =xtmp; y1: =ytmp; end;
End; begin grDriver: = Detect;
InitGraph (grDriver, grMode,);
ErrCode: = GraphResult; if ErrCode = grok then begin {Do graphics}
xMax: =GetMaxX; yMax: =GetMaxY;
Rectangle (0,0, xMax, yMax);
Randomize;
For i: =1 to nr_obiecte do begin x [i]: =raza+Random (xMax-2*raza); y [i]:
=raza+Random (yMax-2*raza); sensx [i]: =-l+(i mod 2)*2; sensy [i]: =-sensx [i];
Deseneaz (x [i], y [i], i); end;
Repeat
For i: =1 to nr_obiecte do begin
Deseneaz (x [i], y [i], i); xtmp: =x [i]+pasx*sensx [i]; ytmp: =y
[i]+pasy*sensy [i];
If (xtmp>raza) and (xtmp<xMax-raza) then x [i]: =xtmp else sensx [i]: =sensx [i];
If (ytmp>raza) and (ytmp<yMax-raza) then y [i]: =ytmp else sensy [i]: =sensy [i];
Deseneaz (x [i], y [i], i);
Delay (100-l0*viteza); end;

Until KeyPressed;
Readln;
CloseGraph; end else
Writeln (Graphics error:, GraphErrorMsg (ErrCode); end.
/Program C de umplere a ecranului text prin acces direct la memoria
ecran include <dos. H> include <conio. H> struct scrcar {unsigned char car,
atrib;
} far *ecran; int lin, col; int culoare=BLUE, fundal=LIGHTGRAY; void main
(void){ecran= (struct scrcar far *) MK_FP (0xb800,0); for (lin=0; lin<25; lin+) for
(col=0; col<80; col+) {ecran [lin*80+col]. Car=*; ecran [lin*80+col].
Atrib=fundal*16+culoare;
} getch ();
Program Acces_direct_ecran_grafic320_200;
{Fiecare jumtate de ecran se genereaz din cealalt jumtate pe baza
proprietilor automatelor celulare asemntor ca n jocul Life}
Uses crt;
Const maxl=200-l; maxc=320-l; mijl=maxc div 2;
Type Matrice=array [0. Maxl, 0. Maxc] of byte; var scr: Matrice absolute
$A000:0; {adresa memoriei ecran n modul grafic 320x200} i, j, k, l, c, x: integer;
ok: char;
BEGIN asm {iniializeaz n mod grafic 320x200x250 NU n
640x400x256} mov ah, 0 mov al, 13h int 10h; end; randomize; x: =random
(maxc); for k: =1 to 2 do for i: =0 to maxl do for j: =0 to mijl do scr [i, j+k*mijl]:
=random (maxc); k: =0; repeat repeat for i: =0 to maxl do for j: =0 to mijl do
begin l: =i; c: =j+k*mijl; if (scr [(l-l) mod maxl, c] <scr [l, c]) and scr [l, (c-l) mod
mijl] <scr [l, c]) then scr [i, j+(k+1) mod 2)*mijl]: = (scr [(l-l) mod maxl, c]+scr [l,
(c-l) mod mijl]+ x) div 3-l else if (scr [l, (c+1) mod mijl] >scr [l, c]) and scr [(l+1)
mod maxl, c] >scr [l, c]) then scr [i, j+(k+1) mod 2)*mijl]: = (scr [(l+1) mod maxl,
c]+scr [l, (c+1) mod mijl]+ x) div 3+1 else scr [i, j+(k+1) mod 2)*mijl]: =scr [l, c]+1;
end; k: = (k+1) mod 2; until keypressed; ok: =readkey; x: =random (maxc); if
ok<>#27 then ok: =readkey; until ok=#27; readln;} asm {nchide modul grafic}
mov ax, 0 int 10h end;
END.
Program Mouse; {Gestionarea mouse-ului prin apelul ntreruperii de
sistem $33} uses Crt, Graph, Dos; var grDriver, grMode, ErrCode: Integer;
mfunc, buton, mx, my, xf, yf, x, y: word; xi, yi: integer; s1, s2, s3: string [5];
P: pointer;
Size: Word;
{ntr $33, nR. Fctiei dorite n AX:
00 mouse reset
01 cuplare cursor mouse (vizibil)
02 decuplare cursor mouse (ascuns)
03 determ. Unei apsri pe tasta i semnalare poziie
04 poziionarea cursorului de mouse
05 inforM. Suplim. Despre apsarea tastelor
06 inreg. Tastelor de mouse eliberate

07 stabilire domeniu orizontal (minim i maxim)


|| -vertical || - || 09 selectare cursor grafic
10 selectare cursor text
13/14 emulare creion optic conectat/deconectat
15 stabilire sensibilitate mouse
29 fixarea paginii ecran n care mouse-ul e vizibil
30 afiarea || - || - || - || procedure MouseReg; var reg:
registers; begin reg.ax: =mfunc; reG. Bx: =buton; reg.cx: =mx; reG. Dx: =my;
ntr ($33, reg); mfunc: =reg.ax; buton: =reG. Bx; mx: =reg.cx; my: =reG. Dx;
end;
} procedure MouseAsm; ASSEMBLER;
ASM
MOV AX, mfunc
MOV BX, buton
MOV CX, mx
MOV DX, my
INT $33
MOV mfunc, AX
MOV buton, BX
MOV mx, CX
MOV my, DX end;
Begin grDriver: = Detect;
InitGraph (grDriver, grMode,);
ErrCode: = GraphResult; if ErrCode = grok then begin if mem [memW [0:
$ce+2]: memW [0: $ce]] =$cf then begin outtext (Mouse-ul nu este instalat!);
readln; closegraph; halt; end; mfunc: =0; mouseasm; {iniializare} mfunc: =1;
mouseasm; {vizibil} mfunc: =3; mouseasm; xi: =mx; yi: =my; setactivepage (1);
rectangle (xi, yi, mx, my);
Size: = Imagesize (xi, yi, mx, my);
GetMem (P, Size); {Get memory from heap}
GetImage (xi, yi, mx, my, P^); putimage (xi, yi, P^, XORput); setactivepage
(0);
PutImage (100, 100, P^, ORPut); repeat mouseasm; xi: =mx; yi: =my;
while buton=1 do begin
PutImage (100, 100, P^, XORPut); mouseasm; setactivepage (1); rectangle
(xi, yi, mx, my);
Size: = Imagesize (xi, yi, mx, my);
GetMem (P, Size); {Get memory from heap}
GetImage (xi, yi, mx, my, P^); putimage (xi, yi, P^, XORput); setactivepage
(0);
PutImage (100, 100, P^, ORPut); end; until keypressed; mfunc: =2;
mouseasm; {decuplare mouse}
CloseGraph; end else
WriteLn (Graphics error:, GraphErrorMsg (ErrCode); end.

/Program C de generare a efectului grafic-plasma-prin utilizarea unor


funcii ale modului grafic include <graphics. H> include <stdlib. H> include
<stdio. H> include <conio. H> include <math. H> include <dos. H> int MX, MY;
int p1, p2, p3, p4, r1, r2, r3, r4; void plasma (int x1, int x2, int y1, int y2){if (x2x1<2) return; p1=getpixel (x1, y1); p2=getpixel (x2, y1); p3=getpixel (x2, y2);
p4=getpixel (x1, y2); r1=random (4); r2=random (4); r3=random (4); r4=random
(4); if (getpixel (x1+(x2-x1)/2, y1) =0) putpixel (x1+(x2-x1)/2, y1, (p1+p2)/2+r1);
if (getpixel (x2, y1+(y2-y1)/2) =0) putpixel (x2, y1+(y2-y1)/2, (p2+p3)/2+r2); if
(getpixel (x1+(x2-x1)/2, y2) =0) putpixel (x1+(x2-x1)/2, y2, (p3+p4)/2+r3); if
(getpixel (x1, y1+(y2-y1)/2) =0) putpixel (x1, y1+(y2-y1)/2, (p4+p1)/2+r4);
putpixel (x1+(x2-x1)/2, y1+(y2-y1)/2, (p1+p2+p3+p4)/4+random (2); plasma
(x1, x1+(x2-x1)/2, y1, y1+(y2-y1)/2); plasma (x1+(x2-x1)/2, x2, y1, y1+(y2y1)/2); plasma (x1, x1+(x2-x1)/2, y1+(y2-y1)/2, y2); plasma (x1+(x2-x1)/2, x2,
y1+(y2-y1)/2, y2); int gdriver = VGA, gmode = VGAHI, errorcode, i; double
red=20, green=30, blue=40; struct palettetype pal; void main (void){
/* select a driver and mode that supports the use */
/* of the setrgbpalette function. */
/* initialize graphics and local variables */initgraph (&gdriver, &gmode,
);
/* read result of initialization */errorcode = graphresult (); if (errorcode! =
grok) /* an error occurred */
{printf (Graphics error: %s, grapherrormsg (errorcode); printf (Press any
key to halt:); getch (); exit (1); /* terminate with an error code */
/* grab a copy of the palette */getpalette (&pal); for (i=0; i<pal. Size; i+)
setrgbpalette (pal. Colors [i], red+i, green+i, blue+i); randomize ();
MX=getmaxx (); MY=getmaxy (); putpixel (0,0, MAXCOLORS/2); putpixel
(0, MY, MAXCOLORS/2); putpixel (MX, 0, MAXCOLORS/2); putpixel (MX, MY,
MAXCOLORS/2); plasma (0, MX, 0, MY);
/rotate palette while (! Kbhit (){for (i=0; i<pal. Size; i+) setrgbpalette (pal.
Colors [i], (int) red+i, (int) green+i, (int) blue+i); red+=0.5; green+=1; blue+=1.5;
closegraph ();
Program arpe;
{Program de joc demonstrativ: arpele culegtor de numere. El este
dirijat cu ajutorul sgeilor, viteza sa de micare poate fi modificata
corespunztor n orice moment folosind tastele de la 1 la 9.}
Uses Crt;
Const se=#219; lungmax=95; maxnext=10; xlimit= [1,80]; ylimit= [1,25];
Var sx, sy: array [1.95] of byte; c: char; i, primul, ultimul, next, tdelay,
idelay: integer; xnext, ynext: byte;
Begin clrscr; randomize; for i: =1 to 79 do begin gotoxy (i, 1); write (se);
gotoxy (i, 25); write (se); end; for i: =1 to 24 do begin gotoxy (1, i); write (se);
gotoxy (80, i); write (se); end; primul: =2; ultimul: =1; for i: =primul downto
ultimul do begin sx [i]: =40; sy [i]: =13; end; next: =0; idelay: =100; for i:
=primul downto ultimul do begin gotoxy (sx [i], sy [i]); write (se); end; c:
=readkey; while next<maxnext do begin xnext: =2+random (78); ynext:
=2+random (23); inc (next); gotoxy (xnext, ynext); write (next); repeat if

keypressed then begin c: =readkey; tdelay: =idelay; if c=#0 then c: =readkey;


end else tdelay: =tdelay*97 div 100; case c of 1.9: idelay: =100+100 div (ord
(c)-ord (1)+1);
#75: {stnga} begin gotoxy (sx [ultimul], sy [ultimul]); write ( ); if
primul=lungmax then begin sx [1]: =sx [primul]-l; sy [1]: =sy [primul]; primul:
=1 end else begin inc (primul); sx [primul]: =sx [primul-l]-l; sy [primul]: =sy
[primul-l]; end; if ultimul=lungmax then ultimul: =1 else inc (ultimul); end;
#77: {dreapta} begin gotoxy (sx [ultimul], sy [ultimul]); write ( ); if
primul=lungmax then begin sx [1]: =sx [primul]+1; sy [1]: =sy [primul]; primul:
=1 end else begin inc (primul); sx [primul]: =sx [primul-l]+1; sy [primul]: =sy
[primul-l]; end; if ultimul=lungmax then ultimul: =1 else inc (ultimul); end;
#72: {sus} begin gotoxy (sx [ultimul], sy [ultimul]); write ( ); if
primul=lungmax then begin sx [1]: =sx [primul]; sy [1]: =sy [primul]-l; primul:
=1 end else begin inc (primul); sx [primul]: =sx [primul-l]; sy [primul]: =sy
[primul-l]-l; end; if ultimul=lungmax then ultimul: =1 else inc (ultimul); end;
#80: {jos} begin gotoxy (sx [ultimul], sy [ultimul]); write ( ); if
primul=lungmax then begin sx [1]: =sx [primul]; sy [1]: =sy [primul]+1; primul:
=1 end else begin inc (primul); sx [primul]: =sx [primul-l]; sy [primul]: =sy
[primul-l]+1; end; if ultimul=lungmax then ultimul: =1 else inc (ultimul); end;
end; if primul > ultimul then for i: =primul downto ultimul do begin gotoxy (sx
[i], sy [i]); write (se); if (sx [primul] =sx [i]) and (sy [primul] =sy [i]) and
(i<>primul) then c: =#27; end else begin for i: =ultimul to lungmax do begin
gotoxy (sx [i], sy [i]); write (se); if (sx [primul] =sx [i]) and (sy [primul] =sy [i]) and
(i<>primul) then c: =#27; end; for i: =1 to primul do begin gotoxy (sx [i], sy [i]);
write (se); if (sx [primul] =sx [i]) and (sy [primul] =sy [i]) and (i<>primul) then c:
=#27; end; end; if (sx [primul] n xlimit) or (sy [primul] n ylimit) then c: =#27;
delay (tdelay); until (c=#27) or (sx [primul] =xnext) and (sy [primul] =ynext);
sound (next*30); if c=#27 then next: =maxnext else if ultimul-next <= 0 then
begin for i: =lungmax+ultimul-next to lungmax do begin sx [i]: =sx [ultimul]; sy
[i]: =sy [ultimul]; end; for i: =1 to ultimul do begin sx [i]: =sx [ultimul]; sy [i]: =sy
[ultimul]; end; ultimul: =lungmax+ultimul-next; end else begin for i: =ultimulnext to ultimul do begin sx [i]: =sx [ultimul]; sy [i]: =sy [ultimul]; end; ultimul:
=ultimul-next; end; delay (tdelay); nosound; end; {next < maxnext}
End.
Program Scan_Taste;
{Program ce demonstreaz posibilitatea de acces la codurile de scanare
ale tastaturii. Este indicat sa fie lansat n mod DOS i nu de sub Windows.}
Uses Crt, Dos;
Var tasta: byte;
KbdIntvec: procedure;
{$F+}
Procedure KeyClick; interrupt; begin
Port [$20]: =$20; {resetarea portului de acces al tastaturii} end;
Begin
GetIntvec ($9, @KbdIntvec); {modificarea ntreruperii de tastatura}

SetIntvec ($9, Addr (KeyClick); {cu o procedura proprie inofensiva} tasta:


=0; repeat repeat until tasta<>Port [$60]; tasta: =Port [$60]; gotoxy (20,2); write
(tasta:3); until tasta=129;
SetIntvec ($9, @KbdIntvec);
End.
Program Taste_muzicale_V2;
{Program demonstrativ de folosire muzicala a tastaturii pe post de orga.
Pentru o mai buna nelegere este utila consultarea programului
scantast.pas}
Uses Crt, Dos;
Const
Nota_Do: array [1.4] of integer= (33,66,132,264);
Raport: array [1.10] of real=
(24/24,27/24,30/24,32/24,36/24,40/24,45/24, Nota: array [1.10] of string [3]
= (Do, Re, Mi, Fa, Sol, La, Si, Do, Re, Mi);
CodT: array [1.4] of byte= (44,30,16,2);
Type Pixel=Record atrib: byte; car: char; end;
Var tasta: byte; i: integer;
KbdIntvec: procedure; ecran: array [1.25,1.80] of Pixel absolute
$b800:0000;
{$F+}
Procedure KeyClick; interrupt; begin
Port [$20]: =$20; end;
Begin
Clrscr;
GetIntvec ($9, @KbdIntvec);
SetIntvec ($9, Addr (KeyClick); tasta: =0; repeat repeat until tasta<>Port
[$60]; tasta: =Port [$60]; if (tasta>=CodT [1]) and (tasta<CodT [1]+10) then begin
gotoxy (5*(tasta+l-CodT [1]), 24); write (Nota [tasta+l-CodT [1]]); sound (Trunc
(Raport [tasta+l-CodT [1]] * Nota_Do [1]) end else if (tasta>=CodT [2]) and
(tasta<CodT [2]+10) then begin gotoxy (5*(tasta+l-CodT [2]), 22); write (Nota
[tasta+l-CodT [2]]); sound (Trunc (Raport [tasta+l-CodT [2]] * Nota_Do [2]) end
else if (tasta>=CodT [3]) and (tasta<CodT [3]+10) then begin gotoxy (5*(tasta+lCodT [3]), 20); write (Nota [tasta+l-CodT [3]]); sound (Trunc (Raport [tasta+lCodT [3]] * Nota_Do [3]) end else if (tasta>=CodT [4]) and (tasta<CodT [4]+10)
then begin gotoxy (5*(tasta+l-CodT [4]), 18); write (Nota [tasta+l-CodT [4]]);
sound (Trunc (Raport [tasta+l-CodT [4]] * Nota_Do [4]) end else nosound; until
tasta=129;
SetIntvec ($9, @KbdIntvec);
End.
Program Testare_VESA;
{Program de testare a posibilitilor de lucru a plcii grafice n standardul
VESA.} uses dos; type tmoduri=array [1.256] of word; var imod, vseg, x, y: word;
cbank, c: longint; rg: registers; ntbanks: longint; opt: char; vesabuf: record sign:
longint; vers: word; oem: pchar; capab: longint; list: ^tmoduri; reserv: array
[1.512] of byte end; vesamod: record attr: word; wina, winb: byte; gran, winsiz,

sega, segb: word; pagfun: pointer; bytes, width, height: word; charw, charh,
planes, bits, nbanks, model, sbank, nrimpg, reservb, rms, rfp, gms, gfs, bms,
bfs: byte; reserv: array [1.512] of byte end; function hexa (v: word): string; const
s: string [16] =0123456789abcdef; function hexb (b: byte): string; begin hexb:
=s [b div 16+1]+s [b mod 16+1]; end; begin hexa: =hexb (hi (v)+hexb (lo (v); end;
procedure setbank (b: longint); begin vseg: =$a000; if b<>cbank then with rg,
vesamod do begin cbank: =b; ax: =$4f05; bx: =0; dx: =b*64 div gran; ntr (16,
rg); end; end; procedure putpixel (x, y: word; cul: longint); var l: longint; m, z:
word; begin with rg, vesamod do case bits of
4: begin l: =longint (bytes)*y+x div 8; port [$3ce]: =3; port [$3cf]: =0; port
[$3ce]: =5; port [$3cf]: =2; port [$3ce]: =8; port [$3cf]: =128 shr (x and 7);
setbank (l shr 16); z: =mem [vseg: word (l)]; mem [vseg: word (l)]: =cul; end;
8: begin l: =longint (bytes)*y+x; setbank (l shr 16); mem [vseg: word (l)]:
=cul; end;
15,16: begin l: =longint (bytes)*y+x*2; setbank (l shr 16); memw [vseg:
word (l)]: =cul; end;
24: begin l: =longint (bytes)*y+x*3; z: =word (l); m: =l shr 16; setbank (m);
if z<$fffe then move (cul, mem [vseg: z], 3) else begin mem [vseg: z]: =lo (cul); if
z=$ffff then setbank (m+1); mem [vseg: z+1]: =lo (cul shr 8); if z=$fffe then
setbank (m+1); mem [vseg: z+2]: =cul shr 16; end; end; end; end; begin with rg,
vesabuf, vesamod do begin ax: =$4f00; es: =seg (vesabuf); di: =ofs (vesabuf);
sign: =$41534556; ntr (16, rg); if al<>$4f then begin writeln (Standardul VESA
nu e implementat); exit end; imod: =1; while list^ [imod] <>$ffff do begin ax: =3;
ntr (16, rg); ax: =$4f01; cx: =list^ [imod]; es: =seg (vesamod); di: =ofs (vesamod);
ntr (16, rg); if attr and 16<>0 then begin writeln (oem, VESA Versiune , hi
(vers), ., lo (vers); writeln (hexa (list^ [imod]), Rezoluie: , width, x , height,
Culori: , longint (1) shl bits); write (Doriti testare (D/N)? ); readln (opt); end
else opt: =N; if upcase (opt) =D then begin ax: =$4f02; bx: =list^ [imod]; ntr
(16, rg); cbank: =-l; ntbanks: =longint (bytes)*height div gran div 1024; for x: =0
to ntbanks do begin setbank (x); mem [$a000: $ffff]: =0; fillchar (mem [$a000:0],
$ffff, 0); end; case bits of
4,8: c: =15;
15: c: =32767;
16: c: =65535;
24: c: =longint (1) shl 24-l; end; for x: =0 to width-l do begin putpixel (x,
0, c); putpixel (x, height-l, c); end; for y: =0 to height-l do begin putpixel (0, y, c);
putpixel (width-l, y, c); end; for x: =0 to 191 do for y: =0 to 191 do begin case
bits of
4: c: = (y div 48)*4+x div 48;
8: c: = (y div 12)*4+x div 12;
15,16: c: = (y div 6)*(1 shl rfp)+x div 6;
24: c: =longint (x)*65536+y; end; putpixel (x+4, y+4, c); end; readln; end;
inc (imod); end; ax: =3; ntr (16, rg); end; end.
Curioziti i trucuri de programare
Pentru o ct mai complet prezentare a programrii n C nu puteam evita
prezentarea unor curioziti i ale unor trucuri de programare C. Acelai lucru

este valabil i pentru limbajul Pascal dar este acesta este oarecum ieit din
mod. Numrul foarte mare de astfel de invenii a condus la organizarea nc
din 1984 a unui concurs internaional de programare numit foarte sugestiv The
International Obfuscated C Code Contest IOCCC adic Concursul
internaional de programare ofuscat C (nclcit i confuz). Participanii la
acest concurs ofer n fiecare an adevrate perle de programare C ce dovedesc,
pe lng serioase cunotine de C, aptitudinile extraordinare i fiabilitatea
compilatorului C. Multe din capodoperele acestui concurs au fost apoi
inscripionate pe tricouri sau pungi, spre deliciul fanilor programrii C.
Aceast pasiune are totui i o latur serioas ce poate fi sesizat n
programarea sub platformele (sistemele de operare) gen Unix. n aceste sisteme
toate programele circul nu numai sub forma de cod executabil ci i n sursa
original C. Ascunderea unor informaii despre programarea sistem de ochii
celor periculos de curioi este astfel dificil. Dar iat c acest tip de
programare ofuscat face acest lucru posibil! Numai cei foarte pasionai i
prind urechile n descifrarea unor astfel de programe intenionat nclcite.
Altfel spus, secretul unor astfel de programe se ascunde chiar n rebusul din
faa ochilor cititorului.
Recomandm acest capitol n special fanilor programrii C i celor foarte
pasionai.
/Un simplu Hello world! dar care arata o surprinztoare interpretare a
compilatorului C include <stdio. H> char a [] =Hello world!; int i; void main
(void){for (i=0; a [i]! =; i+) putchar (i [a]); /! A [i] <=> *(a+i) <=> *(i+a) <=> i [a]!
/Iat unde conduce folosirea tipului de date float:
/c este foarte diferit de w?!
/Putem spune ca acesta este un bug al C-ului?
Include <stdio. H> float a=12345679., b=12345678., c=a*a-b*b, u=a*a,
v=b*b, w=u-v; void main (){printf (a=%f, b=%f=%f, w=%f, a, b, c, w);
/Iat i varianta corecta n care nu se produce nici o trunchiere:
include <stdio. H> long double a=12345679., b=12345678., c=a*a-b*b, u=a*a,
v=b*b, w=u-v; void main (){printf (a=%Lf, b=%Lf=%Lf, w=%Lf, a, b, c, w);
/Acest program este capabil s-i duplice identic la ieire codul sursa C
fara a efectua nici o
/citire de nicieri. Are deci caracteristica unui virus, se auto-replica!
Include <stdio. H> char *s [] = { #include <stdio. H>, char *s [] = {, void
main (void){, int i; char *ps;, puts (s [0]); puts (s [1]);, for (i=0; i<10; i+),
{putchar (34); for (ps=s [i]; *ps; ps+) putchar (*ps);, putchar (34); putchar (, );
putchar (10);}, putchar (34); for (ps=s [10]; *ps; ps+) putchar (*ps); putchar
(34); putchar (10);, putchar (} ); putchar (;); putchar (10);, for (i=2; i<11; i+)
puts (s [i]); putchar (} );
}; void main (void){int i; char *ps; puts (s [0]); puts (s [1]); for (i=0; i<10; i+)
{putchar (34); for (ps=s [i]; *ps; ps+) putchar (*ps); putchar (34); putchar
(, ); putchar (10);} putchar (34); for (ps=s [10]; *ps; ps+) putchar (*ps); putchar
(34); putchar (10); putchar (} ); putchar (;); putchar (10); for (i=2; i<11; i+) puts
(s [i]); putchar (} );
/Program C surpriza (ales dintre cele de la IOCCC)

/Ce face acest program ntr-o singura linie?


Int i; main (){for (; i [] <i; +i){-i;}]; read (---, i+hello, world!, ///);}
read (j, i, p){write (j/p+p, ij, i/i);}
/Alt program C surpriza (ales dintre cele de la IOCCC)
/Ce face acest program ntr-o singura linie?
Main (v, c) char*c; {for (v [c+] =Hello, world!); (! C)[*c] & (v-||-c&execlp
(*c, *c, c [! C]+! C,! C); *c=! C) write (! *c, *c,! *c);}
/Putei decripta acest program C de trei linii? Execuia lui arata clar ce
face, ntrebarea este/insa cum face?!
Define P (X) j=write (1, X, 1) define C 39 int M [5000] = {2}, *u=M, N
[5000], R=22, a [4], l [] = {0, -l, C-l, -l}, m [] = {1.
C, -l, C}, *b=N, d=N, c, e, f, g, i, j, k, s; main (){for (M [i=C*R-l] =24;
f|d>=b;){c=M [g=i]; i=e; for (s=f=0; s<4; s+) if (k=m [s]+g) >=0&k<C*R&l [s]!
=k%C& (! M [k] ||! J&c>=16! =M [k] >=16) a [f+
] =s; if (f){f=M [e=m [s=a [rand ()/(1+2147483647/f)]]+g]; j=j<f? F: j; f+=c&l6*! J; M [g] = c|1<s; M [*d+=e] =f|1< (s+2) %4;} else e=d>b+? B [-l]: e;} P ( ); for
(s=C; s; P (_)
P ( ); for (; P (), RP (|) for (e=C; eP (_ +(*u+/8) %2) P (| +(*u/4) %2
Confruntare de opinii: Informatic versus Matematic
Dei poate prea neobinuit pentru o culegere de probleme, am inut
totui s introducem acest capitol pentru a-l pune n gard pe nceptorii
ntr-ale informaticii de capcana confruntrilor sterile, pro informatic sau
contra matematicii.
E bine ca ei s afle c dei informatica este studiat ca tiin de sine
stttoare ea este totui oficial considerat i clasificat ca o sub-disciplin a
matematicii. Desigur, acest fapt zgndre orgoliul unor informaticieni pursnge care, nenelegnd c aceste clasificri sunt pur formale, intr deseori n
confruntri aprinse de opinii cu matematicienii conservatori pe tema
apartenenei teoriilor informatice la matematic. Aceste sterile discuii n
contradictoriu nu pot fi ns auzite n mediile cu adevrat tiinifice, acolo unde
se ntlnesc cei mai pasionai i mai profunzi cercettori ai ambelor discipline.
Putem rezuma opiniile contradictorii, pe care le-am auzit i noi deseori,
sub forma urmtoarelor dou ntrebri care formuleaz n dou moduri
distincte aceeai dilem:
1. Se bazeaz informatica n ntregime pe matematic sau ea are o
existen separat?
2. Se poate face informatic fr s cunoti matematic foarte bine?
nainte de a oferi rspuns, vom lmuri mai nti o alt confuzie ceea ce
ne va permite s rspundem mai uor la cele dou ntrebri: care este diferena
dintre informatic i tiina calculatoarelor (computer science)?
Se tie c exist n facultile de la noi din ar dou (chiar trei) secii cu
profil informatic: secia de informatic la facultatea de tiine, secia de
calculatoare la facultatea de inginerie i, mai nou, secia de prelucrare
electronic a informaiei economice (informatic economic) la facultatea de
tiine economice. Sunt aceste secii esenial diferite?

S vedem o opinie cu greutate. Iat cuvintele academicianului Nicolae


Teodorescu despre informatic (am pus n eviden prin litere ngroate
cuvintele ce ni s-au prut eseniale): Calculatorul electronic are ns ca merit
esenial stimularea unui mod de gndire care atepta de veacuri un mijloc
tehnic prodigios pentru a da minii omeneti putina hotrtoare de a-l
introduce n strategiile investigative de avangard. Acesta este modul de
gndire algoritmic care permite sortarea, analiza i prelucrarea unui numr
mare de posibiliti, precum i alegerea celei sau celor mai potrivite care
conduc la rezultatul sau rezultatele urmrite, n studiul unor procese complexe
care trebuie s fie simplificate sau abandonate din lips de mijloace de
cercetare. Pentru promovarea acestei gndiri, calculatorul electronic nu era
ns suficient el nsui, ci avea nevoie de o serie de discipline tiinifice avnd
ca baz gndirea algoritmic. Astfel, n puinii ani de la introducerea
calculatorului electronic s-au format discipline constituind o nou ramur a
tiinei cu caractere mixte teoretice i tehnice, numit la un moment
informatic termen care a nlocuit pe cel iniial de tiin a calculului sau
tiin a calculatoarelor (computer science), care avea un neles mai precis, dar
n acelai timp mai restrns.
Vedem c, dintre cei toi termenii de specialitate ce se folosesc, cea mai
larg accepiune o are termenul de informatic. Ceilali termeni, cum sunt
tiina calculatoarelor i informatic economic, nu fac dect s nuaneze i s
particularizeze nelesul iniial mai general. tiina calculatoarelor abordeaz
informatica de pe poziii inginereti, ea primind un aport subtanial de la alte
discipline inginereti ca electronica, tiina prelucrrii semnalelor electrice sau
tiina telecomunicaiilor. Informatica economic utilizeaz noiuni cu caracter
strict economic sau din domeniul tiinelor sociale. Putem deduce c toate
aceste nuanri i specializri au aprut din necesitate, datorit impactului
deosebit pe care utilizarea pe scar larg a calculatoarelor l are asupra
sectoarelor societii.
Dac ns vom grupa disciplinele cu caracter informatic care se predau
simultan la fiecare din aceste secii diferite vom obine lista disciplinelor de
baz ale informaticii: Bazele informaticii, Programare, Structuri de date i
algoritmi, Sisteme de operare, Baze de date. Alte discipline, cum sunt
Arhitectura calculatoarelor, Reele de calculatoare, Ingineria programrii,
Inteligena artificial, Programarea orientat obiect, etc., sunt considerate a fi
discipline de specialitate n domeniu. De altfel, datorit acestor diferenieri i
specializri ntre secii, absolvenii seciilor respective se vor numi
programatori, ingineri de sistem sau economiti-lnformaticieni. S recunoatem
c s-ar ajunge la o adevrat babilonie dac nu numai matematicienii ci i
inginerii sau economitii i-ar disputa cu informaticienii puri ntietatea n
domeniile informatice ce le revin!
Rmne s rspundem la ntrebarea iniial (formulat n dou variante):
n ce msur se poate face informatic fr matematic? Privind lucrurile la fel
de pragmatic ca i mai sus, dac privim informatica ca pe o meserie (cu subspecializrile ei) iar matematica tot ca pe o meserie, este evident c nu este
necesar s cunoti dou meserii pentru a o profesa bine pe una dintre ele. Deci,

poi fi un bun programator, inginer de sistem sau economist-lnformatician fr


s ai cunotine serioase de matematic. Trebuie ns s spunem, spre
dezamgirea celor lenei, c este exclus s fi lipsit de cunotine de
matematic pentru c atunci nu ai avea cum s-i nsueti cunotinele
minimale pe care le ofer disciplinele de baz ale informaticii nirate mai sus.
Aceste discipline de baz fac apel la modele i metode matematice considerate
deja clasice i care sunt privite ca i cultur matematic indispensabil oricrui
specialist n domeniu. Cum s-a ajuns la acest fapt, cum de gseti matematic
n economie i n inginerie, dar nu i invers?
Este marele atu al matematicii: capacitatea de extragere a esenialului i
capacitatea de abstractizare (adic, capacitatea de modelare matematic). De
altfel, este cunoscut faptul c cunotinele matematice eseniale, indiferent de
forma n care ele sunt formalizate sau simbolizate, sunt aceleai pentru orice
civilizaie terestr. Sau extraterestr! Se tie c mesajele de pe sondele spaiale
americane, ce au prsit deja sistemul nostru solar, destinate unor posibile
civilizaii extraterestre sunt scrise n limbaj matematic. S nu ne mai mirm
atunci c fr matematic nu se poate!.
Ca s nu cread cineva c facem pledoarie pentru matematic, aici ntr-o
lucrare de informatic, v facem cunoscut c, din contr, n cartea sa Vrsta de
aur a matematicii, care prezint n 11 capitole cele mai mari realizri ale
matematicii din ultimii 50 de ani, profesorul i cercettorul Keith Devlin de la
universitile Stanford i Pittsburgh a introdus un capitol cu titlul Eficiena
algoritmilor i n alte cinci capitole arat rolul important pe care l-a avut
folosirea calculatorului n creterea eficienei i validrii cercetrii pur
matematice. Adic, ase din unsprezece capitole cer pentru a fi nelese bine nu
numai cunotine de matematc ci i de informatic. Iar unul din cele cinci
capitole, Problema celor patru culori, accentueaz rolul esenial (indispensabil)
al programrii n demonstrarea cu ajutorul calculatorului a uneia din cele mai
celebre probleme de matematic. Aceast demonstraie a creat o bre
serioas n gndirea matematicienilor care au fost nevoii s ia foarte n serios
concurena pe care calculatorul (bine dirijat de programatori) a nceput s
le-o fac. Iat chiar cuvintele profesorului de matematic Keith Devlin scrise n
ncheierea capitolului respectiv (ce explic modul n care s-a fcut demonstraia
cu calculatorul): Matematica nu va mai fi niciodat aceeai.!
ncheiem cu convingerea c, cei care au parcurs cu interes aceast
culegere, inclusiv acest capitol, nu vor mai putea fi tentai de controverse
uoare informatic versus matematic. Credem c s-a putut vedea cum, cei
care sunt deasupra acestor discuii sterile, au sesizat cu nelepciune c
matematica mama informaticii se mbogete acum din plin prin
intermediul informaticii, punndu-le astfel pe picior de egalitate cele dou
discipline.
Noi le urm tuturor celor studioi s-i concentreze toat energia pasiunii
lor pentru nvarea i stpnirea cu miestrie a artei programrii. Ea poate fi
considerat ca fiind prima treapt important spre orizontul ctre care tinde
tiina informaticii.
Bibliografie, adrese i locaii de interes pe Internet

Internetul e foarte mare, stufos i, de multe ori, labirintic. Tocmai de


aceea, ne-am gndit s venim n ajutorul celor foarte pasionai de informatic i
de matematica aplicat n informatic. Oferim n continuare doar cteva adrese
pe care i noi le-am utilizat cu succes. Fiecare din aceste site-uri conine la
rndul lui liste de adrese i legturi (links) ctre alte site-uri cu subiecte
asemntoare. Iat, avei la dispoziie un capt al ghemului!

SFRIT

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