Documente Academic
Documente Profesional
Documente Cultură
Anonim-Culegere Probleme de Informatica 10
Anonim-Culegere Probleme de Informatica 10
Informatic
CUPRINS:
15
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
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
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:
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
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
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
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);
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.
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
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
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
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.
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.
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);
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
/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);
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
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(n-l)
+M=Multiplu (2n) daca M mod 2n=2(n-l) atunci soluia este 1M=10(n-l)+M=2(nl)*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;
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);
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;
{$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]!
SFRIT