Sunteți pe pagina 1din 147

Mugurel Ionu Andreica

Elemente de algoritmic probleme i soluii

Cuprins

Introducere....................................................................................................... 2
Capitolul 1. Programare Dinamic .................................................................. 3
Capitolul 2. Greedy i Euristici ..................................................................... 20
Capitolul 3. Grafuri........................................................................................ 37
Capitolul 4. Structuri de Date. ....................................................................... 53
Capitolul 5. iruri de Caractere ..................................................................... 62
Capitolul 6. Geometrie Computational ........................................................ 70
Capitolul 7. Combinatoric i Teoria Numerelor .......................................... 93
Capitolul 8. Teoria Jocurilor........................................................................ 112
Capitolul 9. Probleme cu Matrici................................................................. 117
Capitolul 10. Probabiliti............................................................................ 119
Capitolul 11. Probleme Ad-Hoc .................................................................. 122
Capitolul 12. Probleme Interactive .............................................................. 133
Capitolul 13. Transformri, Evaluri, Ecuaii i Sisteme de Ecuaii ........... 140
Capitolul 14. Backtracking .......................................................................... 144
Bibliografie .................................................................................................. 146

Editura CIBERNETICA
Bucureti 2011
ISBN: 978-606-8288-15-4

Introducere
Exist multe cri care propun un numr mare de probleme spre rezolvare cititorilor,
n timp ce prezint doar soluii ale unui numr mic dintre problemele propuse. Prerea
proprie este c aceste cri nu i justific existena dect parial. Internet-ul este plin de
enunuri de probleme, de grade de dificultate variate (vezi doar cteva dintre link-urile de la
sfritul acestei cri), majoritatea nefiind nsoite de explicaii care s ajute la rezolvarea lor.
n ziua de azi nu mai ducem lips de materiale de pregtire (existnd attea surse de
probleme online), ci de surse de explicaii bine structurate i comprehensibile.
Aceast carte a fost scris cu scopul de a suplini parial lipsa surselor de explicaii
algoritmice structurate i comprehensibile. Capitolele crii abordeaz tematici variate i
prezint probleme avnd diverse grade de dificultate, nsoite de explicaii complete i
structurate spre a fi uor de lecturat i neles.
Cartea conine i o arhiv de materiale auxiliare (enunuri de probleme, programe
surs, descrieri de soluii, etc.) care au scopul de a complementa explicaiile structurate din
cadrul crii.
Problemele discutate n aceast carte au fost propuse la concursuri i olimpiade
colare, precum olimpiadele naionale din diverse ri, olimpiade internaionale, concursuri
ACM ICPC, etc. Soluiile prezentate sunt, n cea mai mare parte, elaborate n totalitate de
ctre autorul crii. Un numr mic de descrieri de soluii au fost preluate i adaptate de la
concursurile unde au fost propuse problemele respective. Problemele incluse n materialele
auxiliare conin cod surs i explicaii scurte realizate de ctre autor, ns conin, de
asemenea, soluiile oficiale (sau i alte soluii) ale problemelor respective.
Autorul este n prezent cadru didactic (ef de lucrri / lector) la Facultatea de
Automatic i Calculatoare, Universitatea Politehnica din Bucureti. Coninutul crii are la
baz experiena autorului de participant la multe concursuri naionale i internaionale de
informatic (olimpiada naional i internaional de informatic, finala mondial a
concursului ACM ICPC, etc.), precum i de membru al comisiei tiinifice la astfel de
concursuri (olimpiada naional de informatic, olimpiada de informatic a Europei Centrale,
olimpiada balcanic de informatic, concursul ACM ICPC regiunea Europa de Sud-Est,
concursuri .campion, etc.).

Capitolul 1. Programare Dinamic


Problema 1-1. 1expr (Happy Coding 2006, infoarena)
O 1-expresie este definit n felul urmtor:
1 sau ( 1-expresie ) sau 1-expresie + 1-expresie sau
1-expresie * 1-expresie sau 1-expresie ^ 1-expresie sau
1-expresie !
Dei n cadrul expresiei apare n mod direct doar numarul 1, rezultatele evalurii
operaiilor pot fi numere mai mari dect 1. Pentru a evalua o expresie aritmetic, trebuie
cunoscute prioritile operatorilor. Operatorul cu cea mai mic prioritate este + i realizeaz
operaia de adunare. Rezultatul 1-expresiei 1+1+1 este 3. Operatorul * este mai prioritar
dect operatorul + i realizeaz operaia de nmultire. Rezultatul 1-expresiei
1+1*(1+1)*(1+1+1)+(1+1)*(1+1) este 1+1*2*3+2*2=1+6+4=11. Operatorul ^ este mai
prioritar dect operatorii + i * i realizeaz operaia de ridicare la putere (A^B reprezint
A ridicat la puterea B). Rezultatul 1-expresiei (1+1)*(1+1+1)^(1+1)*(1+1+1)+(1+1) este
2*3^2*3+2=2*9*3+2=54+2=56. Spre deosebire de operatorii + i *, care au proprietatea
c A+B=B+A i A*B=B*A, n cazul ^ nu este neaprat adevrat c A^B=B^A. O alt
particularitate a acestui operator este ordinea de aplicare n cazul absenei parantezelor: el
este asociativ dreapta. De exemplu, A^B^C^D este echivalent cu A^(B^(C^D)). Rezultatul 1expresiei (1+1)^(1+1)^(1+1+1) este 2^2^3=2^(2^3)=2^8=256 i nu (2^2)^3=4^3=64. Astfel,
dac exist mai muli operatori ^ neseparai de paranteze, ordinea de efectuare a operaiilor
este de la dreapta ctre stnga. Operatorul cu prioritatea cea mai mare este ! i realizeaz
operaia factorial. Rezultatul 1-expresiei (1+1+1)! este 3!=6. Factorialul unui numar X,
notat X!, este definit ca 1*2*..*X. Rezultatul 1-expresiei (1+1)*(1+1+1+1)!^(1+1+1)!! este
2*4!^3!!=2*(4!)^(3!!)=2*(4!)^((3!)!)=2*24^(6!)=2*(24^720) (rezultatul este prea mare
pentru a fi afisat aici).
Lungimea unei 1-expresii este egal cu numrul de caractere ale irului ce reprezint 1expresia. Lungimea 1-expresiei (1+1)!^(1+1)*(1+1)+1 este 20. Dndu-se o secven de
maxim 10.000 de valori, s se determine pentru fiecare numr N din secven (N 38) o 1expresie de lungime minim al carei rezultat sa fie egal cu N.
Exemple:
N=1 => 1
N=3 => 1+1=1
N=200 => (1+1)^(1+1+1)*(1+(1+1+1+1)!)

Soluie: Pentru fiecare K de la 1 la 38 se calculeaz lungimea minim a unei 1-expresii care


are ca rezultat pe K, iar ultima operatie efectuat n cadrul acestei 1-expresii este +, *, ^ sau !
(deci se calculeaz 4 valori). Este important s se calculeze toate aceste 4 valori i nu doar o
singur lungime minima a unei 1-expresii care il are ca rezultat pe K, deoarece este posibil ca
acea 1-expresie s se obin folosind operatori de prioritate mic si, pentru a fi folosit n
cadrul unor expresii mai mari, s trebuiasca pus ntre paranteze.
De exemplu, 1-expresia de lungimea minima pentru 8 este: 1+1+(1+1+1)!. O alta scriere
a lui 8, care are lungimea cu 1 mai mare este : (1+1)^(1+1+1). ns aceast a doua
reprezentare a lui 8 poate fi folosit fr a fi inclus ntre paranteze, dac trebuie nmulit cu
o alt expresie, n timp ce prima scriere trebuie inclus ntre paranteze.

Relaiile de recuren se determin destul de uor (pentru un numr K):


pentru '+' : se ncearc combinarea a dou expresii al cror rezultat este X, respectiv K-X
pentru '*' : combinarea a dou expresii avnd valorile X, respectiv K/X
pentru '^' : combinarea a 2 expresii avnd valorile P i Q (unde PQ=K)
pentru '!' : numai n cazul n care K este factorialul unui numar (pentru limitele date, K
poate fi maxim 7! )
Se calculeaz cele 4 valori pentru fiecare numr de la 1 la limita maxim la inceput, apoi
pentru fiecare numr din secven doar se afiaz rezultatul (dac s-ar recalcula valorile
pentru fiecare numr, s-ar depasi limita de timp).
Pentru determinarea relaiilor de recuren vom considera cazul mai general, n care avem
Q operaii binare, op(1), ..., op(Q), n ordinea cresctoare a prioritilor lor (de ex.,
op(1)=+, ..., op(Q)=^). Vom calcula Lmin(i,j)=lungimea minim a unei expresii al crei
rezultat este i, astfel nct ultima operaie efectuat s fie op(j). Dup calcularea acestor
valori pentru un i, vom calcula valorile LRmin(i,j) i RLmin(i,j):
LRmin(i,0)=RLmin(Q+1)=+;
LRmin(i,1jQ)=min{LRmin(i,j-1), Lmin(i,j)} ; RLmin(i,j)=min{RLmin(i,j+1), Lmin(j)}.
Pentru a calcula o valoare Lmin(i,j) vom determina cele dou numere X i Y, astfel nct X
op(j) Y = i. Dac operaia op(j) este comutativ, atunci Lmin(i,j)=min{RLmin(X,j),
RLmin(X,1)+2}+min{RLmin(Y,j), RLmin(Y,1)+2}.
Dac op(j) nu este comutativ, dar este asociativ dreapta (cum este operaia de ridicare la
putere),
atunci
Lmin(i,j)=min{RLmin(X,j+1),
RLmin(X,1)+2}+min{RLmin(Y,j),
RLmin(Y,1)+2}.
Dac op(j) este necomutativ i asociativ stnga, atunci Lmin(i,j)=min{RLmin(X,j),
RLmin(X,1)+1}+min{RLmin(Y,j+1), RLmin(Y,1)+2}.

Problema 1-2. Pali (Happy Coding 2007, infoarena)


Orice cuvnt se poate mpri ntr-un numr mai mare sau mai mic de subsecvene,
fiecare subsecven fiind un palindrom (n cel mai ru caz, fiecare subsecven are lungimea
1). Fiind dat un cuvnt, determinai numrul minim de palindroame n care poate fi mprit
acesta.
Exemple:
aaaabbaa => 2 palindroame: aa + aabbaa
abccbazzz => 2 palindroame: abccba + zzz
Soluie: Se va calcula pmin[i]=numrul minim de palindroame n care poate fi mprit irul
format din primele i caractere ale sirului dat.
Soluia 1
Vom avea pmin[0]=0 i pmin[i]=1+min{pmin[j]|0 ji-1 i subirul format din
caracterele de pe poziiile j+1,..,i este palindrom }. Pentru a determina rapid dac subirul
dintre 2 poziii k i l este un palindrom, vom calcula o matrice Pali[k][l], avnd valorile 1 i
0, dac subirul dintre poziiile k i l este palindrom sau nu. Avem Pali[i][i]=1 i
Pali[i][i+1]=1, dac sir[i]=sir[i+1] (0, altfel).
Pentru l-k 2, Pali[k][l]=1, dac sir[k]= sir[l] i Pali[k+1][l-1]=1.
Soluia 2
Vom ncerca s calculm valorile pmin[i] treptat. Vom parcurge poziiile de la 1 la N
(lungimea irului) i vom incerca s ncepem un palindrom avnd centrul n poziia i (pentru
cazul unui palindrom de lungime impar), respectiv avnd centrul la poziiile i i i+1 (pentru

cazul unui palindrom de lungime par). Ideea important este c, atunci cnd ajungem la
poziia i, toate valorile pmin[j] (j<i) au fost calculate, iar valorile pmin[k] (k>i), au nite
valori pariale (adic valorile calculate nu sunt nc finale, ele mai putnd s scad ulterior).
Vom extinde treptat ct putem de mult un palindrom n jurul poziiei i (respectiv
poziiilor i i i+1); la fiecare pas de extindere, vom incrementa palindromul de la lungimea
curent L, la lungimea L+2 (pentru aceasta verificm caracterele de la capatele
palindromului); nainte de a realiza extinderea, vom incerca s folosim palindromul curent n
cadrul unei solutii - mai exact, avem urmtoarele posibiliti: pmin[i+(L+1)/21]=min{pmin[i+(L+1)/2-1], pmin[i-(L+1)/2]+1} (pentru cazul lungimii impare), respectiv
pmin[i+L/2]= min{pmin[i+L/2], pmin[i-L/2]+1} poate fi folosit pentru a micora valoarea
lui pmin[i+L/2] (pentru cazul lungimii pare).
Complexitatea ambelor solutii este O(N2), ns a doua soluie merge mai repede, n
practic, deoarece ia n considerare numai palindroamele valide (care pot fi cel mult O(N2)).
Problema 1-3. Bitmap (Happy Coding 2007, infoarena)
Nite cercettori au inventat un mod de a codifica un bitmap de dimensiuni MxN
(1M,N11) sub forma unui ir de caractere. irul este, de fapt, o reprezentare a unor operaii
efectuate asupra bitmap-ului. Algoritmul de codificare este descris n continuare:
dac toate celulele bitmap-ului au culoarea 1, atunci codificarea este "1"
dac toate celulele bitmap-ului au culoarea 0, atunci codificarea este "0"
altfel, trebuie s alegeti una din urmtoarele modaliti pentru a codifica bitmap-ul:
o Codificare(B) = "A" + Codificare(B1) + Codificare(B2), unde "+" reprezint
operaia de concatenare, B1 este bitmap-ul rezultat prin pstrarea primelor M/2
linii ale bitmap-ului B i a tuturor coloanelor, iar B2 este bitmap-ul rezultat prin
pstrarea ultimelor M-(M/2) linii ale bitmap-ului B i a tuturor coloanelor
(astfel, B1 va avea M/2 linii i N coloane, iar B2 va avea M-(M/2) linii i N
coloane).
o Codificare(B) = "B" + Codificare(B1) + Codificare(B2), unde B1 este bitmapul rezultat prin pstrarea primelor N/2 coloane ale bitmap-ului B i a tuturor
liniilor, iar B2 este bitmap-ul rezultat prin pstrarea ultimelor N-(N/2) linii ale
bitmap-ului B i a tuturor liniilor (astfel, B1 va avea M linii i N/2 coloane, iar
B2 va avea M linii i N-(N/2) coloane).
o Codificare(B) = "C" + Codificare(B1) + Codificare(B2), unde B1 este bitmap-ul
rezultat prin pstrarea tuturor liniilor cu numere impare ale bitmap-ului B
(liniile sunt numerotate ncepnd de la 1) i a tuturor coloanelor, iar B2 este
bitmap-ul rezultat prin pstrarea tuturor liniilor cu numere pare ale bitmap-ului
B i a tuturor coloanelor (astfel, B1 va avea M-(M/2) linii i N coloane, iar B2 va
avea M/2 linii i N coloane).
o Codificare(B) = "D" + Codificare(B1) + Codificare(B2), unde B1 este bitmap-ul
rezultat prin pstrarea tuturor coloanelor cu numere impare ale bitmap-ului B
(coloanele sunt numerotate ncepnd de la 1) i a tuturor liniilor, iar B2 este
bitmap-ul rezultat prin pstrarea tuturor coloanelor cu numere pare ale bitmapului B i a tuturor liniilor (astfel, B1 va avea M linii i N-(N/2) coloane, iar B2 va
avea M linii i N/2 coloane).
Fiind dat T (1T1500) teste (bitmap-uri), gasiti lungimea celei mai scurte codificri
pentru fiecare bitmap.

Soluie: O prim soluie ar consta n a ncerca toate cele 4 posibiliti de a codifica un bitmap
care nu are toate celulele de aceeai culoare. Aceast abordare de tip backtracking nu s-ar
incadra in limita de timp. Optimizarea necesar const n memoizarea strilor prin care
trecem n cadrul backtracking-ului (algoritmul nu se mai numeste backtracking acum, ci
devine un fel de programare dinamica). O stare este dat de 2 numere pe cel mult 11 bii, S1
i S2. Biii de 1 din S1 definesc liniile selectate din cadrul bitmap-ului initial, iar biii de 1 din
S2 definesc coloanele selectate din cadrul bitmap-ului iniial. Bitmap-ul definit de starea
(S1,S2) este reprezentat de celulele aflate la intersecia dintre liniile selectate de S1 i
coloanele selectate de S2. Prin urmare, vom calcula lmin[S1,S2]=lungimea minim a
codificrii bitmap-ului ce corespunde strilor S1 i S2.
lmin[2M-1,2N-1] va conine rezultatul cutat. Pentru ca soluia s se ncadreze n timp,
matricea cu valorile asociate fiecrei stri nu trebuie reiniializat la fiecare test. Se va folosi
o matrice suplimentar last_test, n care vom memora numrul ultimului test n care am ajuns
s calculm valoarea pentru starea (S1,S2). Dac ajungem la starea (S1,S2) n testul curent,
vom verifica valoarea lui last_test[S1,S2]. Dac aceasta este egal cu numrul testului curent,
nseamn c am calculat deja valoarea respectiv; n caz contrar, o vom calcula acum i vom
seta last_test[S1,S2] la numrul testului curent.
Problema 1-4. Palin (Olimpiada Internaional de Informatic 2000, enun modificat)
Se d un ir format din N (1N5000) de caractere. Pentru fiecare caracter al alfabetului c,
se d un cost cost(c). Determinai costul total minim al caracterelor ce trebuie inserate n ir,
pentru ca acesta s devin palindrom.
Exemplu:
N=5; sirul=Ab3bd => rspunsul este 2 (se obine irul Adb3bdA)
Soluie: Vom calcula urmtoarea matrice: Cmin[i,j]=costul total minim al caracterelor ce
trebuie inserate pentru ca subirul format din caracterele de pe poziile i, i+1, ..., j (ij) s
devin palindrom.
Avem Cmin[i,i]=0. Cmin[i,i+1]=0, dac ir[i]=ir[i+1] (ir[p]=al p-lea caracter al
irului dat); altfel, Cmin[i,i+1]=1. Pentru j>i+1, avem urmtoarele relaii:
dac ir[i]=ir[j], atunci Cmin[i][j]=Cmin[i+1][j-1]
altfel, Cmin[i][j]=min{cost(ir[i])+Cmin[i+1][j], cost(ir[j])+Cmin[i][j-1]}
Rspunsul l avem n Cmin[1][N]. Valorile Cmin[i][j] se calculeaz n ordinea lungimii
intervalului [i,j]. Observm c, atunci cnd calculm perechile (i,j) cu j-i+1=k, avem nevoie
doar de valorile pentru perechi (i,j), cu j-i+1=k-1. Astfel, n orice moment n cadrul
execuiei algoritmului, avem nevoie doar de O(N) valori n memorie.
O alt metod de rezolvare const n a calcula MinC[i][j]=costul total minim al
caracterelor ce trebuie inserate pentru ca subirul format din primele i caractere ale irului s
fie transformat n subirul format din ultimele j caractere ale irului. Avem MinC[0][j0]=0
i MinC[i0][0]=i. Pentru i1 i j1, avem:
dac ir[i]=ir[N-j+1], atunci MinC[i][j]=MinC[i-1][j-1]
altfel, MinC[i][j]=min{cost(ir[N-j+1])+MinC[i][j-1], cost(ir[i])+MinC[i-1][j]}
Rezultatul este min{min{MinC[i][i+1]|0iN},min{MinC[i][i+2]| 0iN-1}}. i n acest
caz putem folosi doar O(N) memorie.

Problema 1-5. Roboi (Olimpiada Baltic de Informatic, 2002, enun modificat)


Se dau N (1N10) roboi. Fiecare robot i (1iN) este amplasat la coordonatele
(x(i),y(i)), se uit n direcia d(i) (Nord, Est, Sud sau Vest) i are propriul su program P(i).
Un program P(i) const dintr-o secven de nc(i) (0nc(i) 50) comenzi. Vom nota prin
P(i,j) a j-a comand din programul P(i). Comenzile sunt de dou tipuri:
(1) rotaie cu 90 de grade spre stnga/spre dreapta ;
(2) deplasare cu o poziie n direcia n care se uit.
Dac robotul se afl la coordonatele (xr,yr) i are de executat o comand de deplasare,
atunci: dac se uit n direcia Nord/Est/Sut/Vest, noile sale coordonate sunt: (xr,yr1)/(xr+1,yr)/(xr,yr+1)/(xr-1,yr). Fiecare comand P(i,j) are un cost de tergere C(i,j). Se
dorete tergerea unor comenzi din programele roboilor astfe nct, n urma comenzilor
efectuate, toi roboii s ajung n aceeai poziie. Costul total al comenzilor terse trebuie s
fie minim.
Soluie: Pentru fiecare robot i vom determina mulimea de poziii (xr(i),yr(i),dr(i)) n care
poate ajunge robotul n urma efecturii comenzilor din programul su, n cazul n care unele
comenzi pot fi terse, mpreun cu costul minim pentru a ajunge la poziiile respective (dr(i)
este direcia n care se uit robotul). Vom nota prin S(i,j)=mulimea strilor n care poate
ajunge robotul i dac lum n considerare doar comenzile 1, ..., j.
Avem S(i,0)={poziie=(x(i),y(i),d(i)), cost=0}. Pentru 1jnc(i), iniializm S(i,j) cu S(i,j1) (cazul n care comanda P(i,j) nu se execut). Apoi considerm fiecare poziie din S(i,j-1),
la care efectum comanda P(i,j). S presupunem c, n urma considerrii poziiei (xr, yr, dr)
cu costul cr i a efecturii comenzii P(i,j), obinem poziia (xr, yr, dr) cu costul cr. Dac
poziia (xr, yr, dr) nu se afl n S(i,j), o introducem, setnd costul cr. Dac poziia se afl
n S(i,j) cu un cost mai mare, atunci modificm costul la cr.
Putem implementa mulimile S(i,j) ca nite arbori echilibrai sau, deoarece fiecare robot
se poate plimba doar n poziiile la distan cel mult nc(i) fa de poziia iniial, putem
menine un vector caracteristic pentru fiecare tuplu (xdr, ydr, dr) (unde xdr i ydr sunt ntre
nc(i) i +nc(i), dr este ntre 1 i 4, poziia real fiind (x(i)+xdr, y(i)+ydr, dr)).
La final, vom determina mulimea SS(i), coninnd toate poziiile (xr,yr) unde poate
ajunge robotul, indiferent de orientare, mpreun cu costul acestora (practic, pentru fiecare
poziie (xr,yr,dr) cu costul cr, introducem (xr,yr) cu costul cr n SS(i), dac (xr,yr) nu exist
acolo, sau micorm costul asociat lui (xr,yr) n SS(i) la cr, dac avea un cost asociat mai
mare dect cr).
n continuare, vom considera fiecare poziie (xr, yr) din SS(1). Pentru fiecare poziie, vom
calcula costul total pentru ca toi roboii s ajung n poziia respectiv. Vom parcurge toi
roboii j (1jN). Dac poziia (xr,yr) nu exist n SS(j), atunci costul total corespunztor ei
va fi +. Dac poziia (xr,yr) apare n toate mulimile SS(j) (1jN), atunci costul ei total va
fi suma costurilor asociate n fiecare mulime. Rspunsul problemei este dat de poziia (xr,yr)
pentru care costul total calculat este minim.
Problema 1-6. Drum de valoare maxim ntr-un graf orientat aciclic
Se d un graf orientat aciclic cu N noduri. Fiecare nod i (1iN) are o valoare v(i). Dorim
s determinm un drum n acest graf, pentru care suma valorilor este maxim. n plus, pentru
fiecare nod i se cunoate o submulime de noduri S(i). n cadrul drumului, valoarea unui nod

i poate fi nlocuit cu valoarea oricrui alt nod din mulimea S(i). Totui, se pot realiza
maxim K (0KN) astfel de nlocuiri.
Soluie: Vom calcula Vmax(i,j)=suma maxim a unui drum ce se termin la nodul i i n care
s-au efectuat j nlocuiri (0jK). Pentru nceput, vom calcula pentru fiecare nod valoarea
vs(i)=max{v(j)|j S(i)}. Vom calcula apoi o sortare topologic a nodurilor: o(1), ..., o(N) i
vom parcurge nodurile n ordinea din cadrul sortrii topologice (i=1,...,N).
Iniializm Vmax(o(i), j)=max{Vmax(x, j)+v(j)| exist muchia orientat (x,o(i)) n graf}
(0jK). Apoi considerm toate valorile 1jK i setm Vmax(o(i),j)=max{Vmax(o(i),j),
max{Vmax(x,j-1)+vs(j)| exist muchia orientat (x,o(i)) n graf }}.
Drumul de valoare maxim este max{Vmax(i,j)|1iN, 0jK}. Observm c
max{Vmax(i,0)|1iN} este drumul de valoare maxim fr nicio interschimbare.
Complexitatea algoritmului este O((N+M)(K+1)).
Variante ale acestei probleme au fost propuse la multe concursuri de programare (de ex.,
Olimpiada Baltic de Informatic, 2000).
Problema 1-7. Traversarea podului cu o lantern
De o parte a unui pod se afl N (1N100.000) persoane. Fiecare persoan i are un timp
T(i) de traversare a podului. Afar este noapte, exist o singur lantern i se dorete
traversarea podului de ctre toate cele N persoane. Pe pod pot trece simultan maxim dou
persoane, dar, ntruct exist o singur lantern, ele vor circula la viteza persoanei mai lente
(durata de traversare simultan a podului a persoanelor i i j este max{T(i),T(j)}). Determinai
o strategie de traversare a podului cu durat total minim.
Soluie: Vom sorta persoanele astfel nct s avem T(1)T(2)...T(N). Vom calcula
Tmin(i)=timpul minim necesar pentru traversarea podului de ctre primele i persoane (n
ordinea sortat dup timpii de traversare).
Avem Tmin(1)=T(1), Tmin(2)=max{T(1), T(2)}=T(2), Tmin(3)=T(2)+T(1)+T(3). Pentru
i4 avem Tmin(i)=min{Tmin(i-1)+T(1)+T(i), Tmin(i-2)+T(1)+T(i)+ T(2)+T(2)}. Prima
variant corespunde urmtorului caz: au traversat podul primele i-1 persoane, persoana 1 se
ntoarce cu lanterna i trece podul mpreun cu persoana i. A doua variant corespunde
urmtorului caz: au traversat podul primele i-2 persoane; se ntoarce pe partea cealalt
persoana 1, mpreun cu lanterna; trec podul persoanele i-1 i i mpreuna; se ntoarce pe
partea cealalt persoana 2, cu lanterna; trec podul persoanele 1 i 2 mpreun.
Complexitatea algoritmului este O(Nlog(N)) (faza de sortare), plus O(N) (faza de
programare dinamic).
Problema 1-8. Cuplaj de Cost Maxim ntr-un Arbore (Olimpiada de Informatic a
Europei Centrale, 2007, enun modificat)
Se d un arbore cu N (1N5000) noduri. Fiecare muchie (u,v) are un cost c(u,v)0.
Determinai un cuplaj de cost maxim, precum i numrul de cuplaje de cost maxim. Un
cuplaj este o submulime de muchii astfel nct oricare dou muchii din cuplaj nu au niciun
capt comun. Costul unui cuplaj este egal cu suma costurilor muchiilor din cuplaj.
Soluie: Vom alege o rdcin pentru arbore (un nod oarecare r), definind astfel relaiile de
printe, fiu, subarbore, etc. Vom calcula, pentru fiecare nod i, cte patru valori: CA(i)=costul
maxim al unui cuplaj considernd doar nodurile din subarborele lui i i care conine o muchie

adiacent cu nodul i; CB(i)=o valoare avnd aceeai semnificaie ca i CA(i), doar c nu


exist nicio muchie n cuplaj care s fie adiacent cu nodul i; NCA(i)=numrul de cuplaje de
cost maxim n subarborele nodului i ce conin o muchie adiacent cu nodul i; NCB(i)=
numrul de cuplaje de cost maxim n subarborele nodului i ce nu conin o muchie adiacent
cu nodul i.
Vom parcurge arborele de la frunze spre rdcin. Pentru o frunz i avem CA(i)=-,
CB(i)=0 i NC(i)=1. Pentru un nod neterminal i vom calcula CB(i) ca fiind suma valorilor
max{CA(j), CB(j)}, cu j fiu al lui i. Vom determina, de asemenea, acel fiu k al lui i pentru
care valoarea (max{CA(k), CB(k)}-CB(k)) este minim ntre toi ceilali fii.
CA(i) va fi egal cu c(i,k)+CB(i)+CB(k)-max{CA(k),CB(k)} (muchia adugat la cuplajul
de cost maxim este muchia i-k).
NCB(i) este calculat ca produs al urmtoarelor valori: NCmax(j)=(dac CA(j)>CB(j)
atunci NCA(j) altfel dac CA(j)<CB(j) atunci NCB(j) altfel (NCA(j)+NCB(j))), unde j ia ca
valori, pe rnd, fiecare fiu al lui i.
Pentru a calcula NCA(i) l iniializm la 0 i apoi considerm, pe rnd, fiecare fiu j al lui i.
Dac
CA(i)=c(i,j)+CB(i)+CB(j)-max{CA(j),
CB(j)},
atunci
setm
NCA(i)=
NCA(i)+NCB(i)/NCmax(j)NCB(j), unde NCmax(j) a fost definit anterior.
Costul maxim al unui cuplaj este max{CA(r), CB(r)}, iar numrul de cuplaje maxime este
egal cu NCmax(r) (folosind definiia dat mai sus). Complexitatea algoritmului este
O(N)NrMari(N), unde NrMari(N) este complexitatea lucrului (adunri, scderi, nmuliri,
mpriri) cu numere mari avnd O(N) cifre.
Problema 1-9. estoase (ACM ICPC NEERC, 2004)
N (1N50.000) estoase se mic pe o strad cu aceeai vitez. Fiecare estoas vede
estoasele dinaintea ei i de dup ea. Unele estoase se mic n grup, astfel c o estoas nu
poate vedea celelalte estoase din acelai grup (nu sunt nainte sau dup ea, ci chiar n dreptul
ei). Fiecare estoas i (1iN) spune c sunt exact a(i) estoase naintea ei i exact b(i)
estoase dup ea (i este un simplu identificator al unei estoase care nu are legtur cu
ordinea estoaselor pe strad). Determinai numrul minim de estoase care mint.
Exemplu:
Numrul minim de estoase care mint
N=5
este 2: estoasele 1 i 4.
a(1)=0 ; b(1)=2
a(2)=0 ; b(2)=3
a(3)=2 ; b(3)=1
a(4)=1 ; b(4)=2
a(5)=4 ; b(5)=0
Soluie: S considerm c fiecare estoas i are asociat o coordonat x(i) pe strad. Vom
considera c o estoas j se afl naintea (dup/n dreptul) unei estoase i dac x(j)>x(i)
(x(j)<x(i) / x(j)=x(i)). Vom considera estoasele sortate descresctor dup coordonata x
asociat (o(1), ..., o(N)), x(o(i))x(o(i+1)), 1iN-1 (aceast ordonare nu este cunoscut).
Dac mai multe estoase se afl la aceeai coordonat x, atunci ele se pot afla n orice
ordine n cadrul ordonrii. Fiecare afirmaie a unei estoase i (1iN) este echivalent cu a
spune c estoasele o(j) cu j n intervalul de poziii [front(i)=a(i)+1, back(i)=N-b(i)] din
cadrul ordonrii o sunt la coordonate x egale, toate estoasele o(j) cu j n intervalul de poziii
[1,a(i)] din cadrul ordonrii o sunt la coordonate x mai mari, i toate estoasele o(j) cu j n
intervalul de poziii [N-b(i)+1,N] din cadrul ordonrii o sunt la coordonate x mai mici.

Vom ignora intervalele cu back(i)<front(i) (ce corespund unor estoase ce mint n mod
obligatoriu) i vom sorta apoi celelalte intervale [front(i), back(i)] cresctor dup captul
stnga (i, pentru acelai capt stnga, cresctor dup captul dreapta). Apoi vom pstra doar
cele MN intervale distincte i vom asocia o pondere fiecrui interval pstrat, egal cu
numrul de apariii ale intervalului n cadrul sortrii; dac ponderea intervalului este mai
mare dect lungimea sa (lungimea unui interval [p,q] este q-p+1), atunci ponderea este setat
la lungimea acestuia.
n acest moment avem urmtoarea problem. Dndu-se M=O(N) intervale [left(i),
right(i)], fiecare avnd o pondere w(i) (1iM), determinai o mulime de intervale cu
proprietatea c oricare dou intervale nu se intersecteaz, a cror sum a ponderilor este
maxim. Suma ponderilor acestor intervale corespunde unui numr maxim de estoase care
spun adevrul. Celelalte estoase vor fi distribuite n intervalele din mulime a cror pondere
este mai mic dect lungimea lor, iar estoasele rmase dup aceast redistribuire vor forma
cte un grup singure, pe acele poziii (de la 1 la N) care nu aparin niciunui interval din
mulimea selectat.
Pentru a rezolva problema la care am ajuns vom sorta cresctor cele 2M capete de
intervale, reinnd, pentru fiecare capt p, tipul su tip(p) (stnga sau dreapta) i indicele
intervalului din care face parte, idx(p). Dac avem mai multe capete de interval cu aceeai
valoare, atunci capetele stnga se vor afla naintea capetelor dreapta cu valoarea respectiv.
Vom parcurge apoi irul celor 2M capete de interval i pentru fiecare poziie p vom
calcula o valoare Wmax(p)=suma maxim a ponderilor unei submulimi de intervale care nu
se intersecteaz, ale cror capete dreapta se afl pe poziii qp. Vom iniializa Wmax(0)=0.
Dac tip(p)=stnga, atunci setm pozleft(idx(p))=p i Wmax(p)=Wmax(p-1). Dac
tip(p)=dreapta, atunci Wmax(p)=max{Wmax(p-1), w(p)+Wmax(pozleft(idx(p))-1)}; primul
caz corespunde situaiei n care intervalul idx(p) nu este selectat, iar al doilea caz corespunde
situaiei n care intervalul idx(p) este selectat.
Wmax(2M) este suma maxim a ponderilor din mulimea cutat. Mulimea poate fi
determinat dac urmrim modul n care au fost calculate valorile Wmax(*). Aadar, aceast
problem a fost rezolvat ntr-o complexitate O(Mlog(M)), obinnd o soluie de
complexitate O(Nlog(N)) pentru problema iniial.
Problema 1-10. Operaii fiscale (TIMUS)
Se dau trei numere A, B i C de cel mult 1.000 de cifre (n baza Q, 2Q100). Modificai
cifrele numerelor A, B i C, n aa fel nct suma lor s fie numrul C. Dac cifra i unui
numr se modific de la valoarea x la y, se pltete un cost egal cu |x-y|. Efectuai
modificrile astfel nct costul total pltit s fie minim.
Soluie: Vom extinde cele 3 numere astfel nct s aib toate acelai numr N de cifre
(adugnd 0-uri la nceput). Vom nota prin X(i) a i-a cifr a numrului X (X=A, B sau C;
cifrele se numr de la cea mai puin semnificativ la cea mai semnificativ). Vom calcula
CA(i)=costul total minim pltit pentru ca adunnd numerele formate din cifrele de pe
poziiile 1,...,i ale numerelor A i B s obinem cifrele de pe poziiile 1,...,i ale numrului C i
s nu avem transport; CB(i)=aceeai semnificaie, dar avem transport.
Avem CA(0)=0 i CB(0)=+. Pentru o poziie i vom iniializa CA(i)=CB(i)=+, apoi
vom ncerca toate posibilitile cx pentru cifra i din numrul A i cy pentru cifra i din
numrul B (0cx,cyQ-1; avem restricii suplimentare n cazul n care poziia i este o cifr

10

extins a numrului, caz n care ea trebuie s rmn 0, sau dac este cea mai semnificativ
cifr a numrului dinainte de extindere, caz n care cx,cy1).
Pentru fiecare posibilitate calculm sxy=cx+cy i considerm dou cazuri: (1) nu avem
transport de la poziia anterioar => calculm cxy=sxy div Q i rxy=sxy mod Q; setm
costxy=|cx-A(i)|+|cy-B(i)|+|rxy-C(i)|+CA(i-1) ; (2) avem transport de la poziia anterioar
=> calculm cxy=(sxy+1) div Q i rxy=(sxy+1) mod Q; setm costxy=|cx-A(i)|+|cyB(i)|+|rxy-C(i)|+CB(i-1). Apoi, dac cxy>0, setm CA(i)=min{CA(i), costxy}; altfel, setm
CB(i)=min{CB(i), costxy}. Complexitatea soluiei este O(NQ2).
Putem reduce complexitatea la O(NQ), dup cum urmeaz. n loc s ncercm toate
combinaiile de posibiliti cx i cy la un pas i, vom considera toate posibilitile de sume sxy
(de la 0 la 2Q-2). Dac sxyA(i)+B(i), vom seta cx=A(i)+min{sxy-(A(i)+B(i)), B-1-A(i)} i
cy=sxy-cx. Dac sxy<A(i)+B(i), atunci setm cx=A(i)-min{A(i)+B(i)-sxy, A(i)} i cy=sxy-cx.
O situaie interesant apare atunci cnd trebuie s pltim un cost wA0 pentru
modificarea cu o unitate a unei cifre din A, wB0 pentru modificarea cu 1 a unei cifre din B,
respectiv wC0 pentru modificarea cu 1 a unei cifre din C. Pentru ambii algoritmi descrii
(de complexitate O(NQ2) i O(NQ)) vom calcula costxy ca fiind: wA|cx-A(i)|+wB|cyB(i)|+wC|rxy-C(i)|+CA(i-1), respectiv ca wA|cx-A(i)|+wB|cy-B(i)|+wC|rxy-C(i)|+CB(i-1).
Pentru al doilea algoritm (de complexitate O(NQ)), o dat ce fixm suma sxy, dac wAwB,
atunci vom folosi procedeul descris mai sus. Dac wB<wA, atunci setm nti cy i apoi
calculm cx ca sxy-cy. Dac sxyA(i)+B(i), cy va fi egal cu B(i)+min{sxy-(A(i)+B(i)), Q-1B(i)}; altfel, cy=B(i)-min{A(i)+B(i)-sxy, B(i)}.
Problema 1-11. Alegeri (Lotul Naional de Informatic, Romnia 2007)
n ara Apulumia se apropie timpul alegerilor pentru preedinte. n ar sunt un numr de
N (3n2.000.000.000) de alegtori. Din acetia, doar o mic parte l susin n continuare pe
actualul preedinte, care, n mod natural, dorete s fie reales.
Pentru o desfurare democratic a alegerilor se aplic urmatoarea procedur: toi
alegtorii sunt mprii n grupe egale, care cu majoritate simpl (jumtate plus unu) aleg un
reprezentant, apoi reprezentanii sunt mprii n grupe egale, care la rndul lor aleg un
reprezentant, i asa mai departe, dup acelai principiu, pn la desemnarea unui singur
reprezentant, preedintele. Actualul preedinte mparte alegtorii n grupe i plaseaz
susintorii dup bunul su plac. Ajutai-l s determine numrul minim de susintori ai si,
care plasai corespunztor duc la ctigarea alegerilor. ntr-o grup, la egalitate de voturi,
ctig opoziia.
Exemplu: N=9 => Sunt necesari 4 susintori.
Soluie: Se determin toi divizorii lui N, i apoi se sorteaz n ordine cresctoare (n vectorul
dv, unde dv[k] reprezint al k-lea divizor al lui N; 1kNrDivizori). Apoi se calculeaz n
vectorul nmin[i] numrul minim de susintori necesari pentru a ctiga alegerile, dac ar
exista dv[i] alegtori n total.
Evident, nmin[1]=1. Pentru i=2,...,NrDivizori, iniializm nmin[i]=+. Considerm apoi
toi divizorii dv[j] (1ji-1) i dac dv[j] este divisor al lui dv[i], atunci calculm numrul de
suintori necesari dac cei dv[i] alegtori ar fi mprii n dv[j] grupe: acest numr este
NS(i,j)=((dv[i] div dv[j]) div 2)+1)nmin[j]; setm apoi nmin[i]=min{nmin[i], NS(i,j)}.
nmin[NrDivizori] reprezint rspunsul problemei.

11

Problema 1-12. Drumuri palindromice (USACO 2002, enun modificat)


Se d un graf neorientat cu N (1N1000) noduri. Fiecare nod are asociat o liter dintrun alfabet cu C simboluri (l(i) este litera asociat nodului i). Determinai cte drumuri
palindromice de lungime fix L (1L500 exist. Un drum este palindromic dac,
parcurgndu-l dintre-un sens i concatennd simbolurile asociate nodurilor de pe drum,
obinem un palindrom. Un drum poate conine acelai nod de mai multe ori.
Soluie: O prim soluie este urmtoarea. Vom calcula matricea NPAL(i,j,k)=numrul de
drumuri palindromice de lungime k dintre nodurile i i j. Avem NPAL(i,i,1)=1 i
NPAL(i,j,2)=1, dac l(i)=l(j) i nodurile i i j sunt adiacente n graf.
Pentru fiecare lungime 3kL vom calcula NPAL(i,j,k) dup cum urmeaz. Dac l(i)l(j),
atunci NPAL(i,j,k)=0. Altfel, iniializm NPAL(i,j,k)=0, apoi considerm toi vecinii i ai
nodului i i toi vecinii j ai nodului j, astfel nct l(i)=l(j) i setm
NPAL(i,j,k)=NPAL(i,j,k)+NPAL(i,j,k-2). Soluia este suma valorilor NPAL(*,*,L). Acest
algoritm are complexitatea O(N2LD2), unde D este numrul maxim de vecini ai unui nod
din graf. Cnd D este mare, putem mbunti algoritmul dup cum urmeaz.
Calculm, n plus, NPALaux(i,j,k)=numrul de drumuri de lungime k, cu proprietatea c
ncep n nodul i, se termin n nodul j, iar subdrumul format din bucata de drum ce ncepe
imediat dup nodul i i se termin la nodul j este palindromic. Pentru 3kL, definiiile se
schimb dup cum urmeaz. Pentru a calcula NPALaux(i,j,k) iniializm valoarea cu 0 i apoi
considerm toi vecinii i ai nodului i, setnd NPALaux(i,j,k)=NPALaux(i,j,k)+NPAL(i,j,k-1).
NPAL(i,j,k) (cu l(i)=l(j)) va fi acum egal cu suma valorilor NPALaux(i,j,k-1), cu j un
vecin al nodului j. Complexitatea s-a redus la O(N2LD).
Problema 1-13. Schimb valutar (Olimpiada Naional de Informatic, Croaia, 2001)
Gigel are X euro. El a aflat dinainte, pentru fiecare din urmtoarele N (1N100.000) zile,
rata de schimb dintre euro i dolar. Mai exact, pentru fiecare zi i (1iN) se tie c 1
dolar=DolEuro(i) euro (dac se face conversia din dolari n euro) i 1 euro=EuroDol(i)
dolari (dac se face conversia din euro n dolari). Determinai cea mai mare sum (n euro)
pe care o poate avea Gigel dup cele N zile. n fiecare zi, el poate schimba dolarii n euro sau
euro n dolari (nu neaprat pe toi), sau poate s nu efectueze nicio tranzacie de schimb
valutar.
Soluie: Vom calcula Dmax(i) i Emax(i), suma maxim de dolari (respectiv, euro), pe care o
poate avea Gigel la sfritul primelor i zile. Avem Dmax(0)=0 i Emax(0)=X. Pentru 1iN
avem: Dmax(i)=max{Dmax(i-1), Emax(i-1)EurDol(i)} i Emax(i)=max{Emax(i-1), Dmax(i1)DolEur(i)}. Emax(N) este suma maxim n euro pe care o poate avea Gigel la sfritul
celor N zile.
Problema 1-14. Tiere cu maximizarea sumei
Se d un ir de N (1N100.000) valori ntregi: a(1), , a(N) (-1000a(i)1000; 1iN).
Eliminai K (1K30) secvene (disjuncte) de cte x (1KxN) numere (consecutive), astfel
nct suma numerelor rmase n secven s fie maxim.

12

Soluie: Maximizarea sumei elementelor rmase este echivalent cu minimizarea sumei


elementelor eliminate. Vom calcula Smin(i,j)=suma minim a elementelor eliminate, dac
dintre primele i elemente am eliminat j secvene.
Avem Smin(i,0)=0 i Smin(i,jx>i)=+ (0iN). Pentru i1 i 1jmin{i div x, K}, avem:
Smin(i,j)=min{Smin(i-1,j),Smin(i-x,j-1)+Sum(i-x+1,i)}.
Sum(u,v) reprezint suma elementelor dintre poziiile u i v (inclusiv). Sum(u,v)=SP(b)SP(a-1), unde SP(q)=suma primelor q elemente (SP(0)=0 i SP(1qN)=SP(q-1)+a(q)).
Complexitatea algoritmului este O(NK).
Problema 1-15. Mesaj
Se d un ir S format din N caractere (1N1.000) i o list de M cuvinte (0M1.000) de
lungime cel mult L (1L20). Determinai numrul minim de caractere ce trebuie eliminate
din irul S, astfel nct irul rmas s poat fi reprezentat ca o concatenare a unor cuvinte din
lista de cuvinte (n cadrul concatenrii, un cuvnt poate aprea de 0, 1, sau mai multe ori).
Cuvintele sunt formate din caractere ale unui alfabet A ce conine cel mult Q litere
(1Q1.000).
Soluie: Vom nota prin S(i) caracterul de pe poziia i din irul S, i prin S(i..j) subirul dintre
poziiile i i j ale irului S. Pentru nceput, vom parcurge irul S de la sfrit ctre nceput (de
la dreapta la stnga) i vom calcula, pentru fiecare poziie i i fiecare caracter c, valoarea
Next(i,c)=cea mai din stnga poziie ji, astfel nct S(j)=c.
Pentru i=N vom avea Next(N, cS(N))=N+1 i Next(N, S(N))=N. Pentru 1iN-1, vom
avea: Next(i, S(i))=i i Next(i, cS(i))=Next(i+1, c). Aadar, aceste valori se pot calcula n
timp O(NQ) (cu i variind descresctor, de la N ctre 1).
Vom calcula apoi Nmin(i)=numrul minim de caractere ce trebuie eliminate din S(i..N),
pentru ca irul rmas (S(i..N) fr caracterele eliminate) s poat fi scris ca o concatenare de
cuvinte din lista dat. Avem Nmin(N+1)=0. Pentru 1iN (n ordine descresctoare a lui i),
avem urmtoarele situaii:
(1) nu ncepe niciun cuvnt la poziia i; n acest caz, avem Nmincand(i, 0)=1+Nmin(i+1);
(2) la poziia i ncepe cuvntul j (1jM).
Pentru cazul 2, va trebui s determinm dac cuvntul j chiar se regsete ca un subir de
caractere (nu neaprat consecutive) n S(i..N). Pentru aceasta, vom parcurge cu un contor k
toate poziiile din cuvntul j (Cuv(j)); 1k|Cuv(j)| (|Cuv(j)|=numrul de caractere ale
cuvntului Cuv(j)). n cadrul parcurgerii vom reine cte o poziie poz, reprezentnd cea mai
din stnga poziie pe care ar putea aprea caracterul Cuv(j,k) (al k-lea caracter din Cuv(j)).
Iniial avem poz=i. Pentru k=1,...,|Cuv(j)| efectum urmtoarele aciuni: poz=Next(poz,
Cuv(j,k))+1; dac pozN+2, atunci ntrerupem ciclul al crui contor este k.
Dac la sfritul parcurgerii caracterelor din Cuv(j) avem pozN+1, atunci cuvntul
Cuv(j) se termin, cel mai devreme, pe poziia poz-1. Aadar, vom avea Nmincand(i,j)=poz-i|Cuv(j)|+Nmin(poz). Altfel, dac poz>N+1, setm Nmincand(i,j)=+. Nmin(i) va fi egal cu
min{Nmincand(i,j)|0jM}.
Problema poate fi extins la cazul n care fiecare caracter c (1cQ) are un cost de
eliminare Cost(c)0. n acest caz, vom calcula uor diferit valorile candidat Nmincand(i,j)
(1iN; 0jM). Nmincand(i,0)=Cost(S(i))+Nmin(i+1). Vom calcula n prealabil (la nceput)
sumele prefix SP(u): SP(0)=0 i SP(1uN)=Cost(S(u))+SP(u-1). De asemenea, pentru
fiecare cuvnt Cuv(j), vom calcula la nceput Scost(j)=suma costurilor Cost(Cuv(j,k))
(1k|Cuv(j)|). Cu aceste valori calculate, i calculnd poziia poz folosind acelai algoritm

13

prezentat anterior, vom avea Nmincand(i,j)=SP(poz-1)-SP(i-1)-Scost(j)+Nmin(poz) (pentru


cazul 1jM i pozN+1).
Problema 1-16. Tetris
Se d o tabl de tetris alctuit din N (1N3) coloane i nlime infinit. De asemenea,
se d o secven de M piese de tetris ce trebuie aezate, n ordine, pe tabl. O pies de tetris
este o component conex de ptrele, ce poate fi rotit i translatat. Dorim s amplasm
toate piesele pe tabl astfel nct nlimea maxim ocupat pe oricare dintre coloane s fie
minim.
Soluie: O prim soluie este urmtoarea. Vom calcula matricea OK(h(1), ..., h(N), j)=1, dac
coloana i este ocupat pn la nlimea h(i) (eventual cu guri) (1iN) i am considerat
deja primele j (0jM) piese.
ncepem cu OK(0, ..., 0, 0)=1 i OK(h(1), ..., h(N), 0)=0 dac cel puin o valoare h(i) este
mai mare dect 0. Considerm apoi, pe rnd, fiecare stare (h(1), ..., h(N), j) n ordine
cresctoare a lui j (i n orice ordine pentru j egal) pentru care OK(h(1), ..., h(N), j)=1
(1jM-1).
Vom considera fiecare posibilitate de a translata i roti piesa j+1 i apoi o vom amplasa
pe tabl. Dup selectarea translaiei (practic, se alege cea mai din stnga coloan pe care o va
ocupa piesa) i a rotaiei, pentru fiecare coloan j ocupat de o ptric a piesei, vom calcula
hjos(j) (hsus(j)) = diferena n modul ntre linia cea mai de jos (sus) a unui ptrel al piesei
de pe coloana j i linia celui mai de sus ptrel al piesei (indiferent de coloana pe care se afl
acesta). n urma amplasrii, noile nlimi ale coloanelor vor fi h(1), ..., h(N). Dac o
coloan j nu este ocupat de niciun ptrel al piesei, atunci h(j)=h(j). Pentru coloanele j
ocupate de pies vom calcula hmax=max{hjos(j)+h(j) | j este o coloan ocupat de cel puin
un ptrel al piesei}; pentru o astfel de coloan j vom avea h(j)=hmax-hsus(j).
Vom seta OK(h(1), ..., h(N), j+1)=1. La final, rspunsul va fi min{max{h(1), ..., h(N)} |
OK(h(1), ..., h(N), N)=1}. Considernd c fiecare pies are dimensiune O(1), aceast soluie
are un ordin de complexitate de O(MNNM).
O mbuntire este urmtoarea. Vom calcula hmin(h(1), ..., h(N-1), j)=nlimea minim
pentru h(N), dac nlimile coloanelor 1, ..., N-1 sunt h(1), ..., h(N-1) i am considerat
primele j piese. Vom avea hmin(0, ..., 0, 0)=0 i hmin(h(1), ..., h(N-1), 0)=+ dac avem cel
puin o nlime h(i)>0.
La fel ca nainte, vom considera strile (h(1), ..., h(N-1), j) n aceeai ordine (1jM-1).
Vom considera fiecare translaie i rotaie a piesei j+1. Considernd h(N)=hmin(h(1), ...,
h(N-1), j), putem folosi acelai procedeu ca i n soluia anterioar pentru a obine valorile
h(1), ..., h(N). Apoi vom seta hmin(h(1), ..., h(N-1), j+1)=min{h(N), hmin(h(1), ..., h(N1), j+1)} (iniial, toate valorile hmin(*, ..., *) se consider a fi +, cu excepia lui hmin(0, ...,
0)).
Rspunsul va fi min{hmin(h(1), ..., h(N-1), N)}. Complexitatea acestei soluii este O(MN-1
NM) (exponentul a fost redus cu 1 unitate).
Problema 1-17. Vectori de Teleportare pentru K Persoane
K (1K5) persoane se afl ntr-un cub d-dimensional (1d5) ce const din N
(1N100.0001/(d(K-1)+1)) ptrele n fiecare dimensiune (numerotate de la 1 la N). Persoana i
(1iK) se afl iniial la poziia (xs(i,1), ..., xs(i,d)) i trebuie s ajung n poziia (xf(i,1), ...,
xf(i,d)). Se d un ir de M (1M100) vectori d-dimensionali de teleportare; al j-lea vector

14

este (v(j,1), ..., v(j,d)), cu N+1v(j,q)N-1 (1qd). Pentru fiecare vector din ir, n ordinea
n care sunt dai, se tie c exact una din cele K persoane va efectua o teleportare
corespunztoare acelui vector. Dac o persoan se afl n poziia (x(1), ..., x(d)) i se
teleporteaz folosind vectorul (v(j,1), ..., v(j,d)), atunci noua sa poziie va fi (x(1)+v(j,1), ...,
x(d)+v(j,d)), cu condiia ca aceast poziie s se afle n interiorul cubului.
n interiorul cubului anumite poziii sunt blocate. O persoan nu se poate teleporta ntr-o
poziie blocat. Poziiile iniiale ale persoanelor nu sunt blocate.
Determinai dac este posibil ca fiecare persoan s ajung n poziia sa final, folosind
irul de M vectori de teleportare dat.
Soluie: O prim soluie const n a calcula urmtoarea matrice: OK(j, xc(1,1), ..., xc(1,d), ...,
xc(i,1), ..., xc(i,d), ..., xc(K,1), ..., xc(K,d))=1, dac dup folosirea primilor j vectori, fiecare
persoan i poate ajunge n poziia (xc(i,1), ..., xc(i,d)) (1iK) (i 0, altfel).
Iniial avem OK(0, xs(1,1), ..., xs(1,d), ..., xs(K,1), ..., xs(K,d))=1. Pentru a calcula OK(j,
S=(xc(1,1), ..., xc(1,d), ..., xc(K,1), ..., xc(K,d))) vom considera, pe rnd, fiecare persoan i i
vom ncerca dac aceasta poate fi cea care se teleporteaz folosind vectorul j. Calculm
poziia anterioar xc(i,q)=xc(i,q)-v(j,q) (1qd). Dac OK(j-1, S(i)=(xc(p, 1), ..., xc(p,d)
(1pi-1), xc(i,1), , xc(i,d), xc(p,1), ..., xc(p, d) (i+1pK)))=1, atunci vom seta OK(j,
S)=1.
Dac pentru nicio persoan i (1iK) nu gsim OK(j-1, S(i))=1, atunci OK(j,S)=0. Vom
considera, prin definiie, c OK(j, xc(p,q) (1pK, 1qd))=0 dac vreuna din coordonatele
xc(p,q) se afl n afara cubului sau dac vreo poziie (xc(i,1), ..., xc(i,d)) este blocat.
La final vom verifica dac OK(M, xf(p,q) (1pK, 1qd))=1 i, dac da, vom reconstitui
soluia folosind valorile deja calculate. Acest algoritm are complexitatea O(MNdK+1) i
calculeaz O(MNdK) stri. Se observ uor c se dorete ca complexitatea recomandat s fie
O(Md+MNd(K-1)+1). Aadar, soluia gsit este cu un factor de O(Nd) mai slab.
Pentru a optimiza complexitatea algoritmului vom calcula sumele pariale SV(j,q)
(1pM, 1qd). Avem SV(0,*)=0 i SV(1jM, q)=SV(j-1, q)+v(j,q). Observm acum c,
dac dup folosirea a j vectori de teleportare, persoanele i (1iK-1) se afl n poziiile
xc(i,q) (1qd), atunci putem determina n mod unic poziia persoanei K. Astfel, vom calcula
Scur(q)=(xc(1,q)+...+xc(K-1,q))-(xs(1,q)+...+xs(K-1,q)) (1qd) (sau 0, dac K=1). Poziia
n care se afl persoana K este xc(K,q)=xs(K,q)+SV(j,q)-Scur(q) (1qd). Algoritmul nu se
modific cu nimic, cu excepia faptului c nu vom mai menine i poziia persoanei K n
cadrul strii din matricea OK, ea fiind dedus, de fiecare dat, din poziiile persoanelor 1, ...,
K-1. n acest fel, complexitatea algoritmului s-a redus la O(Md+MNd(K-1)+1).
Problema 1-18. Cai multicolorai (TIMUS, enun modificat)
Se dau N (1N500) cai aezai n ordine, unul dup altul (de la calul numerotat cu 1, la
calul numerotat cu N). Fiecare cal i (1iN) are o culoare c(i) (1c(i)K; 2K20) i o for
f(i) (0f(i)100).
Caii trebuie mprii n Q (1Qmin{N, 100}) intervale (de cai aezai pe poziii
consecutive), n aa fel nct fiecare cal face parte dintr-un interval i fiecare interval conine
cel mult CMAX cai. Toi caii dintr-un interval vor fi dui n acelai grajd. S presupunem c
suma forelor cailor de culoarea j dintr-un interval [a,b] este sf(j) (1jK) (obinut prin
aplicarea funciei comutative csum(j) {+,max} asupra valorilor forelor cailor de culoarea j
din interval). Agresivitatea cailor din intervalul respectiv este egal cu produsul valorilor
sf(j) (sf(1)sf(2)...sf(K)).

15

Determinai o mprire a cailor n intervale astfel nct agresivitatea total (obinut prin
aplicarea funciei comutative fsum {+,max} asupra agresivitilor din fiecare interval) s fie
minim.
Exemplu:
N=6; K=2; Q=3
Agresivitatea total minim este 2. Cele
fsum=+; csum(*)=+
Q=3 intervale formate pot fi: [1,2],
[3,5], [6,6]. Agresivitatea n fiecare din
c(1)=1; f(1)=1
cele 3 intervale este: 0, 2, 0.
c(2)=1; f(2)=1
c(3)=2; f(3)=1
c(4)=1; f(4)=1
c(5)=2; f(5)=1
c(6)=1; f(6)=1
Soluie: Vom calcula Amin(i,j)=agresivitatea total minim pentru a mpri primii i cai n j
intervale. Avem Amin(0,0)=0 i Amin(i,j>i)=+. Pentru a calcula Amin(i,j) va trebui s
alegem al j-lea interval. Despre acest interval tim c se termin la calul i, dar nu tim la ce
cal ncepe. Vom iniializa un vector sf(col) (1colK) cu valoarea 0. Vom menine, de
asemenea, Pcol=produsul elementelor din vectorul sf.
Vom considera apoi fiecare poziie p de nceput a celui de-al j-lea interval, n sens
descresctor, ncepnd de la p=i i terminnd la p=max{j, i-CMAX+1}. Vom iniializa
Amin(i,j)=+. Cnd ajungem la o valoare nou a lui p, vom seta sf(c(p))=csum(c(p))(sf(c(p)),
f(p)). Vom calcula apoi noua valoare a lui Pcol. Putem realiza acest lucru n timp O(K)
(parcurgnd ntreg vectorul sf) sau, mai eficient, n timp O(1).
Vom menine, n plus, numrul nzero de element egale cu zero din vectorul sf (iniial,
nzero=K) i Pnz, produsul elementelor nenule din vectorul sf (iniial, Pnz=1). nainte s
modificm sf(c(p)) cu f(p), dac sf(c(p))=0 i f(p)>0, atunci decrementm nzero cu 1. Dac
nzero tocmai a sczut cu 1 unitate, atunci setm sf(c(p))=csum(c(p))(sf(c(p)), f(p)) (realizm
modificarea) i setm Pnz=Pnzsf(c(p)). Dac nzero nu a sczut i sf(c(p))>0, atunci fie
sfold(c(p)) valoarea lui sf(c(p)) dinaintea modificrii. Setm Pnz=Pnz/sfold(c(p))sf(c(p)).
Dac nzero>0, atunci Pcol=0; altfel, Pcol=Pnz.
Dup ce avem calculat valoarea lui Pcol corespunztoarea poziiei p, setm
Amin(i,j)=min{Amin(i,j), fsum(Amin(p-1,j-1), Pcol)}.
Valoarea Amin(N,Q) este agresivitatea total minim. mprirea n intervale poate fi i ea
determinat uor, dac pentru fiecare pereche (i,j) reinem acea valoare a lui p pentru care s-a
obinut Amin(i,j). Complexitatea algoritmului este O(N2Q).
Observm c putem generaliza problema. Putem folosi alte funcii de agregare pentru:
(1) suma forelor cailor de aceeai culoare dintr-un interval => putem folosi, de
exemplu, suma, maximul sau minimul;
(2) costul unui interval => n loc de produsul forelor cailor de culori diferite putem folosi
suma, maximul, minimul, etc.
Multe dintre aceste combinaii pot fi suportate modificnd foarte puin algoritmul
prezentat (i pstrnd complexitatea O(N2Q)). De exemplu, dac funcia f ce determin
costul unui interval este inversabil (are o funcie invers), atunci, cnd trecem la o valoare p
nou, i putem calcula valoarea n O(1) (valoare nou=(valoare veche) f-1 sfold(c(p)) f
sf(c(p))). De asemenea, dac funcia pentru suma forelor cailor de aceeai culoare dintr-un
interval (sf(c(p))) este max sau min i funcia f pentru costul unui interval (pe baza costurilor
asociate fiecrei culori) este aceeai (max sau min), avem: valoare nou=f(valoare veche,

16

sf(c(p))). Tot pentru cazul max/min, putem menine un max/min-heap cu valorile sf(c(p)) pe
msur ce decrementm valoarea lui p (cnd se modific sf(c(p)) tergem din heap valoarea
veche i o introducem pe cea nou). n aceste cazuri, valoarea nou a costului unui interval
se poate obine extragnd elementul din vrful heap-ului, n timp O(log(K)) (ajungnd la o
complexitate de O(N2Qlog(K))). Pentru alte combinaii, ns, va trebui s recalculm costul
corespunztor unui interval n timp O(K) (pentru fiecare valoare a lui p), ajungnd la o
complexitate de O(N2QK).
Problema 1-19. Vinuri (Olimpiada Naional de Informatic, Romnia 1997)
La un depozit specializat din Reca sosesc, pe rnd, N (1N300) clieni care solicit
fiecare o cantitate dat de Cabernet (clientul i cere L(i) litri, 1iN, 1L(i)100), oferind o
sum pentru achiziionarea ntregii cantiti cerute (S(i), 0S(i)1.000.000). n butoiul din
magazinul de deservire (considerat de capacitate nelimitat) nu se gsete iniial nicio
pictur de vin. Dan eptic, administratorul depozitului, are un algoritm propriu de
deservire a clienilor: n funcie de ceea ce are n butoi, dar i de inspiraia de moment, el
poate s rspund:
- V ofer ntreaga cantitate cu cea mai mare placere !
sau
- Nu v pot oferi acum ceea ce dorii, mai revenii cu solicitarea alt dat!
Pe clientul servit l elibereaz de grija banilor corespunztori costului licorii cumprate,
iar pe cel refuzat l salut politicos i are grij ca, imediat ce a plecat clientul (i), s coboare
i s aduc n butoiul din magazin exact cantitatea solicitat de clientul respectiv (cel ce nu a
fost servit), adic L(i).
Cunoscnd cele N cantiti cerute de clieni, s se determine un mod de a rspunde
solicitrilor astfel nct, n final, suma ncasat s fie maxim.
Soluie: Observm c, dac toi clienii ar fi refuzai, cantitatea maxim de vin ce s-ar putea
afla n butoi este cel mult egal cu LMAX=30.000. Aadar, vom putea calcula valorile
Smax(i,j)=suma maxim ce poate fi ncasat, dac dup ce au sosit primii i clieni au rmas j
litri n butoi.
Iniial, Smax(0,0)=0 i Smax(0, j>0)=-. Pentru i1 avem: pentru 0jL(i)-1,
Smax(i,j)=S(i)+Smax(i-1, j+L(i)); pentru L(i)jLMAX, Smax(i,j)=max{S(i)+Smax(i-1,
j+L(i)), Smax(i-1, j-L(i))}.
Rezultatul este max{Smax(N,j)|0jLMAX}. Complexitatea algoritmului este O(NLMAX).
Problema 1-20. Funcii de optimizare ntr-o secven
Se d o secven de N (1N100.000) numere v(i) (1iN). Fiecare poziie i are asociat
un interval de poziii [l(i), r(i)] (1l(i)r(i)i-1), o valoare z(i) i o funcie f(i)(x) cresctoare.
Dorim s determinm o secven ((a) de K numere (unde K poate aparine unei mulimi
SK {1,...,N}) ; (b) fr limit de numere) u(1)<u(2)<...<u(K), astfel nct: vom defini
q(u(1))=z(u(1)) i q(u(j))=f(u(j))(q(u(j-1))) (2jK); n plus, u(j) se afl n intervalul
[l(u(j+1)), r(u(j+1))]. Dorim ca valoarea q(u(K)) s fie minim.
Soluie: Pentru cazul a) vom calcula valorile qmin(i,j)=cea mai mic valoare, dac n
submulimea pe care o selectm, avem u(j)=i. qmin(i,1)=z(i) (1iN).
Pentru
2jK,
vom
considera
valorile
i
n
ordine
cresctoare.
qmin(i,j)=f(i)(qm(i,j)=min{+, min{qmin(p,j-1)|l(i)pr(i)}}).

17

Pentru calcularea valorii qm(i,j) putem considera toate poziiile p din intervalul [l(i), r(i)],
pentru a obine o complexitate O(N2K). Rspunsul este min{q(i,j)|j SK}. Dac nainte de a
calcula valorile qmin(*,j) construim un arbore de intervale peste valorile qmin(*,j-1), atunci
putem reduce complexitatea la O(NKlog(N)). Pentru a calcula qm(i,j) vom folosi o
interogare de tipul range minimum query pe intervalul [l(i), r(i)], la care poate fi obinut
rspunsul n timp O(log(N)). Dac folosim tehnica RMQ [Bender-RMQLCA2000] peste
valorile qmin(*,j-1) (preprocesare O(Nlog(N)) i gsirea minimului dintr-un interval [a,b] n
timp O(1)), obinem aceeai complexitate, dar fr utilizarea unui arbore de intervale. Acest
soluie poate ajunge i la O(NK), deoarece etapa de preprocesare a RMQ poate fi redus
(folosind nite metode mai complicate), la O(N).
Dac avem l(i)l(i+1) i r(i)r(i+1) (1iN-1), atunci putem folosi un deque (doubleended queue). Deque-ul va reine perechi (valoare,poziie). Cnd vrem s adaugm o pereche
(val,poz) la sfritul deque-ului, vom efectua urmtorii pai: ct timp deque-ul nu este gol i
ultima pereche (val,poz) din deque are proprietatea valval, vom terge perechea (val,
poz) din deque. Cnd trecem la o nou valoare a lui j, golim deque-ul. Cnd ajungem la o
poziie i, efectum urmtorii pai:
(1) ct timp deque-ul nu e gol i perechea (val,poz) de la nceputul deque-ului are
proprietatea poz<l(i), tergem aceast pereche de la nceputul deque-ului;
(2) adugm, pe rnd, la sfritul deque-ului, perechile (val=qmin(p,j-1), poz=p), cu r(i1)+1pr(i) (naintea fiecrei adugri efectum paii descrii anterior) ; (3) dac deque-ul e
gol, atunci qmin(i,j)=+; altfel, fie (val,poz) perechea de la nceputul deque-ului; vom seta
qmin(i,j)=f(i)(val). Utilizarea deque-ului asigur o complexitate O(NK).
Pentru cazul (b) vom renuna la indicele j din cadrul dinamicii: vom calcula valorile
qmin(i)=cea mai mic valoare, dac i este ultima poziie din cadrul submulimii selectate.
Avem
qmin(1)=z(1).
Pentru
2iN,
vom
avea
qmin(i)=min{z(i),
qm(i)=min{qmin(p)|l(i)pr(i)}}. O implementare direct (care consider, pe rnd, fiecare
poziie p), are o complexitate O(N2).
Putem folosi i de aceast dat un arbore de intervale. Interogrile sunt aceleai.
Diferena este dat de faptul c atunci cnd calculm o valoare qmin(i), atribuim aceast
valoare frunzei i din arbore (iniial, fiecare frunz va avea asociat valoare +) acest tip de
modificare se numete point update [Andreica-ISPDC2008]. Fiecare interogare i
actualizare pot fi realizate n timp O(log(N)).
Dac avem proprietile l(i)l(i+1) i r(i)r(i+1), atunci putem folosi din nou un deque.
Diferenele fa de algoritmul anterior sunt urmtoarele. Iniial, deque-ul este gol. Cnd
ajungem la o poziie i, tergem n mod repetat perechea (val,poz) de la nceputul deque-ului
ct timp val<l(i) i deque-ul nu e gol, apoi inserm perechile (val=qmin(p), poz=p), cu r(i1)+1pr(i), la sfritul deque-ului (naintea fiecrei inserri efectum paii descrii anterior,
pentru a ne asigura c valorile din deque sunt sortate n ordine cresctoare). Dac deque-ul e
gol, atunci qmin(i)=z(i); altfel, fie (val,poz) prima pereche din deque: qmin(i)=min{z(i),
f(i)(val)}.
Rspunsul este min{qmin(i)|1iN}. Complexitatea algoritmului este O(Nlog(N)) (dac
folosim arbori de intervale) i, respectiv, O(N), dac folosim (i suntem n situaia de a putea
folosi) deque-ul.
Problema 1-21. Submulime de noduri cu restricii
Se d un graf neorientat cu N (1N1.000) noduri. Fiecare nod i al grafului are o pondere
w(i) (1iN). Notm prin NV(i) mulimea nodurilor adiacente cu nodul i. Fiecare nod i are

18

asociate 2 seturi de submulimi: S(i,1) i S(i,2), avnd ns(i,1), respectiv ns(i,2) submulimi
valide fiecare (submulimile sunt identificate prin S(i,p,j) (1jns(i,p); p=1,2),
S(i,p,j) NV(i), iar fiecare element al lui S(i,p,j) este strict mai mic dect i).
Seturile de submulimi S(i,p) pot fi date i sub form implicit (de ex., S(i,p) conine toate
submulimile de vecini ai nodului i avnd un numr x (0x|NV(i)|) de elemente ce aparin
unei mulimi de numere XV(i,p)). Determinai o submulime SN de noduri ale grafului avnd
pondere total maxim (minim), astfel nct fiecare nod i (1iN) s respecte urmtoarele
proprieti:
dac nodul i face parte din SN, atunci trebuie s existe cel puin o submulime S(i,1,j),
astfel nct toate nodurile din S(i,1,j) fac parte i ele din SN
dac nodul i nu face parte din SN, atunci trebuie s existe cel puin o submulime S(i,2,j),
astfel nct toate nodurile din S(i,2,j) fac parte din SN
Se tie c pentru orice muchie (a,b) din graf are loc proprietatea: |a-b|K (1K11).
Soluie: Vom parcurge nodurile n ordine, de la 1 la N, i vom calcula un tabel
Wopt(i,ST)=ponderea maxim (minim) a unei submulimi a nodurilor {1,2,...,i} astfel nct:
(1) toate nodurile 1ji respect proprietile; i (2) ST este o submulime a nodurilor {iK+1, ..., i} care indic care dintre aceste noduri fac parte din SN. Rspunsul optim este
opt{Wopt(N, *)} (unde opt=max sau opt=min, n funcie de caz max dac urmrim
maximizarea ponderii i min altfel).
Iniial avem Wopt(0,{})=0. Pentru 1iN vom folosi urmtoarele formule:
(1) Wopt(i, (S U {i})\{i-K})=opt{Wopt(i-1, S) | 1p|S(i,1)| a.. S(i,1,p) S}
(2) Wopt(i, S\{i-K})=opt{Wopt(i-1, S) | 1p|S(i,2)| a.. S(i,2,p) S}

19

Capitolul 2. Greedy i Euristici


Problema 2-1. Colorarea intervalelor (TIMUS)
Se dau N (1N100.000) intervale [A(i),B(i)] (1iN). Se tie c reuniunea acestor
intervale este intervalul [0,L]. Dorim s colorm o parte dintre cele N intervale (i s le
lsm pe celelalte necolorate), astfel nct suma lungimilor poriunilor din intervalul [0,L]
care sunt incluse ntr-un singur interval colorat s fie cel puin 2/3L.
Soluie: Vom sorta intervalele dup captul stnga, astfel nct s avem
A(o(1))A(o(2))...A(o(N)). Vom menine coordonata dreapta xr a ultimului interval colorat.
Iniial, xr=0. Vom parcurge intervalele n ordinea sortat. Pe msur ce parcurgem
intervalele, vom menine un indice icand (iniial 0) i suma maxim cu care poate crete
suma lungimilor poriunilor acoperite de un singur interval (smax).
Cnd ajungem la un interval o(i) (1iN), nti verificm dac icand>0 i dac
A(o(i))>xr. Dac da, atunci vom colora intervalul icand, vom seta xr=B(icand) i vom mri
suma lungimilor poriunilor acoperite de un singur interval colorat (SL) cu smax; apoi
resetm icand i smax la 0.
Dup aceasta, vom considera intervalul o(i) ca un posibil interval candidat pentru a fi
colorat. Vom calcula s(i)=cu ct va crete SL dac intervalul o(i) ar fi colorat. Dac
A(o(i))xr, atunci s(i)=B(o(i))-A(o(i)); altfel, dac B(o(i))>xr, atunci s(i)=(B(o(i))-xr)-(xrA(o(i))); altfel, s(i)=0. Dac s(i)>smax, atunci setm smax=s(i) i icand=o(i). La sfritul
parcurgerii, dac icand>0, vom colora intervalul icand i vom aduna smax la SL (SL este 0 la
nceputul algoritmului).
Algoritmul descris este un algoritm euristic pentru maximizarea sumei poriunilor incluse
ntr-un singur interval colorat, care nu ofer niciun fel de garanii. Totui, n practic, pentru
multe cazuri, el se comport destul de bine. ncercai s gsii un test pentru care algoritmul
descris obine un rezultat mai prost dect 2/3L.
Problema 2-2. Ordonarea nlimilor (SGU)
Se dau N (1N6.000) nlimi h(1), ..., h(N). nlimile sunt numere reale ntre 1.950.000
i 2.050.000. Media aritmetic a nlimilor este 2.000.000. Determinai (dac exist) o
ordonare o(1), ..., o(N) a nlimilor (h(o(1)), ..., h(o(N))), astfel nct oricum am alege dou
poziii diferite p i q (p<q), suma nlimilor dintre poziiile p i q inclusiv
(h(o(p))+h(o(p+1))+...+h(o(q))) s fie n intervalul [2.000.000(q-p+1)-100.000,
2.000.000(q-p+1)+100.000].
Soluie: Vom folosi urmtorul algoritm euristic. Pentru nceput, vom ordona nalimile, astfel
nct s avem h(1)h(2)...h(N). Vom iniializa dou variabile i=1 i j=N i vom menine
un sens dir cu valorile 0 sau 1 (iniial, dir=0) i suma S a nalimilor adugate pn acum n
cadrul ordonrii (iniial, S=0).
Apoi vom aduga, pe rnd, pe fiecare poziie k de la 1 la N, cte o nlime. La fiecare
poziie k, dac dir=0, vom aduga pe poziia k nlimea h(i) (dup care setm i=i+1), iar
dac dir=1, adugm pe poziia k nlimea h(j) (dup care setm j=j-1); apoi incrementm S

20

cu valoarea nlimii adugate. Dac S<k2.000.000, atunci setm dir=1; altfel, setm dir=0.
Dup aceasta, trecem la urmtoarea poziie (k+1).
La final mai trebuie s verificm dac ordonarea obinut respect proprietile cerute. S
observm c dac exist dou poziii p i q pentru care suma nlimilor dintre ele nu
respect proprietatea cerut, atunci una din perechile (1,q) sau (p,N) nu va respecta, de
asemenea, proprietatea cerut. Aadar, trebuie s verificm doar perechi de poziii de forma
(1,q2) sau (pN-1,N). Pentru aceasta vom calcula sumele prefix (SP(0)=0; SP(i)=SP(i1)+h(o(i))) i sumele sufix (SS(N+1)=0; SS(i)=SS(i+1)+h(o(i))) i vom verifica c acestea
(SP(q2) i SS(pN-1)) au valori n intervalul dorit.
Observm c euristica prezentat nu ine cont de valorile propriu-zise ale nlimilor i de
limitele date. Ea ncearc s menin sumele prefix ct mai aproape de media aritmetic a
tuturor numerelor. Aadar, problema poate fi generalizat n felul urmtor: Se dau N nlimi
cu valori n intervalul [X,Y]. Notm media lor aritmetic cu M. Dorim s le ordonm n aa
fel nct media aritmetic a oricrei subsecvene continue de nlimi s fie n intervalul [(1f)M, (1+f)M], unde f este o fraciune din M (n principiu, 0f1, dar nu este obligatoriu).
Problema 2-3. Numr maxim de interschimbri la heapsort (ACM ICPC NEERC 2004)
Algoritmul de sortare HeapSort a unei permutri cu N elemente funcioneaz n felul
urmtor. n prima etap se construiete un max-heap, adic un heap cu proprietatea c
valoarea din orice nod este mai mare dect valorile din fiii si. Un heap este codificat sub
forma unui vector a(1), ..., a(N) n felul urmtor. Poziia 1 corespunde rdcinii. Poziiile 2i
i 2i+1 corespund celor doi fii ai nodului i (dac 2i>N sau 2i+1>N, atunci fiul respectiv nu
exist). a(i) reprezint valoarea asociat nodului i.
n a doua etap se extrage n mod repetat (de N ori) elementul din rdcina heap-ului
(a(1)). Acest element este adugat n irul sortat pe poziia N, iar n heap, n locul su, este
pus elementul a(N). Dup aceast operaie, N (dimensiunea heap-ului) este decrementat, iar
proprietatea de heap este refcut n modul urmtor. Dac a(1) este mai mic dect vreunul
din fiii si, a(1) este interschimbat cu valoarea maxim a unui din cei doi fii ai rdcinii. Fie
acest fiu x. Se verific apoi, n mod repetat, dac a(x) este mai mic dect vreunul din fiii
nodului x i, dac da, a(x) este interschimbat cu a(y) (unde y este fiul cu valoarea maxim a
nodului x), dup care setm x=y.
Dndu-se N (1N100.000), determinai un heap (ce conine elementele 1, ..., N), pentru
care a doua parte a algoritmului HeapSort realizeaz un numr maxim de interschimbri.
Exemplu: N=6 => a(1)=6, a(2)=5, a(3)=3, a(4)=2, a(5)=4, a(6)=1.
Soluie: Vom determina un heap (o secven a(1), ..., a(N)) n mod inductiv, pornind de la
secvena care maximizeaz numrul de interschimbri pentru N-1. Pentru N=1 avem o
singur secven (a(1)=1), ce genereaz 0 interschimbri.
S presupunem c a(1), ..., a(N-1) este secvena (heap-ul) care maximizeaz numrul de
interschimbri pentru N-1 i, dintre toate aceste secvene, are proprietatea c a(N-1)=1. Vom
determina o secven b(1), ..., b(N), care maximizeaz numrul de interschimbri pentru un
heap de dimensiune N, care va avea b(N)=1. Dup extragerea elementului din rdcin,
valoarea b(1) va fi setat la 1 (iar heap-ul va avea N-1 elemente). Vrem acum ca elementul 1
s coboare ct mai mult n heap (pn pe ultimul nivel din heap). De asemenea, vrem ca
heap-ul obinut dup coborrea elementului 1 s fie a(1), ..., a(N-1) (unde a(N-1)=1).
Aadar, heap-ul b(1), ..., b(N) se obine dup cum urmeaz. Iniializm b(i)=a(i) (1iN1) (momentam, lsm b(N) nesetat). Determinm apoi nodurile de pe drumul de la nodul N-1

21

pn la rdcin. Fie aceste noduri v(1)=N-1, v(2)=v(1)/2, ..., v(i)=v(i-1)/2, ..., v(k)=1
(mpririle se efectueaz pstrndu-se partea ntreag inferioar). Vom parcurge cu un
contor j (j=1,...,k-1) i vom seta b(v(j))=b(v(j+1)) (practic, coborm n heap toate elementele
de pe drumul de la poziia N-1 la rdcina heap-ului, suprascriind valoarea de pe poziia N-1).
Dup aceast coborre, setm b(1)=N i b(N)=1. Astfel, n timp logaritmic
(k=O(log(N))), am obinut heap-ul de dimensiune N care maximizeaz numrul de
interschimbri, pornind de la heap-ul de dimensiune N-1. Un algoritm de complexitate
O(Nlog(N)) este uor de implementat (pornim de la un heap cu un singur element i, pentru
fiecare pas i=2,...,N:
(1) coborm n jos n heap valorile din nodurile de pe drumul de la rdcin pn la nodul
i-1;
(2) punem valoarea i n rdcin;
(3) mrim dimensiunea heap-ului cu 1 element i punem valoarea 1 n nodul i.
O alt soluie este urmtoarea. S considerm c valorile de pe poziiile 1, ..., N ale heapului dorit sunt x(1), ..., x(N). tim c x(1)=N i dorim ca x(N)=1. n mod similar cu soluia
precedent, vom dori ca, dup fiecare extragere a elementului maxim din heap, pe ultima
poziie din heap s ajung elementul 1. Vom iniializa un vector b(i)=i i un graf orientat G
cu N noduri i fr nicio muchie. Apoi, pentru i de la N ctre 2, efectum urmtorii pai:
(1) eliminm elementul b(1) din heap i punem n locul su elementul b(i); tim c acum b(1)
conine valoarea 1, pe care dorim s o ducem pe poziia b(i-1)
(2) fie poziiile poz(1)=b(1), poz(2), ..., poz(K)=b(i-1) corespunztoare, n ordine, poziiilor
din heap de pe drumul de la rdcin (poziia 1) pn la ultima poziie din heap (poziia i-1)
(3) pentru fiecare indice j=2, ..., K, introducem muchie orientat n graful G de la nodul
b(poz(j)) ctre b(poz(j)), unde poz(j) este fratele lui poz(j) (dac exist) ; dac poz(j) este
par, atunci poz(j)=poz(j)+1 (altfel, poz(j)=poz(j)-1).
(4) interschimbm, pe rnd, elementele de pe poziiile poz(j) i poz(j+1) n vectorul b (n
ordine, de la j=1 la j=K-1)
Graful G este un graf de ordine parial. Dac avem muchia orientat i->j n G, atunci
trebuie ca x(i) s fie mai mare dect x(j). G conine O(Nlog(N)) muchii. n continuare vom
sorta topologic nodurile din G, plasnd nodul N la nceput i nodul 1 la final. Vom considera
apoi nodurile i ale lui G n ordinea din sortarea topologic i vom seta x(i)=j, unde j este
poziia lui i n sortarea topologic (1jN). n felul acesta am obinut valorile de pe fiecare
poziie a heap-ului cutat.
Problema 2-4. Tije (Stelele Informaticii 2007)
Se consider N+1 tije, numerotate de la 1 la N+1 (1N100). Tijele 1, ..., N conin
fiecare cte N bile. Bilele de pe tija i au toate culoarea i. Tija N+1 este goal. La orice
moment dat, putei efectua mutri de tipul urmtor: se ia o bil din vrful unei tije surs i se
amplaseaz n vrful unei tije destinaie, cu condiia ca tija surs s conin cel puin o bil
naintea mutrii, iar tija destinaie s conin cel mult N bile dup efectuarea mutrii.
Determinai o secven de mutri astfel nct, n urma executrii mutrilor, pe fiecare tij
de la 1 la N s se gseasc cte N bile, fiecare bil avnd o culoare diferit, iar tija N+1 s fie
goal.
Soluie: Vom rezolva problema n N-1 runde. La fiecare rund r (1rN-1) vom aduce N bile
de culori diferite pe tija r. La nceputul rundei r (1iN-1), tijele 1,...,r-1 sunt deja n starea

22

final, iar primele r-1 bile (cele din vrf) de pe tijele i (riN) sunt de culori diferite de la 1
la r-1. Urmtoarele bile de pe fiecare tij i (riN) sunt de culoarea i.
Vom ncepe prin a muta r bile de pe tija N pe tija N+1. Obinem, astfel, culorile 1,...,r-1
i N pe tija N+1. Vom parcurge apoi, n ordine descresctoare, tijele de la i=N-1 pn la i=r.
Vom muta primele r-1 bile de pe tija i pe tija i+1 apoi vom muta bila rmas n vrful tijei i
(ce are culoarea i) pe tija N+1. Astfel, am obinut bile de toate culorile pe tija N+1. Pe tija r
mai avem N-r bile de culoarea r. Vom muta cte o bil de pe tija r pe fiecare din tijele
r+1, ..., N. Astfel, tija r devine goal. n acest moment, putem muta toate bilele de pe tija
N+1 pe tija r. Acum am ajuns la sfritul rundei. Primele r tije conin bile din toate culorile,
tijele r+1, ..., N au primele r bile (cele din vrf) de culori 1,...,r (ntr-o ordine oarecare), iar
urmtoarele N-r bile de culoarea i (unde r+1iN este numrul tijei).
n total se efectueaz O(N3) mutri.
Problema 2-5. Tierea unui poligon convex tricolorat (TIMUS)
Se d un poligon convex cu N (3N1.000) vrfuri. Fiecare vrf este colorat ntr-una din
culorile R(ou), G(alben) sau V(erde). Exist cel puin un vrf colorat n fiecare din cele 3
culori. Trasai N-2 diagonale care s nu se intersecteze astfel nct triunghiurile obinute
(determinate de diagonale i laturile poligonului) s aib fiecare cte un vrf din fiecare
culoare.
Soluie: Numrm cte vrfuri sunt colorate n fiecare culoare C (num(C)). Ct timp
poligonul are mai mult de 3 vrfuri, alegem un vrf v colorat ntr-o culoare C astfel nct
num(C)>1 i cele dou vrfuri vecine cu vrful v (situate nainte i dup v pe conturul
poligonului) s aib culori diferite (diferite ntre ele i diferite de culoarea lui v). Vom trasa
diagonala determinat de cele dou vrfuri situate nainte i dup v pe conturul poligonului
(vrfurile a i b). Dup aceasta, eliminm vrful v de pe conturul poligonului i vom
considera diagonala proaspt trasat (a,b) ca fiind o latur a poligonului, care are acum cu un
vrf mai puin. Dup eliminarea lui v decrementm cu 1 valoarea num(C) (unde C este
culoarea vrfului v).
Acest algoritm determin o mprire corect sau nu gsete o astfel de colorare (n niciun
caz nu determin o mprire invalid n triunghiuri). S analizm ce ar putea s nu mearg
bine. S presupunem c, la un pas, toate culorile C au num(C)=1. n acest caz, poligonul mai
are doar 3 vrfuri colorate diferit, i cum toate triunghiurile anterioare au vfurile colorate
diferit, am gsit o soluie corect. Aadar, singura problem ce ar putea aprea ar consta n
faptul c, la un moment dat, s-ar putea s nu existe niciun vrf v ai crui vecini s fie colorai
diferit ntre ei i diferit de v.
Algoritmul ar putea fi mbuntit prin folosirea unor euristici pentru alegerea nodului v
care s fie eliminat (atunci cnd pot fi eliminate mai multe astfel de noduri). De exemplu,
dintre toate nodurile ar putea fi eliminat acel nod v de culoare C astfel nct:
(1) num(C) este cel mai mare dintre toi candidaii ; sau
(2) prin eliminarea sa, determin formarea celui mai mare numr de triunghiuri formate
din 3 vrfuri consecutive pe poligon, cu toate cele 3 vrfuri colorate diferit.
Algoritmul poate fi implementat cu complexitatea O(N2).
Problema 2-6. Sortarea cheilor (Olimpiada de Informatic a Europei Centrale, 2005)
Se d un tabel ce conine multe rnduri i C coloane. Valorile de pe fircare coloan sunt
numerice. Asupra acestui tabel se pot efectua operaii de tipul Sort(k) (1kC), care au

23

urmtorul efect: sorteaz rndurile tabelului cresctor, n funcie de valoarea de pe coloana k;


dac dou rnduri au aceeai valoare pe coloana k, atunci, n urma sortrii, ordinea lor
relativ nu se schimb (adic rndul aflat mai sus n tabel rmne deasupra celui aflat mai
jos).
Dou secvene de operaii de sortare sunt echivalente dac produc acelai efect asupra
tabelului, indiferent de valorile coninute n tabel (s presupunem c T1(T) este tabelul
obinut n urma aplicrii primei secvene de operaii asupra unui tabel iniial T, iar T2(T) este
tabelul obinut n urma aplicrii celei de-a doua secvene asupra aceluiai tabel T; trebuie s
avem T1(T)=T2(T), oricare ar fi tabelul iniial T).
Dndu-se o secven de operaii de sortare, determinai cea mai scurt secven
echivalent cu aceasta (care conine un numr minim de operaii).
Exemplu: C=4, secvena=Sort(1) ; Sort(2); Sort(1); Sort(2); Sort(3); Sort(3). Cea mai
scurt secven echivalent este: Sort(1); Sort(2); Sort(3).
Soluie: Rezolvarea problemei se bazeaz pe urmtoarea observaie. Dac avem o secven
Sort(k); X; Sort(k) (unde X este o secven oarecare de operaii), aceasta este echivalent cu
secvena X; Sort(k). Aadar, din secvena dat trebuie s pstrm doar ultima operaie Sort(k)
pentru fiecare coloan k pentru care apare o astfel de operaie.
Vom menine secvena rezultat sub forma unei liste dublu nlnuite (iniial vid). Apoi
vom traversa secvena iniial de la stnga la dreapta i, pentru fiecare coloan k (1kC),
vom reine un pointer p(k) ctre cea mai recent apariie a sa n cadrul secvenei. Cnd
ntlnim o operaie Sort(k), verificm dac p(k) este setat (iniial, p(k) nu este setat, 1kC).
Dac p(k) este setat, atunci tergem din list elementul refereniat de p(k). tergerea se poate
realiza n timp O(1). Dup aceasta inserm operaia Sort(k) la sfritul listei i, indiferent
dac p(k) era setat sau nu, setm p(k) la elementul din list corespunztor lui Sort(k).
La final lista va conine cea mai scurt secven echivalent. Complexitatea acestei soluii
este O(lungimea secvenei + C).
O alt variant, de complexitate O(lungimea secvenei+Clog(C)) const n a reine,
pentru fiecare coloan k, poziia din secven pe care apare ultima operaie Sort(k). La sfrit
sortm coloanele cresctor dup aceast poziie (ignorndu-le pe cele care nu au nicio
apariie) i afim operaiile Sort(*) din secvena echivalent n ordinea sortat a coloanelor.
Problema 2-7. Mesaj (Lotul Naional de Informatic, Romnia, 2005)
Se d un ir de caractere de lungime L. Acest ir conine un mesaj ascuns i a fost obinut
prin concatenarea cuvintelor care formau mesajul i apoi inserarea unor caractere
ntmpltoare la poziii ntmpltoare n ir. N lexicografi s-au decis s descifreze mesajul. n
acest scop, lexicografii vin pe rnd (n ordine, de la 1 la N) i fiecare lexicograf adaug un
cuvnt la un dicionar. Iniial dicionarul este vid. Dup ce a adugat cuvntul, fiecare
lexicograf ncearc s descopere mesajul ascuns n ir. n acest scop, lexicograful
partiioneaz irul ntr-un numr maxim de subsecvene, astfel nct fiecare subsecven s
conin ca subir unul dintre cuvintele existente n dicionar la momentul respectiv. Deci
numrul maxim de subsecvene n care a fost partiionat irul reprezint de fapt numrul de
cuvinte din mesaj identificate de lexicograf (cuvintele din mesaj nu sunt n mod necesar
distincte). Aflai pentru fiecare lexicograf numrul de cuvinte din mesajul descifrat de el.

24

Soluie: Imediat dup citirea irului se va calcula o matrice First(i,c)=cea mai mic poziie j
mai mare sau egal cu i pentru care al j-lea caracter din ir este egal cu c (First(i,c)=i, dac
pe poziia i din ir se afl caracterul c; altfel, First(i,c)=First(i+1,c)).
Cu aceast matrice calculat, pentru un dicionar posibil putem aplica o soluie greedy: se
alege cuvntul pentru care segmentul n care se afl ca subir este minim ca lungime. Putem
sri din caracter n caracter folosind matricea calculat mai sus, obinnd o complexitate
O(LS), unde S este suma lungimilor cuvintelor de pn acum.
Aceast complexitate este mult prea mare (deoarece ea apare la fiecare cuvnt). O
mbuntire const din folosirea unui trie n care s inserm cuvintele. n cadrul greedy-ului,
vom menine o mulime de noduri M din trie, pentru care prefixul corespunztor lor a fost
deja descoperit. Cnd parcurgem un caracter nou c, pentru acele noduri ale trie-ului din M
care au o muchie etichetat cu c ctre unul din fii f, introducem n M fiul f. Cnd am introdus
n M un nod corespunztor unui cuvnt existent n dicionar, atunci am gsit un nou cuvnt.
Dup aceasta, resetm mulimea M (iniial, ea va conine doar rdcina trie-ului). Totui,
complexitatea total nu este mbuntit.
O mbuntire real este urmtoarea. Vom calcula pe parcurs un vector J[i] = cel mai
mic k astfel nct subsecventa irului aflat ntre poziiile i i k (inclusiv) conine un cuvnt
dat (pn acum) ca subir (sau k=i-1 altfel). Avnd calculat acest vector pentru cuvintele
precedente, l putem reactualiza n complexitate O(Lx), unde x este lungimea cuvntului
curent, folosind matricea First (considerm fiecare poziie de nceput i i, folosind matricea
First(*,*), gsim n timp O(x) cea mai mic poziie k cu proprietatea c noul cuvnt apare n
ntervalul [i,k]; apoi setm J[i]=min{J[i], k} sau, dac J[i]<i, atunci J[i]=k). Cu vectorul J
calculat, putem aplica greedy-ul n complexitatea O(r), unde r este rspunsul. ncepem cu
poz=1 (poziiile irului sunt numerotate de la 1 la L) i r=0. Ct timp (pozL i J[poz]poz):
(1) r=r+1; (2) poz=J[poz]+1. Complexitatea total devine O(LS).
Problema 2-8. Monezi (Olimpiada Baltic de Informatic, 2006)
Se dau N (1N500.000) tipuri de monezi. Pentru fiecare tip i (1iN) se cunoate
valoarea monezii V(i) (0V(i)1.000.000.000), precum i dac deinei vreo moned de tipul
respectiv (T(i)=1) sau nu (T(i)=0). Valorile monezilor sunt date n ordine cresctoare i se
tie c V(1)=1.
Determinai o valoare minim SK (1K1.000.000.000), astfel nct mulimea M
generat de urmtorul algoritm s conin un numr maxim de tipuri de monezi i pentru care
T(i)=0:
(1) M={};
(2) ct timp S>0 execut:
(2.1) alege cea mai mare moned i cu V(i)S;
(2.2) adaug moneda i la mulimea M;
(2.3) S=S-V(i)
Soluie: Vom aduga o moned fictiv N+1, cu V(N+1)=+ i T(N+1)=1. Vom parcurge
irul monezilor n ordine cresctoare, meninnd pe parcurs suma S dorit. S presupunem c
am ajuns la moneda i (1iN). Dac S+V(i)>K, atunci algoritmul se termin. Dac T(i)=1,
atunci trecem la moneda urmtoare; altfel, vom verifica dac putem modifica suma S astfel
nct s fie generat o moned de tipul i de ctre algoritm. Dac S+V(i)<V(i+1), atunci V(i)
este prima moned aleas de algoritm pentru suma S=S+V(i); dup ce este aleas aceast
moned, suma devine S i, n continuare, vor fi alese monezile corespunztoare sumei S.

25

Aadar, dac S+V(i)<V(i+1), atunci setm S=S+V(i), adugm tipul i la mulimea de monezi
ce vor fi alese i trecem la moneda urmtoare i+1. Suma final S maximizeaz numrul de
monezi alese de algoritm i este cea mai mic sum cu aceast proprietate.
Problema 2-9. irag (Lotul Naional de Informatic, Romnia 2008)
Pentru a intra n Cartea Recordurilor, locuitorii din Vscui vor face un irag de mrgele
foarte foarte lung. n acest scop ei au cumprat mrgele de K (2K100.000) culori (pentru
fiecare culoare i fiind cunoscut numrul a(i) de mrgele cumprate; 1a(i)109). Locuitorii
din Vscui consider c iragul este frumos dac oricare secven de P (2PK) mrgele
consecutive din irag (2PK) nu conine dou mrgele de aceeai culoare. Determinai
lungimea maxim a unui irag frumos care se poate construi cu mrgelele cumprate.
Soluie: O serie de soluii oferite de d-na prof. Emanuela Cerchez sunt urmtoarele.
1) Vom sorta descresctor vectorul a. Considerm primele p valori din irul a i le vom
scdea cu a(p) (ceea ce ar nsemna c vom plasa mrgelele 1, 2, ..., p de a(p) ori. Resortm
vectorul a i repetm operaia.
Complexitate: O(K2log(K))
2) Observm c dup aplicarea unui pas, tabloul a este divizat n dou subsecvene
descresctoare. Pentru sortare este suficient sa interclasm cele dou secvene.
Complexitatea va fi n acest caz O(K2).
3) O alt soluie este s organizm valorile a(1), a(2), ..., a(K) ca un heap i la fiecare pas s
extragem de p ori maximul, reducem elementele i le reinserm n heap.
Complexitate: O(KPlog(K)).
4) Complexitate: Sortare+O(Plog(S)). (unde S=a(1)+...+a(K))
Sortm vectorul a descresctor. Calculm n vectorul SP irul sumelor pariale:
SP(i)=a(i)+a(i+1)+...+a(K) (SP(K+1)=0 i SP(1jK)=a(j)+SP(j+1)). Vom cuta binar (n
intervalul [0, (SP(1) div P)+2]) numrul maxim de secvene de lungime P pe care le putem
forma. Funcia good(x) verific dac putem construi x secvene de lungime P formate din
valori distincte:
int good(long long x)
{for (i=0; i<p; i++)
{if (x*(p - i) > SP[i]) return -1;
if (a[i] <= x) return i;}
return p;}
Funcia returneaz valoarea -1 dac nu este posibil, respectiv o valoare 0 (poziia) n caz
contrar. Lungimea iragului se determin astfel: rezp+rest, unde: rest=poz+SP[poz]-rez(ppoz) (poz=good(rez)).
O alt soluie bazat tot pe cutarea binar a numrului de secvene de lungime P care s
fie formate din valori distincte este urmtoarea. Cutm valoarea rez n acelai interval ca i
nainte. Testul de fezabilitate (care verific dac se pot forma x astfel de secvene) este
urmtorul. Iniializm 2 contoare Q i R cu 0. Apoi parcurgem toate tipurile i de mrgele
(toate culorile). Dac a(i)>x, setm Q=Q+x; altfel, Q=Q+a(i); dac, la un moment dat,
avem Qx, atunci setm R=R+1 i Q=Q mod x. Dac privim cele x secvene ca fiind x
rnduri ale unei matrici cu x linii i P coloane, R reprezint numrul de coloane pe care am
reuit s le completm n aa fel nct fiecare din cele x linii s conin elemente de valori
(culori) diferite. Dac RP, atunci putem forma x secvene de cte P mrgele de culori

26

diferite => x este o valoare fezabil i vom cuta n continuare un x mai mare. Altfel, x nu
este fezabil i vom cuta n continuare un x mai mic.
La sfritul cutrii binare am obinut un ir de lungime rezP. Mai trebuie s calculm
restul (cte mrgele mai pot fi adugate la sfrit, ntre 0 i P-1). Vom iniializa contoarele R,
Q i nextra la 0 i apoi vom parcurge cele K tipuri (culori) de mrgele (i=1,...,K). Dac
a(i)>rez, atunci setm R=R+rez i Q=Q+1; altfel efectum urmtoarele aciuni:
(1) R=R+a(i);
(2) dac R>rezP atunci {R=R-1; Q=Q+1}; altfel nextra=nextra+1.
Restul va fi egal cu rest=Q+min{R-rezP, nextra}. Aadar, lungimea maxim este
rezP+rest.
Problema 2-10. Numr minim de greuti
Determinai o mulime W cu numr minim de greuti ntregi, care are proprietatea c
orice greutate ntreag ntre 1 i N (1N10100) poate fi cntrit folosind fiecare greutate din
W cel mult o dat i avnd la dispoziie un cntar cu dou talere. Considerm dou cazuri:
(1) greutile se pun doar pe un taler i greutatea de cntrit se pune pe cellalt taler;
(2) greutile din W pot fi puse pe ambele talere (inclusiv lng greutatea de cntrit).
Soluie: Pentru cazul (1), mulimea W const din puterile lui 2 mai mici sau egale cu N:
W={2i|0iparte ntreag inferioar(log2(N))}. Pentru a cntri o greutate X determinm
reprezentarea sa n baza 2. Pentru fiecare bit i (0ilog2(N)) de 1, punem greutatea 2i pe
talerul din stnga. Apoi punem greutatea X pe talerul din dreapta.
Pentru cazul (2) mulimea W const din puterile lui 3 mai mici sau egale cu N, plus cea
mai mic putere a lui 3 mai mare sau egal cu N: W={3i|0iparte ntreag
superioar(log3(N))}. Cnd avem de cntrit o greutate X procedm dup cum urmeaz.
Determinm reprezentarea n baza 3 a lui X. Fie Q(i) puterea la care apare 3i n reprezentarea
lui X (Q(i)=0, 1 sau 2). Parcurgem poziiile i cresctor, ncepnd de la 0, pn la valoarea
maxim posibil (parte ntreag superioar din log3(N)). Vom considera c greutatea X este
amplasat pe talerul din stnga. Dac Q(i)=1, atunci punem greutatea 3i pe talerul din
dreapta (cel opus lui X) i setm Q(i)=0. Dac Q(i)=2, atunci punem greutatea 3i pe talerul
din stnga (lng X), dup care setm Q(i)=0 i Q(i+1)=Q(i+1)+1. Dac Q(i)=0, atunci
trecem la poziia urmtoare. Observm c, n cadrul algoritmului, putem ajunge i cu Q(i)=3
(deoarece realizm i incrementri cu 1). Dac ajungem la o poziie i unde Q(i)=3, atunci
setm Q(i)=0 i Q(i+1)=Q(i+1)+1; apoi trecem mai departe. Observm c n felul acesta, n
cel mai ru caz, este posibil s folosim o greutate 3i unde 3i este cea mai mic putere a lui 3
mai mare sau egal dect X.
Problema 2-11. Traverse (Lotul Naional de Informatic, Romnia 2000)
2 locomotive se afl la capete opuse ale unei ine ce const din N (2N100.000) poziii
(prima locomotiv pe poziia 1, cealalt pe poziia N). Pe fiecare poziie i se afl sau nu o
travers (1iN). O locomotiv se poate deplasa de la poziia curent iK (respectiv iNK+1) la poziia urmtoare (i+1 pentru prima locomotiv i i-1 pentru a doua), numai dac pe
poziia urmtoare se afl o travers sau dac printre ultimele K poziii traversate (inclusiv cea
curent) se afl cel puin o poziie care conine o travers. Dac nici poziia urmtoare i nici
ultimele K (1KN) poziii parcurse nu conin nicio travers, atunci mecanicul locomotivei
va trebui s demonteze o travers de pe o poziie parcurs anterior i s o monteze pe poziia
urmtoare. Dup aceast mutare, locomotiva se poate muta pe poziia urmtoare; dac nu

27

exist nicio travers pe poziiile parcurse anterior i locomotiva se afl n situaia de a nu


putea realiza deplasarea pe poziia urmtoare, atunci locomotiva rmne blocat pe poziia
curent.
Cele 2 locomotive doresc s ajung una lng cealalt, pe poziii consecutive (prima pe o
poziie i, iar a doua pe poziia i+1; 1iN-1). Determinai numrul minim de mutri ce
trebuie efectuate pentru ca cele 2 locomotive s ajung pe poziii alturate.
Soluie: Vom calcula pentru prima locomotiv valorile Tleft(i)=numrul minim de mutri ce
trebuie realizate pentru ca locomotiva s ajung de pe poziia 1 pe poziia i. Avem Tleft(0)=0.
Vom parcurge valorile lui i (1iN) n ordine cresctoare i vom menine dou contoare:
nlipsa=numrul de poziii consecutive fr traverse parcurse de locomotiv de la ultima
poziie cu travers parcurs, i ntrav=numrul de traverse peste care a trecut locomotiva.
Iniial, nlipsa=ntrav=0.
Dac pe poziia i se afl o travers, atunci setm Tleft(i)=Tleft(i-1), nlipsa=0 i
ntrav=ntrav+1. Dac pe poziia i nu se afl o travers i nlipsa<K, atunci setm
Tleft(i)=Tleft(i-1) i nlipsa=nlipsa+1. Dac pe poziia i nu se afl travers i nlipsa=K,
atunci verificm dac ntrav1. Dac ntrav1, atunci vom muta o travers anterioar pe
poziia i i apoi vom seta Tleft(i)=Tleft(i-1)+1 i nlipsa=0. Vom calcula, n mod similar,
nite valori Tright, parcurgnd poziiile descresctor, de la N ctre 1. Avem Tright(N+1)=0.
Pentru 1iN calculm Tright(i) pe baza lui Tright(i+1), considernd aceleai cazuri ca i n
cazul lui Tleft(i) (care a fost calculat pe baza lui Tleft(i-1)). Vom calcula apoi
Vmin=min{Tleft(i)+ Tright(i+1)|1iN-1}, reprezentnd numrul total minim de mutri
necesare. Complexitatea algoritmului este O(N).
Problema 2-12. Cri (Olimpiada Baltic de Informatic 2005)
Avei la dispoziie N cri de joc (1N100.000). Fiecare carte i (1iN) are dou fee i
pe fiecare din ele este scris un numr: a(i) i b(i) (-1000a(i),b(i)1000). Trebuie s aezai
toate crile pe mas, cu una din fee n sus. Pe K (0KN) dintre cri trebuie s schimbai
semnul numrului de pe faa de sus. Fie S suma numerelor de pe feele de sus ale celor N
cri (considernd numerele cu semn schimbat pentru cele K cri alese). Alegei cte o fa
pentru fiecare carte i alegi cele K cri cror s le schimbai semnul, astfel nct S s fie
minim.
Soluie: Dac o carte i este aleas pentru a-i schimba semnul feei de sus, atunci vom pune
pe faa de sus valoarea maxim cmax(i)=max{a(i),b(i)}. Dac nu este aleas, pe faa de sus
ea ar trebui s aib valoarea minim cmin(i)=min{a(i), b(i)}. O prim soluie const din
construirea unui graf bipartit care conine cele N cri n partea stng i 2 noduri (X i Y) n
partea dreapt. O muchie de la o carte i la nodul X are capacitatea 1 i costul cmax(i), iar
muchia (i,Y) are capacitate 1 i costul cmin(i).
Mai introducem dou noduri speciale S i D. Ducem muchii de capacitate 1 (i cost 0) de
la S la fiecare carte i; introducem i muchia (X,D), de capacitate K i muchia (Y,D), de
capacitate N-K.
Vom calcula un flux maxim de cost minim n acest graf. La final, fluxul va fi egal cu N,
iar costul minim va reprezenta suma minim posibil S. Totui, complexitatea acestui
algoritm este prea mare.
O a doua soluie, mult mai simpl, este urmtoarea. Vom presupune iniial c toate crile
contribuie la sum cu semnul neschimbat. n acest caz, avem suma S=suma valorilor cmin(i)

28

(1iN). Vom alege apoi acele K cri pentru care diferena dintre noua lor contribuie i
vechea lor contribuie este minim. Astfel, vom sorta cresctor crile dup valoarea dif(i)=cmax(i)-cmin(i) i le vom alege pe primele K din aceast ordine. Fie Sdif suma celor mai mici
K valori dif(*). Suma minim S este egal cu S+Sdif.
Problema 2-13. Acoperire cu numr minim de intervale
Se dau N (1N100.000) intervale nchise. Intervalul i (1iN) este [A(i), B(i)]. Se mai
d i un interval special [U,V]. Determinai K1 submulimi disjuncte ale mulimii de
intervale {1,,N}, astfel nct reuniunea intervalelor din fiecare submulime s includ
intervalul [U,V].
Soluie: Vom trata nti cazul K=1. Vom sorta intervalele dup captul lor stnga i le vom
parcurge n aceast ordine. Vom aduga i un interval fictiv [V+1, ].
Pe durata parcurgerii vom menine o variabil xc, pe care o iniializm la U. De asemenea,
vom menine dou variabile, xcand i icand, pe care le iniializm la U, respectiv 0.
S presupunem c, n cadrul parcurgerii, am ajuns la intervalul i. Dac A(i)>xc, atunci
verificm dac icand0; dac icand=0, atunci algoritmul se termin; dac icand0, atunci
adugm intervalul icand la submulime, setm xc=xcand, dup care resetm icand=0 dac
am ajuns cu xcV, atunci algoritmul se termin. Dup aceste procesri, verificm dac
A(i)xc i B(i)>xcand; dac da, atunci setm icand=i i xcand=B(i).
Dac la final avem xcV, atunci am gsit o submulime cu numr minim de intervale a
cror reuniuni include intervalul [U,V]. Observm c algoritmul a funcionat dup cum
urmeaz: de fiecare dat a ales intervalul care are captul dreapta cel mai mare i care are o
intersecie nevid cu ultimul interval adugat la submulime. Complexitatea algoritmului este
O(Nlog(N)) de la sortare, plus O(N) de la parcurgerea intervalelor.
Putem generaliza aceast soluie pentru K>1. Vom folosi o structur de date Dxc care va
conine pn unde a ajuns reuniunea intervalelor din fiecare submulime (n Dxc vom reine
perechi (xc, idx); unde 1iK). Vom folosi, de asemenea, o structur Dxcand care va conine
intervalele candidate (cel mult K) cu cele mai mari capete dreapta.
Vom iniializa Dxc prin inserarea perechilor (xc=U, idx=i) (1iK). Dxcand va fi, iniial,
vid. Dxc ofer funciile:
getMin(), care va ntoarce perechea (xc, idx) cu valoare minim a lui xc;
delMin(), care va terge perechea (xc, idx) cu xc minim din Dxc;
add(xc, idx), care adug perechea (xc, idx) n Dxc.
Dxcand ofer funcii similare:
getMax() va ntoarce perechea (xcand, icand) cu valoare maxim a lui xcand;
delMax() va terge din Dxcand perechea (xcand, icand) cu valoare maxim a lui xcand;
add(xcand, icand) adaug perechea (xcand, icand) n Dxcand.
Vom parcurge apoi cele N intervale n aceeai ordine ca i n soluia pentru K=1 (n
ordine cresctoare ale capetelor stnga), folosind i de aceast dat intervalul fictiv [V+1, ].
S presupunem c n cadrul parcurgerii am ajuns la intervalul i. Ct timp
A(i)>Dxc.getMin().xc vom efectua urmtoarele aciuni:
(1) dac Dxcand este vid, atunci algoritmul se termin;
(2) altfel, fie (xcand, icand)=Dxcand.getMax() i (xc, idx)=Dxc.getMin(); dac xcand>xc,
atunci apelm Dxc.delMin(), Dxcand.delMax(), dup care adugm perechea (xcand, idx) n

29

Dxc, precum i intervalul icand n submulimea de intervale S(idx) (presupunem c avem K


astfel de submulimi, numerotate de la 1 la K).
Dac avem Dxc.getMin().xcV, atunci algoritmul se termin. Altfel, vom considera
intervalul i la care am ajuns drept un interval candidat. Vom introduce perechea (B(i), i) n
Dxcand.
Din punct de vedere al implementrii, Dxc i Dxcand pot fi:
(1) vectori meninui sortai;
(2) min-heap i, respectiv, max-heap;
(3) arbori echilibrai.
n cazul (1), operaia de gsire a minimului (maximului) dureaz O(1), iar o operaie de
inserare/tergere dureaz O(lungimea vectorului). Dxc conine mereu K elemente, deci
inserrile i tergerile vor dura O(K). n cazul lui Dxcand, am putea ajunge cu O(N) elemente
n vector, deci o inserare/tergere ar putea dura O(N). Dac, ns, dup fiecare inserare dup
care avem mai mult de K elemente n Dxcand tergem elementul minim, pentru a rmne cu
cel mult K elemente, lungimea lui Dxcand este limitat la K elemente, iar operaiile de
inserare/tergere dureaz O(K).
n cazul min-heap-ului (max-heap-ului), gsirea minimului (maximului) se face n O(1),
iar inserarea unui element sau tergerea minimului (maximului) se fac n O(log(K)) (pentru
Dxc), respectiv O(log(N)) pentru Dxcand. n acest caz, e mai greu s limitm numrul de
elemente din Dxcand la K, deoarece ar trebui s avem acces i la perechea (xcand, icand) din
Dxcand cu xcand minim. Pentru asta, am putea folosi un min-max-heap n locul unui maxheap.
Dac folosim arbori echilibrai, toate operaiile au complexitatea O(log(K)) pentru Dxc i
O(log(N)) sau O(log(K)) pentru Dxcand. Folosind arbori echilibrai putem avea acces uor la
cel mai mic i cel mai mare element din Dxcand, astfel c putem realiza tergeri pentru a
menine numrul de elemente la cel mult K.
n cel mai bun caz, aadar, complexitatea soluiei este O(Nlog(K)). O extensie interesant
(pentru K=1) este urmtoarea: fiecare interval i are o pondere w(i)0 i dorim s gsim o
submulime de intervale cu suma minim a ponderilor, astfel nct reuniunea lor s includ
intervalul [U,V].
Putem rezolva aceast problem dup cum urmeaz. Vom sorta toate capetele stnga i
dreapta ale intervalelor (inclusiv ale intervalului [U,V]), obinnd un ir x(1)<x(2)<...<x(Q)
(unde Q2n+2 este numrul de coordonate distincte). Fie i i j indicii pentru care x(i)=U i
x(j)=V.
Vom construi o mulime de puncte P, dup cum urmeaz. Dac i=j, P={x(i)}. Altfel, vom
aduga la P puncte avnd coordonate de forma: (x(g)+x(g+1))/2 (igj-1). Acum putem
folosi un algoritm de programare dinamic, prezentat n [Andreica-MCBE2008], pentru a
gsi o submulime de intervale de pondere total minim pentru a acoperi mulimea de
puncte P. Trebuie doar s observm c dac fiecare punct din P este acoperit de un interval
din submulime, atunci ntregul interval [U,V] este acoperit de un interval din submulime.
Complexitatea algoritmului de programare dinamic este O(Nlog(N)).
Problema 2-14. Bilete la concert (Olimpiada de Informatic a Europei Centrale, 2005)
ntr-o sal de concert exist N (1N100.000) locuri, aezate n linie i numerotate de la
1 la N, de la stnga la dreapta. ntruct urmeaz s aib loc un concert al unei formaii foarte
populare, organizatorii concertului au scos la vnzare biletele pentru concert, pe care le vnd
n intervale de cte L (1LM) locuri consecutive. S-au primit M (1M100.000) cereri de

30

cumprare. O cerere i (1iM) specific primul loc P(i) pentru care se doresc bilete
(1P(i)N-L+1); astfel, cererea dorete cumprarea biletelor pentru locurile P(i), P(i)+1, ...,
P(i)+L-1.
Preul cumprrii biletelor pentru L locuri consecutive, ncepnd de la primul loc
specificat, este 2 RON. Organizatorii i-au dat seama c ar putea obine un profit mai mare
dac, pentru unele cereri, nu ar aloca exact cele L locuri consecutive cerute (ncepnd de la
poziia P(i)), ci alte L locuri consecutive. n acest caz, cei care au emis cererea ar cumpra
oricum biletele (concertul fiind foarte popular), ns nu ar fi dispui s plteasc dect 1
RON (ntruct intervalul de L locuri consecutive nu ncepe de unde au dorit ei).
Primind foarte multe cereri, este posibil ca unele dintre ele s fie refuzate (ntruct ori nu
pot fi satisfcute, ori nu ar fi folositoare ntr-o strategie de vnzare a biletelor care aduce
profitul maxim). tiind c biletul unui loc nu poate fi vndut dect n cadrul unui interval de
L locuri consecutive asociat unei singure cereri, determinai profitul maxim pe care l pot
obine organizatorii concertului.
Soluie: n prima etap vom sorta cererile descresctor dup primul loc cerut din cadrul
intervalului de L locuri consecutive (adic dup valorile P(i)). Vom menine o mulime S a
cererilor satisfcute total (iniial, S este vid), precum i o valoare Pmin, reprezentnd cel
mai din stnga loc ocupat pn acum (iniial, Pmin=N+1).
Vom parcurge cererile n ordinea sortat descresctor dup P(i). Cnd ajungem la o
cerere i, dac P(i)Pmin-L, atunci adugm cererea i la mulimea S i setm Pmin=P(i);
altfel, trecem la cererea urmtoare. Vom nota cererile din S prin S(1), ..., S(K), unde S(1) este
ultima cerere adugat, iar S(K) este prima cerere adugt n S (deci, sunt numerotate n
ordine invers adugrii n S, dar n ordine cresctoare a primului loc P(i) cerut; K=numrul
total de cereri adugate n S). Pentru fiecare cerere i, vom menine um marcaj care indic
dac i face parte din S sau nu (astfel, verificarea dac o cerere i face parte din S sau nu se
realizeaz n O(1)).
n al doilea pas vom modifica mulimea S, fr a-i micora cardinalul. Vom sorta
cresctor dup valoarea P(i) toate cererile (inclusiv cele din S). Vom menine un indice q
care reprezint o cerere din S (S(q)) care ar putea fi nlocuit de o cerere mai eficient.
Iniial, q=1. Vom parcurge apoi cererile, n ordinea sortat. S presupunem c am ajuns
la o cerere i. Dac i nu este n S, atunci: ct timp P(i)P(S(q)) i q<K, incrementm indicele
q cu 1. La ieirea din acest ciclu, dac (P(i)<P(S(q))) i ((q=1) sau (q>1 i P(i)P(S(q1))+L)), atunci vom efectua urmtoarele aciuni:
(1) fie FFree=cea mai din stnga poziie liber, cu proprietatea c toate poziiile FFree,
FFree+1, ..., P(S(q))-1 sunt i ele libere; dac q=1, FFree=0; altfel, FFree=P(S(q-1))+L; (2)
dac (P(i)<P(S(q))) i (((P(i) FFree) mod L) < ((P(S(q)) FFree) mod L)), atunci vom
nlocui cererea S(q) din S cu cererea i (practic, vom marca c cererea S(q) nu mai face parte
din S; apoi vom seta S(q)=i i vom marca c cererea i face parte din S).
n ultima etap vom umple golurile dintre cererile din S, folosind cererile rmase. Au mai
rmas M-K cereri nesatisfcute total. Vom calcula numrul C de cereri ce mai pot fi adugate.
Iniializm C cu ((P(S(1))-1) div L) (div ntorce ctul mpririi ntregia dou numere). Apoi
incrementm C cu fiecare valoare (P(S(q)) P(S(q-1)) L) div L (2qK-1). La final, mai
adugm la C valoarea ((N-P(S(K))-L+1) div L).
Profitul maxim ce poate fi obinut este 2K+min{M-K, C}. Complexitatea algoritmului
este O(Mlog(M)), pentru sortarea cererilor. Putem folosi i o variant a sortrii prin
numrare, pentru a ajunge la o complexitate O(N+M) (pentru fiecare poziie j reinem o list

31

cu toate cererile i care au P(i)=j; apoi concatenm aceste liste n ordine cresctoare sau
descresctoare a poziiei j, obinnd sortarea dorit).
Demonstraia c algoritmul gsete o soluie optim SALG are la baz urmtoarele tehnici.
Presupunem c exist o soluie optim SOPT. Putem arta c SOPT poate fi modificat fr
a-i micora profitul total, astfel nct s ajungem la SALG. Pentru nceput, putem arta c
SOPT poate fi modificat pentru a conine K cereri satisfcute total. Este clar c nu poate
conine mai mult de K (deoarece K a fost calculat astfel nct s reprezinte numrul maxim
de cereri satisfcute total). Dac SOPT conine mai puin de K cereri, atunci putem nlocui/
aduga acele cereri X din SALG la SOPT, care nu se suprapun cu cererile satisfcute total din
SOPT (o cerere X din SALG se poate intersecta cu cel mult 2 cereri Z satisfcute parial n
SOPT, care vor fi eliminate i nlocuite de X, fr a micora profitul total).
Apoi, dac tot nu avem K cereri satisfcute total n SOPT, nseamn c avem o cerere X
satisfcut total n SOPT care intersecteaz 2 cereri Y satisfcute total n SALG. Vom elimina
cererea X i cel mult alte 2 cereri satisfcute parial n SOPT i le vom nlocui cu cererile din
SALG. Astfel, vom ajunge s avem K cereri satisfcute total n SOPT. Dintre toate soluiile
cu K cereri satisfcute total, cea construit conform algoritmului descris maximizeaz
numrul de cereri satisfcute parial care pot fi puse pe lng cele K cereri satisfcute total.
Astfel, demonstraia este complet.
Problema 2-15. Verificarea unor secvene de operaii
Se dau d (1d5) secvene de operaii ce formeaz un program. Secvena i const din
m(i) (1m(i)100.000; m(1)m(d)10.000.000). Operaia j din secvena i (1id;
1jm(i)) este de forma Add(q,x) i reprezint adunarea valorii x la variabila q.
Exist n total K variabile, numerotate de la 1 la K, avnd valorile iniiale v(1), ..., v(K).
Pentru fiecare variabil q exist o funcie F(q,x) care ntoarce 1 dac se consider OK cazul
n care valoarea variabilei q ar fi x, respectiv 0, dac nu este considerat OK.
Cele d secvene de operaii se execut n paralel. O stare a programului const dintr-un
tuplu (op(1), ..., op(d)) (0op(i)m(i); 1id), avnd semnificaia c s-au executat op(i)
operaii din secvena de operaii i. Pentru fiecare stare (op(1), ..., op(d)) vrem s determinm
numrul de variabile q pentru care F(q,v(q))=1 (v(q) este valoarea curent a variabilei q,
care depinde doar de operaiile efectuate pn acum n cele d secvene). Vom nota acest
numr prin NV(op(1), ..., op(d)).
Soluie: Vom considera, pe rnd, fiecare tuplu (op(1), ..., op(d-1)) i vom reine, pentru
fiecare variabil q, vS(q, op(1), ..., op(d-1)). Avem vS(q, op(1)=0, ..., op(d-1)=0)=v(q).
Pentru cazul cnd avem cel puin o valoare op(j)>0, vS(q, op(1), ..., op(d-1))=vS(op(1), ...,
op(j-1), op(j)-1, op(j+1), ..., op(d-1))+(dac operaia op(j) a secvenei j este Add(q,x), atunci
x; altfel, 0).
Pentru fiecare tuplu (op(1), ..., op(d-1)) vom considera, pe rnd, valorile lui op(d) (de la 0
la m(d)). Vom iniializa un contor NOK=numrul de variabile j pentru care F(q, vS(q,
op(1), ..., op(d-1)))=1. Fie v(q)=vS(q, op(1), ..., op(d-1)). Avem NV(op(1), ..., op(d-1),
0)=NOK. Cnd trecem de la valoarea op(d)-1 la valoarea op(d), incrementm v(q) cu x,
unde operaia op(d) a secvenei d este Add(q,x). Apoi setm NOK=NOK+F(q, v(q))-F(q,
vant(q)) (unde vant(q) este valoarea anterioar a variabilei q, adic v(q)-x) i NV(op(1), ...,
op(d))=NOK.

32

Complexitatea acestui algorithm este O(m(1)...m(d-1)(K+m(d))). Observm c putem


considera secvenele n orice ordine. Astfel, a d-a secven va fi cea cu numr maxim de
operaii.
O aplicaie a acestei probleme const n detecia existenei de deadlock-uri (poteniale) n
programe concurente. S presupunem c fiecare variabil q corespunde unui semafor care are
o valoare iniial v(q)0. Cele d secvene de operaii reprezint d thread-uri care se execut
n paralel. O operaie Add(q,x) incrementeaz sau decrementeaz valoarea semaforului q.
Dac n urma operaiei, valoarea semaforului q ar trebui s devin negativ, atunci thread-ul
respectiv se blocheaz pn cnd alt thread mrete valoarea semaforului q suficient de mult.
Un deadlock este o situaie n care exist cel puin un thread care nu i-a ncheiat execuia, i
niciunul din thread-urile care nu i-au ncheiat execuia nu pot executa urmtoarea operaie
(deoarece ar micora sub 0 valoarea unui semafor).
Vom construi un graf al strilor (op(1), ..., op(d)). Funcia F(q,x) ntoarce 1 dac x0, i
-1, dac x<0. Vom aplica algoritmul descris anterior i vom marca ca fiind invalide toate
strile (op(1), ..., op(d)) pentru care NV(op(1), ..., op(d))<K. Graful va consta numai din
strile valide. Vom avea muchii orientate de la o stare valid (op(1), ..., op(d)) ctre fiecare
din strile valide de forma (op(1), ..., op(d)), unde op(j)=op(j)+1 i op(ij)=op(i) (1jd).
Vom parcurge apoi graful ncepnd din starea (0, 0, ..., 0) i vom marca ca fiind atinse toate
strile la care putem ajunge (vom folosi, de exemplu, o parcurge n lime sau n adncime).
Toate strile (op(1), ..., op(d)) din care nu iesie nicio muchie i care au cel puin o valoare
op(i)<m(i) (1id) sunt stri de deadlock. Dac exist cel puin o stare de deadlock care s
fie i valid, i atins, atunci programul prezint posibilitatea apariiei deadlock-urilor.
Problema 2-16. Ptrate (Lotul Naional de Informatic, Romnia 2007, enun
modificat)
Pe o foaie de matematic sunt LxL (1L5.000) ptrele cu latura egal cu 1 cm.
Ptrelele sunt evident organizate n L linii (numerotate de sus n jos de la 1 la L) i L
coloane (numerotate de la stnga la dreapta de la 1 la L). Poziia fiecrui ptrel de pe foaie
este caracterizat prin numrul liniei i numrul coloanei pe care se afl ptrelul.
Pe foaie sunt nnegrite N (1N100.000) ptrele. Trebuie s desenm pe foaia de
matematic o mulime de ptrate care s ndeplineasc urmtoarele condiii:
aria interseciei ntre oricare dou ptrate din aceast mulime este 0;
oricare dintre ptratele acestei mulimi este alctuit doar din ptrele ntregi;
oricare ptrel negru aparine exact unuia dintre ptratele mulimii;
pentru oricare dintre ptratele acestei mulimi, dac notm cu S aria ptratului, atunci
suprafaa ocupat de ptrelele negre din interiorul respectivului ptrat aparine
intervalului [S/k, 4S/k), unde k (5k10) este un numr natural nenul dat.
Se garanteaz c N<L2/k. Determinai o mulime de ptrate care s respecte condiiile de
mai sus.
Soluie: Pentru nceput vom considera ptratul de latur x=L, avnd colul din stnga-sus la
(1,1), care cuprinde toate ptrelele negre i n care aria ocupat de ptrelele negre este
mai mic dect S/k, unde S este aria ptratului de latur x (adic x2).
mprim acest ptrat n patru ptrate egale disjuncte de latur x/2 (prin cele dou linii
mediane) i n aceste 4 ptrate aria punctelor negre nu va depi 4S/k (deoarece aria celor 4
ptrate este de patru ori mai mic dect aria ptratului iniial). Pentru fiecare dintre aceste
patru ptrate avem unul din urmtoarele 3 cazuri:

33

el nu conine nici un ptrel negru; n acest caz, ptratul respectiv nu mai prezint
niciun interes
el conine un numr de ptrele negre a cror arie nsumat se ncadreaz ntre limitele
impuse prin enun: n acest caz el va face parte din soluie;
aria ptrelelor negre este mai mic dect (aria ptratului)/k; n acest caz l divizm n
4 ptrate disjuncte egale i aplicm acelai procedeu pe care l-am aplicat pentru ptratul
iniial
n cel mai defavorabil caz obinem ptrate de latur egal cu 2 care conin un singur
ptrel negru. Acestea ndeplinesc condiiile din enun (deoarece 1/k<1/4).
Pentru a determina eficient numrul de ptrele negre putem folosi mai multe tehnici de
orthogonal range count. Putem folosi range tree, pentru a rspunde la o ntrebare n timp
O(log2(N)) (sau O(log(N)), dac folosim fractional cascading). innd cont de limitele
coordonatelor punctelor, putem calcula o matrice P de dimensiuni LxL, unde P(i,j) este egal
cu numrul de puncte din dreptunghiul (1,1)-(i,j). Avem P(i,j)=P(i,j-1)+P(i-1,j)-P(i-1,j-1) +
(1, dac ptrelul (i,j) este negru; 0, dac este alb). Folosind aceast matrice, numrul de
puncte negre dintr-un dreptunghi (a,b)-(c,d) (cu ab i cd) este egal cu P(c,d)-P(c,b-1)-P(a1,d)+P(a-1,b-1). Matricea se calculeaz n timp O(L2), iar rspunsul la o ntrebare se d n
timp O(1).

Problema 2-17. Tablete (Algoritmiada, infoarena 2008)


Construii o matrice A cu N linii i N coloane care s conin fiecare din numerele de la 1
la N2 exact o dat, astfel nct:
pe fiecare linie a matricii, numerele sunt n ordine cresctoare.
pe coloana K (2KN-1), numerele trebuie s fie pare.
Soluie: Vom ncepe prin a amplasa valorile de pe coloana K. Iniializm o variabil p=NK
i row=N. Ct timp row1 efectum urmtorii pai:
1) dac p este par, atunci: {
1.1) A(row,K)=p;
1.2) vmin=p;
1.3) row=row-1};
2) p=p-1.
Vom completa apoi primele K-1 coloane. Iniializm o variabil next=0. Parcurgem apoi
liniile matricii A, n ordine, de la 1 la N: pentru fiecare rnd row, parcugem coloanele i de la
1 la K-1.
S presupunem c am ajuns la linia row i coloana i. Mai nti incrementm variabila next
cu 1. Apoi, ct timp (nextvmin) i (next este par), incrementm variabila next cu 1. Vom
seta apoi A(row,i)=next.
n continuare, vom completa coloanele K+1,...,N ale matricii A. Iniializm variabila
next=NK (toate numerele de la 1 la NK au fost amplasate pe primele K coloane ale matricii
A). Parcurgem apoi matricea A pe linii i, pentru fiecare linie row, parcurgem matricea pe
coloane, de la i=K+1 la N.
Pentru o linie row i o coloan i, incrementm variabila next cu 1 i apoi setm
A(row,next)=1.
La final, putem avea o problem dac NK este un numr impar: n acest caz, vom rezolva
problema interschimbnd elementele de pe poziiile (linie=1, coloan=K+1) i
(linie=N,coloan=K) din matricea A.

34

Problema 2-18. mprirea unui multiset n numr minim de submulimi


Se d un multiset S ce conine N (1N100.000) numere: S(1), ..., S(N). mprii aceste
numere n ct mai puine submulimi, astfel nct elementele din fiecare submulime s fie
distincte dou cte dou. n caz c exist mai multe mpriri posibile cu numr minim de
submulimi, alegei-o pe aceea pentru care diferena dintre numrul maxim de elemente
dintr-o submulime i numrul minim de elemente s fie ct mai mic.
Soluie: Vom sorta numerele, astfel nct s avem x(1)<x(2)<...<x(M) (MN) i
cnt(i)=numrul de apariii ale elementului x(i) n S. Putem realiza aceast sortare uor, n
timp O(Nlog(N)), sau, dac numerele nu au valori foarte mari, putem folosi sortarea prin
numrare (count sort).
Numrul minim de submulimi necesare este NS=max{cnt(i)|1iM}. n continuare, vom
construi cele NS submulimi: SM(0), ..., SM(NS-1), dup cum urmeaz. Le iniializem pe
toate la mulimea vid, apoi iniializm un contor k=0. Vom parcurge cele M elemente
distincte i, pentru fiecare element cu indicele i, vom realiza de cnt(i) ori urmtorii pai:
(1) adaug x(i) la submulimea SM(k);
(2) k=(k+1) mod NS.
n felul acesta, diferena dintre numrul maxim i minim de elemente dintr-o submulime
este cel mult 1 (sau 0 dac N este multiplu al lui NS). Datorit distribuirii de tip round-robin
a elementelor n submulimi, nu se va ajunge ca aceeai submulime s conin dou
elemente egale.
Problema 2-19. Secven redus (Olimpiada Baltic de Informatic, 2007)
Se d o secven a(1), ..., a(N) (1N1.000.000). Asupra acestei secvene se poate
efectua urmtoarea operaie: reduce(i)=nlocuiete elementele a(i) i a(i+1) din secven cu
elementul max{a(i),a(i+1)} (1iN-1). n urma acestei operaii, secvena va rmne cu N-1
elemente. Costul operaiei este max{a(i),a(i+1)}.
Determinai o secven de N-1 operaii reduce de cost minim (n urma crora secvena
iniial este redus la un singur element).
Soluie: O soluie bazat pe programare dinamic este evident. Fie cmin(i,j)=costul minim
pentru a reduce subsecvena a(i), a(i+1), ..., a(j) l aun singur element. Avem cmin(i,i)=0.
Pentru i<j (n ordine cresctoare a lui j-i+1) vom avea:
cmin(i,j)=min{cmin(i,k)+cmin(k+1,j)|ikj-1}+Max(i,j).
Max(i,j) este elementul maxim dintre a(i), a(i+1), ..., a(j). Acest algoritm are
complexitatea O(N3) i este foarte ineficient pentru limitele date.
Un algoritm greedy este urmtorul. Fie M=N-1. Repet de M ori urmtorii pai:
1) gsete orice indice i astfel nct a(i-1)a(i)a(i+1) (considerm a(0)=a(N+1)=+);
2) dac a(i-1)<a(i+1) atunci aplic operaia reduce(i-1); altfel aplic operaia reduce(i);
3) renumeroteaz elementele de la 1 la N-1 i descrete pe N cu 1.
O implementare direct a acestui algoritm are complexitate O(N2). O implementare cu
complexitate O(N) este urmtoarea. Vom parcurge secvena i vom menine o stiv S i un
cost C. Iniializm stiva astfel nct S(1)=a(0)=+, S(top=2)=a(1) i C=0. Apoi vom
considera poziiile i=2, 3, ..., N+1.
Dac a(i)<S(top) atunci l adugm pe a(i) n vrful stivei:
1) top=top+1;

35

2) S(top)=a(i).
Altfel (a(i)>S(top)), atta timp ct condiia de oprire nu este ndeplinit, vom efectua n
mod repetat urmtorii pai:
1) dac S(top-1)<a(i) atunci reduce elemente S(top-1) i S(top) (i crete C cu S(top-1)),
altfel reduce elementele S(top) i a(i) (i crete C cu a(i));
2) elimin S(top) din vrful stivei: top=top-1.
Dac i=N+1, atunci condiia de oprire este ca stiva s conin doar 2 elemente (top=2),
deoarece unul din ele este n mod sigur a(0) => secvena iniial a fost redus la un singur
element. Dac i<N+1 atunci condiia de oprire este urmtoarea: a(i)<S(top).
La sfritul ciclului de reduceri, dac i<N+1, atunci l adugm pe a(i) n vrful stivei:
1) top=top+1;
2) S(top)=a(i).
O alt soluie liniar foarte simpl este de a calcula C ca fiind egal cu suma valorilor
max{a(i),a(i+1)} (1iN-1). Demonstraia acestui fapt se bazeaz pe inducie. S
presupunem c este adevrat pentru orice secven cu qk elemente i dorim acum s o
demonstrm pentru o secven cu k elemente. Pentru k=1 faptul este adevrat (costul fiind 0).
Pentru k2, fie p poziia unde se afl elementul maxim M din secven. Dac p=1 (p=k)
atunci reducem secvena din dreapta (stnga) maximului, iar la final mai efectum o reducere
de cost M. Dac 2pk-1 vom reduce separat secvenele din stnga i din dreapta maximului,
iar la sfrit vom reduce de dou ori maximum mpreun cu cele 2 elemente rmase n stnga
i, respectiv, dreapta acestuia. n toate cazurile, costul obinut de aceast strategie este egal
cu valoarea calculat dup regula menionat mai sus.

36

Capitolul 3. Grafuri.
Problema 3-1. Sincrograf (Summer Trainings 2003 - Rusia, SGU)
Se d un graf orientat cu N (1N10.000) noduri i M (0M100.000) muchii, n care
fiecare muchie q (1qM), orientat de la i la j, are ataat o valoare w(q).
Un nod i se numete activ dac toate muchiile q care intr n i au w(q)>0 (dac nu exist
nicio astfel de muchie, nodul se consider inactiv).
Din mulimea nodurilor active, se poate selecta un nod i pentru a fi declanat. Cnd un
nod i este declanat, se scade cu 1 valoarea w(qin) ataat tuturor muchiilor qin care intr n
nodul i i se crete cu 1 valoarea w(qout) a tuturor muchiilor qout care ies din nodul respectiv.
Un nod se numete potenial viu dac, pornind din starea curent a grafului, exist o
secven de declanri, n urma creia nodul i poate fi declanat.
Un nod se numete viu, dac este potenial viu pornind din orice stare a grafului n care se
poate ajunge ncepnd din starea iniial.
Determinai toate nodurile vii ale grafului.
Exemplu:
N=6, M=8
Nodurile vii sunt nodurile 1 i 6.
muchia 1: (1->2), w(1)=1
muchia 2: (4->3), w(2)=0
muchia 3: (2->4), w(3)=0
muchia 4: (4->3), w(4)=1
muchia 5: (1->6), w(5)=0
muchia 6: (6->3), w(6)=1
muchia 7: (3->2), w(7)=0
muchia 8: (4->5), w(8)=1000000000
Soluie: Vom determina componentele tare conexe ale grafului dat (n complexitate
O(N+M)). Dac o component tare conex SCCi conine un ciclu orientat Czero n care toate
muchiile au valoare 0, atunci niciun nod din SCCi nu este viu. nti, este evident c nodurile
de pe acest ciclu nu pot fi vii, deoarece ele nu vor putea fi declanate niciodat. Oricare din
celelalte noduri face parte dintr-un ciclu orientat C care conine un nod x care face parte i
din Czero. Dac declanm nodurile de pe C n ordine, ori de cte ori putem, ncepnd cu
succesorul y al nodului x pe ciclul C, vom ajunge ntr-o stare n care nu mai putem declana
niciun nod de pe acest ciclu (deoarece muchia (x,y) va avea valoarea ataat 0 i nu va mai
crete niciodat).
Considerm acum graful orientat aciclic al componentelor tare conexe. Vom sorta
topologic aceste componente tare conexe, n ordinea SCC1, ..., SCCk. Vom reine, pentru
fiecare component, dac este marcat ca fiind moart sau nu. Dac o component conine
un ciclu orientat cu muchii avnd valoare 0, o vom marca ca fiind moart.
Pentru a determina dac o component tare conex conine un ciclu cu muchii de valoare
0, procedm n felul urmtor. Vom considera graful ce const din nodurile componentei i
muchiile de valoare 0. Pentru a determina dac exist un ciclu n acest graf, vom efectua
parcurgeri DFS, dup cum urmeaz. Iniial marcm toate nodurile ca fiind nevizitate. Apoi
considerm pe rnd fiecare nod i, dac acesta este nevizitat, pornim o parcurgere DFS din el.
Toate nodurile vizitate din cadrul parcurgerii DFS sunt marcate ca fiind vizitate imediat ce se

37

intr n ele. n cadrul parcurgerii, dintr-un nod x se poate ajunge direct doar n acele noduri
y nevizitate nc ctre care exist muchie orientat din x.
De asemenea, n cadrul parcurgerii, vom marca ca fiind n stiv toate nodurile aflate
curent n stiva DFS (cnd se intr ntr-un nod, acesta este marcat ca fiind n stiv, iar cnd se
iese dintr-un nod, acesta este demarcat, el nemaifiind n stiv). Dac n cadrul parcurgerii,
atunci cnd vizitm un nod x, gsim o muchie orientat de la un nod x la un nod y aflat n
stiv, atunci am detectat un ciclu.
Complexitatea detectrii ciclurilor de muchii cu valoare 0 pentru toate componentele tare
conexe este O(N+M).
Parcurgem apoi irul componentelor tare conexe n ordinea 1,...,k. Dac SCCi este
marcat ca fiind moart, vom marca ca fiind moarte toate componentele SCCj (j>i) pentru
care exist o muchie oreintat (SCCi->SCCj) n graful orientat aciclic al componentelor tare
conexe.
Toate nodurile din componente tare conexe care nu au fost marcate ca fiind moarte vor fi
vii.
Problema 3-2. Secven grafic
Se d un ir format din N elemente naturale: d(1), ..., d(N) (0d(i)N-1). Decidei dac
exist un graf neorientat cu N noduri astfel nct fiecare nod i (1iN) s aib gradul d(i).
Construii un astfel de graf.
Soluie: O soluie uor de implementat este urmtoarea. Sortm irul de valori date astfel
nct d(1)d(2)...d(N) i reinem n vectorul v nodurile corespunztoare (v(i) corespunde
valorii d(i)).
Legm nodul v(1) de nodurile v(2), ..., v(2+d(1)-1). Dup aceea scdem cu 1 valorile lui
d(2), ..., d(2+d(1)-1), sortm valorile de la 2 la N (modificnd, n acelai timp, i vectorul v,
astfel nct, n orice moment, v(i) corespunde valorii d(i)). Efectum apoi acelai procedeu,
considernd doar valorile d(2), ..., d(N).
Practic, algoritmul va consta din N pai. La fiecare pas i avem doar valorile d(i), ..., d(N).
Legm nodul v(i) de nodurile v(i+1), ..., v(i+d(i)), scdem cu 1 valorile lui d(i+1), ...,
d(i+d(i)) i resortm valorile d(i+1), ..., d(N).
Dac, la un moment dat, avem d(i)>N-i sau ajungem cu d(i)<0, atunci nu exist soluie.
Acest algoritm se poate implementa uor n complexitate O(N2log(N)) (N sortri). Totui,
complexitatea se poate reduce la O(N2), deoarece, pentru a sorta valorile d(i+1), ..., d(N) la
sfritul pasului i, este suficient s interclasm dou iruri sortate: primul ir conine valorile
d(i+1), ..., d(i+d(i)), iar al doilea conine valorile d(i+d(i)+1), ..., d(N). Interclasarea se poate
realiza n timp O(N), obinnd, astfel, complexitatea precizat.
O alt metod pentru a sorta valorile n timp O(N) la sfritul fiecrui pas este s ne
folosim de faptul c valorile sunt numere ntregi din intervalul [0,N-1]. Astfel, putem
construi cte o list L(x) (iniial vid) pentru fiecare valoare x (0xN-1) i inserm valorile
de sortat n lista corespunztoare valorii. La final, doar concatenm n ordinea 0, ..., N-1 cele
N liste.
Evident, metoda descris mai sus poate fi folosit att pentru a construi graful, ct i
pentru a decide dac exist un graf ale crui noduri s aib gradele date. Totui, exist un
algoritm liniar pentru problema de decizie. Sortm n timp O(N) valorile d(1), ..., d(N), astfel
nct d(1)...d(N). Sortarea liniar se poate realiza folosind sortarea prin numrare. Avem
acum urmtoarele dou condiii:

38

1)

2)

i =1
k
i =1

d (i ) este par.
N

d (i ) < k ( k 1) + i = k +1 min{d (i ), k } , pentru orice k=1,...,N.

Condiia (1) este uor de verificat n timp O(N) (calculnd sume prefix).
Pentru condiia (2), un algoritm cu timpul O(N2) este evident. Pentru a obine un timp
liniar, vom ncepe prin a calcula sumele prefix sd(i): sd(0)=0 i sd(1in)=sd(i-1)+d(i).
Vom porni apoi cu k de la N ctre 1, meninnd un vector cnt, unde cnt[i] reprezint numrul
de valori min{d(j),k}=i (j>k).
De asemenea, vom calcula S(k), ca fiind suma din partea dreapt a inegalitii (2) (suma
dup i de la k+1 la N din min{d(i),k}). Evident, vom compara sd(k) cu k(k-1)+S(k), pentru
fiecare valoare a lui k.
Pentru k=N avem S(N)=0 i cnt[i]=0 (0iN-1). De fiecare dat cnd trecem de la k=x la
k=x-1, obinem S(x-1) ca fiind egal cu S(x)-cnt[x]. Apoi setm cnt[x-1] la cnt[x-1]+cnt[x],
dup care resetm cnt[x] la 0. n felul acesta, am obinut un algoritm cu complexitatea O(N).
Probleme care au la baz secvene grafice au fost propuse la multe concursuri i
olimpiade de informatic (de ex., problema Tennis de la Olimpiada Baltic de Informatic,
2002).
Problema 3-3. Augmentarea unui graf orientat la un graf eulerian
Se d un graf orientat avnd N (1N50.000) noduri i M (0M500.000) muchii. Graful
poate conine mai multe muchii de la acelai nod ctre acelai alt nod, avnd acelai sens
(muchii paralele). Adugai un numr minim de muchii orientate acestui graf, astfel nct
graful obinut s conin un ciclu (drum) eulerian.
Soluie: Vom calcula, pentru fiecare nod i (1iN), valorile degin(i) i degout(i),
reprezentnd gradul de intrare (numrul de muchii care intr n nodul i), respectiv gradul de
ieire (numrul de muchii care ies din nodul i).
Apoi vom asocia fiecrui nod i valoarea def(i)=degout(i)-degin(i).
Apoi vom ignora sensul muchiilor grafului i vom mpri graful n componente conexe:
fie Q numrul de componente conexe ale sale. Dintre cele Q componente conexe ale sale, fie
F numrul de componente conexe pentru care toate nodurile i din component au def(i)=0.
Fiecare din celelalte Q-F componente conine cel puin un nod i cu def(i)>0 i un nod j cu
def(j)<0.
Vom ordona componentele ntr-o ordine oarecare i le vom numerota de la 1 la Q. Din
fiecare component i vom alege un nod in(i) cu def(i)>0 i un nod out(i) cu def(i)<0 (dac
toate nodurile j din component au def(j)=0 atunci vom alege un nod k oarecare din
component i vom seta in(i)=out(i)=k).
n continuare vom aduga muchiile orientate (out(i)->in(i+1)) (1iQ-1), precum i
muchia orientat (out(Q)->in(1)). Dup adugarea acestor muchii (i actualizarea valorilor
degin(j), degout(j) i def(j) ale nodurilor adiacente cu muchiile adugate; mai exact, pentru
fiecare muchie (a->b) adugat incrementm degout(a), degin(b) i def(a) cu 1, respectiv
decrementm def(b) cu 1), vom considera S1 mulimea nodurilor i cu def(i)<0 i S2 mulimea
nodurilor i cu def(i)>0.
Vom nota prin Sj(k) al k-lea nod din mulimea Sj (k1) i prin |Sj| numrul de elemente
din Sj.
Vom iniializa dou contoare p1=p2=1. Ct timp p1|S1| i p2|S2|:
1) adugm muchia (S1(p1)->S2(p2));

39

2) incrementm degout(S1(p1)), degin(S2(p2)) i def(S1(p1)) cu 1;


3) vom decrementa def(S2(p2)) cu 1;
4) dac def(S1(p1))=0 atunci p1=p1+1;
5) dac def(S2(p2))=0 atunci p2=p2+1.
Numrul de muchii adugate este egal cu V+F, unde V este suma valorilor iniiale def(i),
pentru acele noduri i cu def(i)>0.
Problema 3-4. Gangsteri (Olimpiada Baltic de Informatic, 2003, enun modificat)
ntr-un ora exist N (1N10.000) gangsteri, organizai n grupe de prieteni. Se cunosc
M (0M500.000) relaii ntre M perechi de gangsteri, de forma:
1) gangsterii i i j sunt prieteni sau
2) gangsterii i i j sunt dumani (1jN).
Se tie c gangsterii au urmtorul cod de etic:
1) Prietenul prietenului meu mi este prieten.
2) Dumanul dumanului meu mi este prieten.
Pe baza celor M relaii date, determinai care este numrul maxim de grupe de prieteni ce
pot exista.
Exemplu:
N=6, M=4
Rspuns: 3
1 i 4 sunt dumani.
Cele 3 grupe de prieteni sunt: {1}, {2,4,6},
3 i 5 sunt prieteni.
{3,5}.
4 i 6 sunt prieteni.
1 i 2 sunt dumani.
Soluie: Vom construi un graf GF n care fiecare nod corespunde unui gangster. Vom
introduce n acest graf muchie ntre doi gangsteri i i j dac se tie c acetia sunt prieteni
(ori sunt prieteni direct, ori au un duman comun). Problema cere determinarea numrului de
componente conexe din graful GF.
Introducerea muchiilor (i,j) pentru relaiile de prietenie este simpl. Pentru relaiile de
dumnie, vom construi un al doilea graf, GE, n care introducem muchie ntre dou noduri i
i j dac tim c cei doi sunt dumani. Apoi, pentru fiecare nod i, vom construi o list cu toi
vecinii lui i n GE, lv(i). Oricare dou noduri din lv(i) reprezint doi gangsteri care sunt
prieteni (deoarece au un duman comun), astfel c am putea introduce o muchie (a,b) ntre
oricare dou noduri a i b din lv(i). Dac implementm algoritmul n felul acesta, putem
ajunge la o complexitate prea mare. S observm c obinem acelai efect i n felul urmtor.
Alegem un nod a din lv(i) i adugm muchie n GF ntre a i orice nod ba din lv(i).
n cazul n care ar fi necesar i verificarea corectitudinii datelor, va trebui doar s
verificm c oricare dou noduri i i j ntre care exist muchie n GE nu sunt n aceeai
component conex n GF.
Problema 3-5. mprirea ptrelelor
Se d o matrice cu NxN ptrele. Fiecare ptrel este colorat n alb (0) sau n negru (1).
Fie Q numrul de ptrele negre. Determinai dac este posibil s mprim ptrelele negre
n dou mulimi disjuncte, egale, A i B, astfel nct mulimea A s poate fi obinut din
mulimea B prin translaii i rotaii cu multipli de 90o.

40

Soluie: Vom considera toate posibilitile (tl, tc) de translaii pe linii i coloane (-Ntl,tcN).
Pentru o pereche (tl,tc) fixat, vom ncerca toate cele 4 posibiliti de rotaii r (cu 0o, 90o,
180o i 270o).
Pentru fiecare tuplu (tl, tc, r), vom parcurge toate cele Q ptrele negre i vom determina
succesorul fiecruia. Succesorul unui ptrel de pe linia (i,j) se calculeaz n felul
urmtor: rotim ptrelul (i,j) conform rotaiei r i obinem un ptrel (i,j). De exemplu,
pentru rotaia cu 90o: i=N-j+1 i j=i. Apoi translatm coordonatele (i,j) cu (tl,tc),
obinnd coordonatele (i=i+tl, j=j+tc). Dac ptrelul (i,j) se afl n matrice (adic
1i, jN) i este de culoare neagr, setm succesorul lui (i,j) la (i,j); altfel, (i,j) nu va
avea succesor.
Astfel, am obinut un graf orientat, n care fiecare nod are gradul de ieire 0 sau 1
(muchia orientat de la nod la succesorul acestuia). Acest graf este compus din cicluri sau
din drumuri. Dac numrul de noduri de pe fiecare ciclu este par i numrul de noduri de pe
fiecare drum este par, atunci am gsit o soluie la problema noastr. n acest caz, mulimea A
se obine lund nodurile din 2 n 2 de pe fiecare drum sau ciclu, iar mulimea B se obine din
nodurile celelalte. Este clar c mulimea B se poate roti i translata peste mulimea A.
Aadar, problema admite soluie dac gsim un tuplu (tl, tc, r) pentru care graful construit
are numai cicluri i drumuri cu numr par de noduri. Complexitatea algoritmului este O(N4).
Problema 3-6. Split Graphs
Un graf neorientat cu N (1N1.000) noduri i M (0MN(N-1)/2) muchii se numete
split graph, dac nodurile sale pot fi mprite n 2 submulimi C i I (eventual vide), astfel
nct:
(1) pentru oricare dou noduri x i y din C exist o muchie (x,y) n graf;
(2) pentru oricare dou noduri x i y din I, muchia (x,y) nu exist n graf.
Mai exact, nodurile din C formeaz o clic (subgtaf complet), iar nodurile din I formeaz
o mulime independent (sau intern stabil). Determinai (dac exist) o mprire a nodurilor
n cele dou mulimi C i I (evident, fiecare nod trebuie s fac parte din una din cele dou
mulimi).
Soluie: Vom asociat fiecrui nod i (1iN) o variabil x(i), ce va indica mulimea din care
face parte nodul (dac x(i)=1, atunci nodul i face parte din mulimea C; dac x(i)=0, atunci
nodul i face parte din mulimea I).
S considerm un nod s oarecare din graf. Vom considera dou cazuri. n primul caz,
vom alege x(s)=1, iar n al doilea caz vom alege x(s)=0. n fiecare caz vom introduce nodul s
ntr-o coad Q. Valorile x(is) vor avea o valoare special, reprezentnd faptul c nu au fost
iniializate.
Apoi, ct timp Q nu este vid, vom extrage nodul a din vrful cozii. Dac x(a)=1, atunci
vom considera toate nodurile b pentru care nu exist muchia (a,b) n graf: dac x(b) este
neiniializat, setm x(b)=0 (nodul b nu poate face parte din mulimea C) i introducem nodul
b n coad; dac x(b) este iniializat i este diferit de 0, atunci nu vom avea soluie n acest
caz (valoarea iniial x(s) nu a fost ghicit corect), iar dac x(b)=0, atunci nu ntreprindem
nicio aciune. Dac x(a)=0, atunci vom considera toate nodurile b pentru care muchia (a,b)
exist n graf: dac x(b) este neiniializat, atunci setm x(b)=1 (nodul b nu poate face parte
din mulimea I) i introducem nodul b n Q; dac x(b) este iniializat i diferit de 1, atunci nu
avem soluie pentru acest caz, iar dac x(b)=1, atunci mergem mai departe.

41

La finalul execuiei acestui pas, dac nu s-a gsit nicio contradicie, avem urmtoarea
situaie. Unele noduri i au variabila x(i) setat la 1 sau 0, iar altele o pot avea nc
neiniializat. Nodurile j cu x(j) nc neiniializat sunt adiacente cu toate nodurile i cu x(i)=1
i nu sunt adiacente cu niciun nod k cu x(k)=0. Aadar, valorile variabilelor lor (x(j)) pot fi
alese independent de valorile variabilelor deja setate. Prin urmare, vom considera un graf
redus ce const doar din nodurile cu variabiele x(i) neiniializate. Din acest graf vom alege
un nod oarecare s i vom considera, ca i prima dat, dou cazuri (x(s)=0 i x(s)=1),
propagnd restriciile mai departe. Vom relua execuia algoritmului descris atta timp ct mai
exist variabile x(j) neiniializate.
Dac reuim s ajungem la final fr nicio contradicie, atunci valorile x(i) indic
apartenena nodurilor la cele dou mulimi. Complexitatea algoritmului este O(N2). Fiecare
nod este introdus o singur dat n coad i pentru fiecare nod extras din coad se consider
O(N) alte noduri.
Problema 3-7. Baz de cicluri a unui graf
Se d un graf neorientat (nu neaprat conex) avnd N noduri (1N30.000) i M muchii
(0Mmin{200.000, N(N-1)/2}). Determinai o mulime Q coninnd un numr maxim de
cicluri simple din acest graf, astfel nct fiecare ciclu s conin cel puin o muchie care nu
apare n niciun alt ciclu din Q. Ne intereseaz doar numrul de elemente din Q, nu i ciclurile
propriu-zise.
Soluie: Pentru fiecare component conex vom determina un arbore DFS al acesteia. S
presupunem c componenta i (1incc; ncc=numrul de componente conexe ale grafului)
conine nn(i) noduri i mm(i) muchii. n arborele DFS se gsesc nn(i)-1 muchii. Dac
adugm fiecare din celelalte (mm(i)-nn(i)+1) muchii la arborele DFS al componentei
conexe i, acestea vor nchide cte un ciclu n arbore (format din muchia adugat (a,b) i
drumul unic dintre nodurile a i b din arbore). Mulimea Q este format din ciclurile nchise
de fiecare muchie (a,b) n arborele DFS al componentei sale (muchia (a,b) se afl n afara
arborelui DFS al componentei sale).
Se observ uor c fiecare astfel de ciclu corespunztor unei muchii (a,b) are drept
muchie unic (care nu apare n alte cicluri) chiar pe muchia (a,b). Astfel, numrul total de
cicluri din Q este suma valorilor (mm(i)-nn(i)+1) (1incc). Cum suma valorilor mm(i) este
M i suma valorilor nn(i) este N (1incc), rezultatul este: M-N+ncc.
Aadar, trebuie doar s determinm numrul de componente conexe din graful dat. Putem
realiza acest lucru n modul standard. Reinem ntreg graful n memorie, apoi efectum
parcurgeri DFS sau BFS din cte un nod nevizitat, marcnd ca vizitate toate nodurile
parcurse. Totui, dac numrul de muchii este prea mare pentru ca graful s fie meninut
complet n memorie, putem proceda dup cum urmeaz. Vom menine o structur de mulimi
disjuncte. Iniial, fiecare nod x este o mulime separat. Pe msur ce citim cte o muchie
(a,b), unim mulimile n care se afl nodurile a i b. Numrul de mulimi obinute la final
este chiar numrul de componente conexe. Folosind o implementare arborescent a
mulimilor disjuncte [CLRS], complexitatea acestei soluii este O(Mlog*(N)). Vom iniializa
numrul de componente conexe ncc la N. La fiecare muchie (a,b) determinm nti dac a i
b sunt n aceeai mulime sau nu. Dac nu sunt n aceeai mulime, doar atunci efectum
unirea celor dou mulimi i decrementm ncc cu 1.

42

Problema 3-8. Muchii Eseniale (Olimpiada de Informatic a Europei Centrale, 2005)


Se d un graf neorientat conex avnd N noduri (1N30.000) i M muchii
(0Mmin{200.000, N(N-1)/2}). Unele noduri ofer servicii de tipul A, iar altele de tipul B
(pentru fiecare nod se tie ce fel de servicii ofer; este posibil ca un nod s ofere ambele
tipuri de servicii).
O muchie se numete esenial dac prin eliminarea ei din graf exist cel puin un nod
care nu mai are acces (cale direct) ctre niciun nod care ofer un serviciu de tipul A sau de
tipul B.
Determinai muchiile eseniale ale grafului.
Soluie: Vom aplica nti algoritmul clasic de determinare a muchiilor critice, bazat pe o
parcurgere DFS a grafului. O muchie esenial trebuie neaprat s fie i o muchie critic.
Muchiile critice sunt muchii ce fac parte din arborele DFS obinut n urma parcurgerii. Mai
rmne s determinm care dintre muchiile critice sunt i eseniale.
Vom calcula pentru fiecare nod i din arborele DFS numerele nA(i) i nB(i), reprezentnd
numrul de noduri ce ofer servicii de tipul A, respectiv B, din subarborele nodului i (aceste
valori se calculeaz ca sume ale valorilor corespunztoare din fiii lui i, la care, eventual, se
adaug 1, dac nodul i ofer servicii de tipul respectiv).
Fie NTA i NTB numrul total de noduri ce ofer servicii de tipul A, respectiv B. O
muchie critic (x,y) (cu x printele lui y n arborele DFS) este esenial dac:
(1) nA(x)=NTA; sau (2) nA(x)=0; sau (3) nB(x)=NTB; sau (4) nB(x)=0.
Complexitatea algoritmului este O(N+M).
Problema 3-9. Depozit (Olimpiada de Informatic a Europei Centrale, 2005)
ntr-un depozit se afl aezate n linie NM produse. Produsele sunt de tipurile 1, 2, ..., M
i exist N produse din fiecare tip. Dorim s ordonm produsele, astfel nct n orice interval
de poziii [(i-1)M+1, iM] (1iN) s existe cte un produs din fiecare tip (altfel spus, pe
primele M poziii s se afle M produse distincte ntre ele, pe urmtoarele M poziii s se afle
tot M produse distincte ntre ele .a.m.d.).
Depozitul are i o poziie liber, localizat (iniial) la sfritul celor NM produse (deci, pe
poziia NM+1). Pentru ordonarea produselor putem efectua doar urmtorul tip de mutri:
lum un produs de pe o poziie i i l mutm pe poziia liber; evident, dup efectuarea
mutrii, poziia i devine noua poziie liber. La final, poziia liber trebuie s fie, ca i la
nceput, poziia NM+1. n plus, numrul total de mutri efectuate trebuie s fie minim.
Soluie: Vom construi un graf bipartit orientat ce conine vrfurile p(1), ..., p(N) n partea
stng i vrfurile q(1), ..., q(N) n partea dreapt. ntre 2 vrfuri p(i) i q(j) exist k muchii
orientate de la p(i) la q(j), dac produsul j apare de k+1 ori n intervalul de poziii [(i-1)M+1,
iM]. De asemenea, exist muchie orientat de la q(j) la p(i) dac produsul j nu apare
niciodat n intervalul [(i-1)M+1, iM].
Pentru fiecare nod x al grafului, numrul de muchii care intr n x este egal cu numrul de
muchii care ies din x. Astfel, fiecare component (conex) a grafului conine un ciclu
eulerian. S presupunem c am determinat un astfel de ciclu pentru o component. Alegem
prima muchie ca fiind de tipul (p(a),q(b)) i mutm unul din produsele de tipul b din
intervalul [(a-1)M+1, aM] n poziia liber NM+1. Vom parcurge ciclul n sens invers
(ncepnd de la muchia dinaintea primei muchii). Pentru fiecare dou muchii consecutive de
pe ciclu (n sens invers) (q(j), p(i)) i (p(k), q(j)), vom muta unul din produsele de tipul j din

43

intervalul [(k-1)M+1, kM] pe poziia liber (care se afl n intervalul [(i-1)M+1, iM]);
dup aceasta, noua poziie liber se va afla undeva n intervalul [(k-1)M+1, kM].
La final, vom mai avea de tratat perechea de muchii consecutive (p(a),q(b)) (muchia
iniial) i (q(b), p(c)). Vom muta produsul de pe poziia NM+1 pe poziia liber, care se
afl undeva n intervalul [(c-1)M+1, cM].
Numrul de mutri efectuate este minim i este egal cu ncc + suma gradelor de ieire ale
nodurilor p(*) (ncc=numrul de componente conexe ale grafului; o component conex se
calculeaz ignornd direcia muchiilor). Complexitatea algoritmului este O(NM).
Problema 3-10. Cereri (Olimpiada de Informatic a Europei Centrale 2008)
Se dau N (1N200) cereri de procesare. Fiecare cerere i (1iN) adduce un venit V(i)
(dac este acceptat), iar pentru procesarea ei are nevoie de alocarea calculatoarelor din
mulimea C(i) (C(i) este o submulime a mulimii {1,...,M}, unde 1M200 este numrul
total de calculatoare disponibile). Pentru a folosi un calculator i pentru cererile care au
nevoie de el, avem dou opiuni:
1) putem cumpra calculatorul i, la preul P(i);
2) putem nchiria calculatorul i pentru fiecare cerere j acceptat pentru care i face parte
din S(j), la preul R(j,i).
Cererile pot fi acceptate sau rejectate. Dac sunt acceptate, atunci calculatoarele cerute
trebuie alocate. Dac un calculator i este cumprat, atunci el poate fi folosit pentru toate
cererile care au nevoie de el (nu trebuie nchiriat niciodat); dac un calculator i nu este
nchiriat, atunci trebuie pltit preul R(j,i) pentru fiecare cerere j acceptat care are nevoie de
calculatorul i.
Determinai profitul maxim ce poate fi obinut (profit=venituri totale costuri totale),
valorile tuturor veniturilor i costurilor sunt distincte.
Soluie: Vom construi urmtorul graf bipartit. n partea stng se afl cte un nod x(i) ce
corespunde fiecrei cereri i; n partea dreapt se afl cte un nod y(j) ce corespunde fiecrui
calculator j. Avem o muchie orientat de la x(i) la y(j), dac j face parte din S(i). Mai
adugm o surs Sr, care are muchii orientate de la ea ctre fiecare nod x(i) i o destinaie
virtual De, pentru care exist muchii de la fiecare nod y(j) la De. Fiecare muchie a grafului
are o anumit capacitate. Fiecare muchie (Sr, x(i)) are capacitatea V(i); fiecare muchie (x(i),
y(j)) are capacitatea R(i,j); fiecare muchie (y(j), De) are capacitatea P(j).
Vom determina un flux maxim n aceast reea de flux. Vom nota prin F(a,b) valoarea
fluxului pe o muchie (a,b) a grafului. Dac o muchie (Sr,x(i)) are F(Sr,x(i))=V(i), atunci vom
rejecta cererea i; altfel, o vom accepta. Dac o muchie (y(j),De) are F(y(j),De)=P(j), atunci
vom cumpra calculatorul j. Pentru fiecare cerere i acceptat i fiecare calculator j din S(i),
dac j nu a fost cumprat, atunci el va fi nchiriat pentru cererea i, pltind preul R(i,j). n
felul acesta, veniturile i cheltuielile au fost determinate i profitul poate fi calculat imediat.
Problema 3-11. Paintball (Lotul Naional de Informatic, Romnia 2008)
Se d un graf cu N (1N100.000) noduri. Din fiecare nod u iese exact o muchie, care
este ndreptat ctre un alt nod v (deci fiecare nod al grafului are gradul de ieire 1). S
considerm o permutare P a nodurilor grafului: P(1), ..., P(N). Considernd ordinea din
permutare, fiecare nod u trage ctre nodul v ctre care este ndreptat muchia de ieire din u
i l omoar. Un nod u trage atunci cnd i vine rndul doar dac nu a fost omort de alt nod
n prealabil i dac nodul v ctre care vrea s trag nu este deja mort.

44

n mod evident, numrul de noduri moarte variaz n funcie de permutarea aleas.


Determinai care este numrul maxim i numrul minim de mori (dac alegem
corespunztor permutarea nodurilor).
Soluie: Pentru a determina numrul minim de mori vom proceda dup cum urmeaz. Vom
menine un contor ndead (iniial 0) i o coad n care introducem iniial doar nodurilr care au
gradul interior 0. Pe rnd, vom extrage din coad un nod u i vom determina nodul v ctre
care este ndreptat muchia care iese din u. Dac v nu e mort, atunci u trage ctre v i l
omoar: incrementm ndead cu 1 i eliminm din graf att nodul u, ct i nodul v => asta
nseamn c decrementm cu 1 gradul de intrare al nodului w ctre care era ndreptat
muchia care ieea din v; dac gradul de intrare al lui w devine 0 (i w nu e deja mort), atunci
l introducem pe w n coad. Dup aceast prim etap, n graf au mai rmas, eventual, doar
cicluri. Pentru fiecare ciclu de lungime L putem alege orice nod s trag primul. Dup
aceasta, ciclul s-a transformat ntr-un lan cu L-1 noduri, din care vor rezulta (L-1) div 2
mori. Astfel, pentru un ciclu de lungime L numrul minim de mori este ((L+1) div 2);
incrementm ndead cu aceast valoare pentru fiecare ciclu. La final, ndead va conine
numrul minim de mori.
Pentru a determina numrul maxim de mori vom iniializa contorul ndead cu 0 i apoi
vom considera, pe rnd, fiecare nod u cu grad de intrare 0. Vom determina toate nodurile
care pot fi atinse din nodul u, mergnd n sensul muchiilor (facem o parcurgere BFS sau DFS
din u, fr a trece prin noduri vizitate n cadrul altor pacurgeri anterioare). Aceste noduri
formeaz un lan, n care ultimul nod are o muchie ndreptat ctre un nod din lan situat
naintea sa (sau ctre un nod vizitat ntr-o parcurgere anterioar). Dac lanul conine L
noduri, atunci putem obine L-1 mori (trage nti penultimul nod, apoi antepenultimul,
.a.m.d.; singurul care nu omoar pe nimeni este ultimul nod din lan i singurul care nu
moare este primul nod din lan); incrementm ndead cu L-1.
Dup acest pas, n graf au mai rmas, eventual, cicluri. Pentru fiecare ciclu de lungime L,
numrul maxim de mori este L-1. Alegem orice nod s trag la nceput, dup care rmnem
cu un lan de lungime L-1, din care, dup cum am vzut, putem obine L-2 mori;
incrementm ndead cu L-1 pentru fiecare ciclu (a crui lungime este L). Numrul maxim de
mori este coninut n contorul ndead.
Problema 3-12. Orientarea muchiilor unui graf planar (CPSPC 2007)
Se d un graf planar cu N (1N10.000) noduri i M muchii. Dorim s atribuim o
orientare fiecrei muchii (u,v) a grafului (u->v sau v->u), astfel nct din fiecare nod s ias
cel mult 3 muchii.
Soluie: Vom ncepe cu o orientare oarecare a muchiilor grafului. Apoi vom parcurge
nodurile grafului. De fiecare dat cnd gsim un nod i care are mai mult de 3 muchii care ies
din el, efectum urmtoarele aciuni: ct timp nodul i are mai mult de 3 muchii de ieire,
efectum o parcurgere BFS din nodul i. Pentru aceasta, vom folosi o coad n care, iniial,
introducem nodul i. Parcurgem nodurile din coad i, dac nodul u din vrful cozii are cel
puin 3 muchii de ieire, introducem n coad toi vecinii si v ctre care exist muchia u->v
(dac nu au fost deja vizitai). Dac are mai puin de 3 muchii de ieire, l introducem ntr-o
mulime special Q (i nu introducem n coad vecinii si v ctre care existau muchii
orientate de la u).

45

Din parcurgerea efectuat am obinut un arbore BFS. Eliminm, pe rnd, din acest arbore,
acele frunze care au 3 sau mai multe muchii de ieire n graf. Astfel, rmnem cu un arbore
n care toate frunzele au 0, 1 sau 2 muchii de ieire n graf. Vom inversa sensul tuturor
muchiilor din arbore (de la tat->fiu, inversm sensul la fiu->tat). Numrul muchiilor de
ieire n graf ale frunzelor crete cu 1, iar numrul muchiilor de ieire ale nodurilor interne
scade sau rmne constant. Numrul muchiilor de ieire din rdcin (nodul i de la care am
nceput parcurgerea) scade.
Vom repeta parcurgerea dac nodul i are, n continuare, mai mult de 3 muchii de ieire.
Algoritmul va gsi de fiecare dat o soluie, deoarece un graf planar are cel mult 3N-6
muchii i, deci, permite existena unei orientri a muchiilor cu proprietatea specificat. Mai
exact, algoritmul ar putea s nu funcioneze doar dac, la un moment dat, se elimin toate
nodurile din arborele BFS (adic toate nodurile din graf care pot fi vizitate din nodul i au cel
puin 3 muchii de ieire). ntruct o muchie de ieire pentru un nod este o muchie de intrare
pentru un alt nod, ar trebui ca ntre cele M noduri ce pot fi atinse din nodul i (inclusiv nodul
i) s existe cel puin 3M muchii (plus 1, cci nodul i are cel puin 4 muchii de ieire), numr
care depete limita maxim de 3M-6.
Complexitatea algoritmului este O(N2) n cel mai ru caz, ns, n practic, merge mult
mai bine.
Problema 3-13. Link (Olimpiada de Informatic a Europei Centrale, 2006)
Se d un graf orientat cu N (2N500.000) noduri. Din fiecare nod u iese exact o singur
muchie, care l unete de alt nod v (este posibil ca u=v); evident, muchia este orientat de la
u la v (o vom nota prin (u,v)). Nodul 1 este un nod special. Dorim s adugm un numr
minim de muchii grafului, astfel nct lungimea minim a unui drum orientat de la nodul 1
ctre orice alt nod s fie cel mult K (1K20.000). Un drum orientat de la u la v pornete din
u i continu pe una din muchiile care ies din u, .a.m.d., pn ajunge n nodul v. Lungimea
unui drum este egal nu numrul de muchii de pe drum.
Soluie: n prima faz a algoritmului vom marca ca fiind acoperite cele (maxim) K noduri
care sunt la distan cel mult K de nodul 1, inclusiv nodul 1 (vom urma maxim K muchii de
ieire, pornind din nodul 1; ntruct fiecare nod are exact o singur muchie de ieire, acest
pas are complexitatea O(K)). Toate celelalte noduri vor fi marcate ca fiind neacoperite. S
considerm acum componentele conexe ale grafului, ignornd sensul muchiilor. Fiecare
astfel de component conine un ciclu n interiorul su i nite arbori ale cror rdcini sunt
nodurile de pe ciclu. Arborii respectivi au muchiile orientate de la fiu ctre printe.
n prima etap vom trata nodurile care sunt n interiorul arborilor ataai nodurilor din
ciclul fiecrei componente. Vom menine o valoare degin[u] pentru fiecare nod u,
reprezentnd cte muchii (v,u) exist n graf (practic, gradul de intrare al nodului u). Vom
introduce ntr-o coad Q toate nodurile u neacoperite, pentru care degin[u]=0.
Fiecrui nod u introdus n Q i vom asocia o distan dist[u], reprezentnd distana de la
nodul 1 la acest nod. Pentru nodurile u neacoperite care au iniial degin[u]=0 vom introduce
muchiile (1,u) n graf i vom seta dist[u]=1; apoi le vom marca ca fiind acoperite. Pentru
toate nodurile v marcate ca fiind acoperite pn acum, vom seta dist[v]=lungimea drumului
orientat de la nodul 1 la nodul v (dist[1]=0).
Vom extrage apoi, pe rnd, nodurile din Q, pn cnd Q devine goal. S presupunem c
am extras un nod u. Fie next(u) nodul ctre care se ndreapt muchia care iese din u (muchia
orientat (u,next(u)) exist n graf). Dac dist[u]<K i ((next(u) este neacoperit) sau

46

(dist[next(u)]>dist[u]+1)), atunci vom seta dist[next(u)]=dist(u)+1 i l vom marca pe


next(u) ca fiind acoperit (vom considera c, iniial, pentru fiecare nod v neacoperit avem
dist[v]=+). Apoi vom decrementa degin[next(u)]. Dac degin[next(u)]=0, atunci: dac
next(u) este nc neacoperit, atunci vom introduce o muchie suplimentar orientat
(1,next(u)) i vom seta dist[next(u)]=1; apoi vom introduce nodul next(u) n Q.
Observm c n cadrul acestei etape au fost acoperite toate nodurile care nu aparin
ciclului din componenta proprie (precum i, eventual, rdcinile arborilor ataati ciclului din
fiecare component; aceste rdcini sunt, dup cum am spus anterior, noduri din cadrul
ciclului).
Vom considera acum fiecare ciclu n parte din cadrul fiecrei componente. Fie acest ciclu
format din nodurile v(1), ..., v(P) (P1). Unele din nodurile v(i) de pe ciclu pot fi acoperite i
au deja o valoare corect pentru dist[v(i)]. Celelalte noduri v(j) nu sunt acoperite i nu au
setat valoarea dist[v(j)]. Dac niciunul din nodurile de pe ciclu nu este acoperit, atunci vom
alege nodul v(1) i vom introduce muchia suplimentar (1,v(1)) (dup care setm
dist[v(1)]=1 i l marcm pe v(1)) ca fiind acoperit. Astfel, n continuare, vom presupune c
ciclul conine cel puin un nod acoperit.
Vom selecta acel nod acoperit u de pe ciclu pentru care dist[u] este minim dintre toate
celelalte noduri de pe ciclu. Vom numerota nodurile de pe ciclu astfel nct v(1)=u. Vom
parcurge apoi nodurile de pe ciclu n sensul muchiilor de ieire, de la i=2,,P (avem
v(i)=next(v(i-1))). Cnd ajungem la un nod v(i), dac v(i-1) este acoperit i dist[v(i-1)]<K,
atunci:
(1) dac nodul v(i) este neacoperit, setm dist[v(i)]=dist[v(i-1)]+1 i marcm v(i) ca
fiind acoperit;
(2) dac nodul v(i) este acoperit (i v(i-1) este i el acoperit, cu dist[v(i-1)]<K), atunci
setm dist[v(i)]=min{dist[v(i)], dist[v(i-1)]+1}.
Dup aceast parcurgere este posibil s mai fi rmas noduri neacoperite pe ciclu, printre
care se afl unele noduri acoperite. Pentru acoperirea nodurilor neacoperite va trebui s
introducem muchii suplimentare.
Pentru acoperirea nodurilor neacoperite, va trebui s alegem un nod iniial v(j) neacoperit,
de pe ciclu. Vom introduce muchia (1,v(j)), l vom marca pe v(j) ca fiind acoperit, apoi vom
avansa pe ciclu K-1 poziii i vom marca toate nodurile ntlnite i neacoperite nc ca fiind
acoperite; s presupunem c am ajuns la poziia r. Ct timp mai sunt noduri acoperite pe
ciclu (putem menine aceast informaie sub forma unui contor de noduri neacoperite), vom
avansa pe ciclu n continuare (ncepnd de la poziia r), pn la urmtorul nod neacoperit; fie
acest nod v(l); vom introduce muchia suplimentar orientat (1,v(l)), vom seta dist[v(l)]=1 i
l vom marca pe v(l) ca fiind acoperit; apoi vom avansa K-1 poziii pe ciclu ncepnd de la
poziia l i vom marca toate nodurile ntlnite i neacoperite nc ca fiind acoperite; fie r
noua poziie la care am ajuns pe ciclu (refolosim variabila r). Aadar, o dat ce am ales nodul
neacoperit iniial v(j), putem acoperi optim celelalte noduri n timp O(P).
Problema care apare este c numrul de muchii suplimentare introduse depinde de nodul
v(j) ales iniial. Va trebui s alegem acel nod v(j) pentru care se introduce un numr minim
de muchii suplimentare.
O prim variant ar fi s ncercm orice nod neacoperit ca punct de start (am obine o
complexitate O(P2) pe ciclu, i O(N2) n total). O mbuntire const n a ncerca s plecm
doar din nodurile de start neacoperite dintr-un interval de K noduri de pe ciclu (adic gsim
primul nod neacoperit v(j), i apoi considerm doar nodurile v(i) cu jij+K, unde adunarea

47

poziia j+K se calculeaz circular pe ciclu); aceast abordare are o complexitate de O(PK)
pe ciclu i O(NK) per total.
Putem mbunti algoritmul dup cum urmeaz. Vom modifica ciclul n u(0), ..., u(L-1),
pentru a conine doar nodurile neacoperite. Vom avea muchii orientate (u(i), u((i+1) mod L)),
de lungime len(u(i), u((i+1) mod L))=1 + numrul de noduri acoperite aflate ntre nodurile
u(i) i u((i+1) mod L) pe ciclul iniial. Vom considera pe rnd fiecare nod i=0,...,L-1 i vom
menine 2 variabile: D i idx (iniial D=0 i idx=0). Pentru fiecare nod u(i), dac i>0, vom
seta D=D-len(u(i-1+L) mod L, u(i)). Apoi, ct timp D<K i idxi, vom seta:
(1) D=D+len(u(idx), u((idx+1) mod L));
(2) idx=(idx+1) mod L.
La sfritul ciclului vom seta Jump[i]=idx, avnd semnificaia c u(Jump[i]) este primul
nod neacoperit de pe ciclu (mergnd n sensul ciclului ncepnd de la nodul u(i)), ce nu poate
fi acoperit dac se introduce muchia suplimentar (1,u(i)). Jump(u[i]) sare peste K noduri de
pe ciclul iniial (sau mai puin de K, dac nu exist attea noduri pe ciclul iniial).
Astfel, atunci cnd pornim cu un nod de start neacoperit u(j), vom sri direct n
u(Jump[j]), fr a trece prin nodurile dintre cele 2 noduri de pe ciclu; vom continua s srim
din nodul la care am ajuns, u(o), la nodul urmtor u(Jump[o]), pn cnd ajungem napoi n
nodul iniial u(j) (sau pn l depim cu ultima sritur). Numrul de muchii suplimentare
necesare, dac plecm din nodul u(j), va fi egal cu 1 + numrul de srituri 1 (se consider
prima muchie suplimentar (1,u(j)) i se exclude ultima sritur prin care ajungem napoi la
u(j) sau srim peste el). Complexitatea pentru un nod de start u(j) este acum O(P/K). ntruct
pentru fiecare ciclu considerm O(K) noduri de start, complexitatea total este O(P) pentru
fiecare ciclu, i O(N) per total.
Problema 3-14. Ora (infoarena)
Se d un graf neorientat complet cu N noduri (1N10.000) noduri. Determinai o
orientare pentru fiecare din muchiile sale, astfel nct ntre oricare 2 noduri din graf x i y s
existe un drum orientat de la x la y care s conin cel mult 2 muchii.
Soluie: Pentru N=2 i N=4 nu exist soluii. Dac N este impar, pornim de la graful cu
nodurile 1, 2 i 3, n care avem muchiile orientate astfel: 1->2, 2->3, 3->1. Dac N este par,
vom porni de la un graf cu 6 noduri, care respect proprietatea (un astfel de graf este desenat
mai jos):

1
6

3
4

48

S presupunem c avem un graf cu K noduri (numerotate de la 1 la K) care are


proprietatea dorit (i K are aceeai paritate ca N). Ct timp K<N, efectum urmtorii pai.
Adugm muchii orientate de la nodul K+1 la toate nodurile 1,...,K i muchii orientate de la
fiecare din nodurile 1,...,K la nodul K+2. Apoi adugm muchia orientat (K+2)->(K+1).
Observm c avem acum un graf cu K+2 noduri care respect proprietatea cerut; astfel,
vom seta K=K+2. Complexitatea acestui algoritm este liniar n numrul de muchii ale
grafului rezultat (O(N2)).
Problema 3-15. Biomech (Happy Coding 2006, infoarena)
n anul 2006, oamenii au construit primul robot biomecanic cu inteligen artificial. n
orice caz, nc nu se tie prea bine ct de avansat este inteligena sa. Tocmai de aceea,
robotul va fi supus unui test. El va fi plasat ntr-o zon rectangular, mparit n ptrate
amplasate pe 5 linii i un numr infinit de coloane. Coloanele sunt numerotate de la - la +
i robotul este plasat iniial n coloana cu numrul 0. Liniile zonei rectangulare sunt
numerotate de la 1 la 5 i robotul va fi plasat la nceput n linia 3 (cea din mijloc). Robotul va
fi orientat n una din cele 8 direcii posibile: Nord, Nord-Est, Est, Sud-Est, Est, Sud, SudVest, Vest, Nord-Vest.
Mutrile pe care robotul le poate face sunt:
Rotatie cu un unghi multiplu de 45 de grade
Din direcia spre care este ndreptat, robotul se poate ntoarce astfel spre oricare alt
direcie. O rotaie de la o direcie iniial la o direcie final consum o anumit cantitate de
timp. Din cauza structurii interne a robotului, se poate ca o rotaie cu un unghi mai mare s
dureze mai puin dect o rotaie cu un unghi mic. De asemenea, o rotaie din direcia X n
direcia Y s-ar putea s nu dureze la fel de mult ca o rotaie din direcia Y n direcia X.
Micare n direcia spre care este orientat, din ptratul curent n urmtorul patrat
(avnd o muchie comun sau un vrf comun cu acesta)
De exemplu, dac roboelul este la linia 3, coloana X, orientat spre Nord-Est, s-ar putea
deplasa n ptrelul de pe linia 2, coloana X+1. Dup mutare, robotul nu i schimb direcia
n care este orientat. De asemenea, nu i este permis s se mute n afara zonei rectangulare
(aadar, anumite micri sunt interzise din anumite ptrate).
Cantitatea de timp necesar pentru o mutare depinde att de direcia n care se mut (din
cauza cmpului magnetic al Pmntului), ct i de linia pe care robotul se afl n momentul
curent (deoarece fiecare dintre cele 5 rnduri are o structura electromagnetic diferita).
Totui, costurile mutrilor nu depind de coloana n care se afl robotul.
Robotul va fi supus unui test, dup cum urmeaz: i se vor acorda TMAX (0TMAX1015)
uniti de timp. Folosindu-le, va trebui s mute ct mai departe posibil de poziia curent.
Distana nu este msurat n termeni de ptrate, ci n termeni de coloane. Dac dup TMAX
uniti temporale robotul se afl pe coloana X, distana este considerat |X| (valoarea absolut
a lui X). Nu este important linia pe care ajunge.
Robotul va alege direcia n care va fi orientat iniial i cantitatea de timp va ncepe s
scad dup ce ia aceast decizie. Aflai care este distana maxim pe care robotul o poate
parcurge n TMAX uniti de timp.
Soluie: Vom calcula matricea A[lstart][dirstart][lfinish][dirfinish][P], reprezentnd timpul
minim pentru a ajunge de pe linia lstart, o coloan oarecare X i privind n direcia dirstart,
pn pe linia lfinish, coloana X+2P (deci o coloan situat cu 2P poziii mai n dreapta) i
privind n direcia dirfinish. Pentru P=0, vom folosi un algoritm de drum minim. Va trebui s

49

avem grij, cci soluia de timp minim pentru a trece de pe o coloan pe coloana imediat din
dreapta ei poate presupune nite mutri in spate, pe un numr limitat de coloane din stnga.
Alegnd o limit maxim de 9 coloane n stnga i n dreapta, putem folosi algoritmul lui
Dijkstra pe un graf ale crui noduri constau din elementele unei submatrici de 5 linii, 19
coloane i au 8 orientri. Pentru P>0, avem:
A[lstart][dirstart][lfinish][dirfinish][P] = A[lstart][dirstart][lintermed][dirintermed][P-1]
+ A[lintermed] [dirintermed][lfinish][dirfinish][P-1].
Variem linia i orientarea intermediar i pstrm minimul. n mod similar, vom calcula o
matrice B[lstart][dirstart][lfinish][dirfinish][P], unde indicele P va reprezenta sosirea pe o
coloan situat cu 2P coloane la stnga coloanei de start.
Cu aceste matrici calculate, vom determina numrul maxim de coloane pe care le poate
parcurge robotul spre stnga i spre dreapta, n timpul dat, alegnd maximul dintre cele 2
variante. Voi prezenta n continuare doar cazul deplasrii spre dreapta, cel al deplasrii spre
stnga fiind similar. Vom porni de la coloana 0 i vom mri treptat numrul de coloane pe
care le poate parcurge robotul (fie acest numar C). Pentru fiecare valoare a lui C i fiecare
stare posibil (linie,orientare) vom menine timpul minim n care se poate ajunge n starea
respectiv. Iniial, robotul poate ajunge n 0 uniti de timp doar n starea iniial. Vom porni
cu P de la valoarea maxim pentru care am calculat valori (de exemplu, aceast valoare
poate fi 61) i l vom decrementa treptat. Presupunnd c am ajuns pn la coloana C, vom
ncerca acum s parcurgem nc 2P coloane. Folosind matricea A i cunoscnd timpul minim
pentru a ajunge la coloana C n fiecare stare posibil S1, vom calcula timpul minim pentru a
ajunge la coloana C+2P, pentru fiecare stare S2. Dac cel puin o stare S2 are acest moment de
timp mai mic sau egal cu durata de timp maxim dat, atunci mrim valoarea lui C cu 2P i
vom considera momentele de timp actualizate pentru noua valoare a lui C. Dac pentru nicio
stare nu se poate ajunge la coloana C+2P n timp util, atunci lsm valoarea lui C
nemodificat, nefcnd nimic altceva (la urmtorul pas avnd, ns, o valoare a lui P cu 1
mai mic). Valoarea final a lui C este numrul maxim de coloane ce poate fi parcurs spre
dreapta in timpul dat.
Problema 3-16. Mutarea bilelor
Se d un graf cu N (1N200) noduri. Fiecare nod i (1iN) conine b(i)0 bile. Putem s
efectum mutri conform crora lum o bil dintr-un nod i i o mutm ntr-un vecin j al
acestuia; costul unei astfel de mutri este c(i,j) (c(i,j) poate fi diferit de c(j,i)). Determinai
costul total minim al mutrilor ce trebuie efectuate pentru ca, la final, fiecare nod i s conin
exact q(i) bile (suma valorilor b(i) este egal cu suma valorilor q(i)).
Soluie: Vom calcula distanele minime (ca numr de muchii) dintre oricare 2 noduri din graf.
Fie d(i,j) distana minim dintre nodurile i i j. Vom construi un graf bipartit, dup cum
urmeaz. n partea stng vom plasa nodurile i care au b(i)>q(i), iar n partea dreapt
nodurile j care au b(j)<q(j). Vom duce muchii orientate de capacitate + i cost d(i,j) de la
fiecare nod i din partea stng la fiecare nod j din partea dreapt. Apoi vom aduga o surs
virtual S, mpreun cu muchiile orientate de la S la fiecare nod i din partea stng; fiecare
astfel de muchie va avea cost 0 i capacitate egal cu b(i)-q(i). Vom aduga i o destinaie
virtual T, mpreun cu muchiile orientate de la fiecare nod j din partea dreapt la nodul T;
fiecare astfel de muchie va avea cost 0 i capacitate q(j)-b(j). Vom calcula un flux maxim de
cost minim de la S la T n graful astfel construit. Costul minim al acestui flux va reprezenta

50

numrul minim de mutri ce trebuie efectuate pentru ca fiecare nod i s ajung, la final, s
conin exact q(i) bile.
Problema poate fi generalizat dup cum urmeaz: la final, fiecare nod i trebuie s
conin cel puin low(i) i cel mult high(i) bile. Acest caz poate fi rezolvat n mod similar.
Construim un graf bipartit similar, n care n partea stng punem toate nodurile i care au
b(i)>low(i), iar n partea dreapt toate nodurile j care au b(j)<low(j). Ducem din nou muchii
orientate de capacitate + i cost d(i,j) ntre fiecare nod i din partea stng i fiecare nod j
din partea dreapt. Apoi introducem sursa virtual S i destinaia virtual T. Ducem muchii
de la S la fiecare nod i din partea stng; fiecare astfel de muchie va avea cost 0, capacitate
superioar egal cu b(i)-low(i) i o capacitate inferioar egal cu max{0, b(i)-high(i)}. Ducem
i muchii orientate de la fiecare nod j din partea dreapt la destinaia virtual T; fiecare astfel
de muchie va avea cost 0 i capacitate superioar egal cu high(j)-b(j) i capacitatea
inferioar egal cu low(j)-b(j). Vom gsi un flux fezabil (care respect constrngerile de
capaciti inferioare i superioare) de la S la T n acest graf, al crui cost s fie minim. Pentru
aceasta, vom efectua transformarea standard pentru a calcula un flux fezabil cu capaciti
inferioare i superioare, care are la baz modificarea grafului i reducerea la o problem de
flux maxim [CLRS]; pstrnd aceleai costuri pe muchii, n aceast etap vom calcula un
flux maxim de cost minim (n loc de un flux maxim simplu).
Problema 3-17. Augmentarea unui arbore
Se d un arbore cu N (1N100.000) noduri. Adugai un numr minim de muchii la
arbore, astfel nct, la finalm fiecare nod s fac parte din exact un ciclu. Considerm dou
cazuri:
(a) se pot dubla muchiile arborelui (adic se pot aduga muchii identice cu muchiile
arborelui) i
(b) nu se pot dubla muchiile arborelui.
Soluie: Vom alege o rdcin r a arborelui, definind astfel relaii tat-fiu. Apoi vom calcula,
pentru fiecare nod i, urmtoarele valori:
CA(i)=numrul minim de muchii necesare pentru ca ntreg subarborele nodului i s
fie satisfcut (adic fiecare nod din subarborele nodului face parte din exact un ciclu,
fr a considera noduri din afara subarborelui)
CB(i)=numrul minim de muchii necesare pentru ca ntreg subarborele nodului i s
fie satisfcut, mai puin nodul i
CC(i)=numrul minim de muchii necesare pentru ca ntreg subarborele nodului i s
fie satisfcut, mai puin un lan care ncepe la nodul i i coboar n jos n
subarborele acestuia pn la un nod diferit de i (nu neaprat pn la o frunz)
Vom calcula aceste valori pornind de la frunze spre rdcin. Pentru o frunz i avem
urmtoarele: CA(i)=+, CB(i)=0, CC(i)=+. Pentru un nod i care nu este frunz, fie fiii
acestuia: f(i,1), ..., f(i,nfii(i)). Avem:
CB(i)=suma valorilor CA(f(i,j)) (1jnfii(i))
CC(i)=CB(i)+min{min{CB(f(i,j), CC(f(i,j))} CA(f(i,j))} | 1jnfii(i)}
Pentru a calcula CA(i) vom proceda dup cum urmeaz. Calculm mai nti valoarea
CA(i)=1+CC(i) (pentru cazul (a)) sau CA(i)=1+CB(i)+min{CC(f(i,j)) CA(f(i,j)) |
1jnfii(i)} (pentru cazul (b)).
Apoi, dac nfii(i)2, vom asocia fiecrui fiu f(i,j) o valoare CF(f(i,j))=min{CB(f(i,j),
CC(f(i,j))}-CA(f(i,j)). Vom selecta (n timp O(nfii(i))) cei doi fii f(i,a) i f(i,b) (ab) pentru

51

care valorile asociate CF(f(i,a)) i CF(f(i,b)) sunt cele mai mici dou valori dintre valorile
tuturor fiilor. Calculm apoi CA(i)=1+CB(i)+CF(f(i,a))+CF(f(i,b)) (sau, dac nfii(i)=1,
CA(i)=+).
Vom avea CA(i)=min{CA(i), CA(i)}.
Rspunsul este CA(r). Complexitatea ntregului algoritm este O(N).

52

Capitolul 4. Structuri de Date.


Problema 4-1. Arbore Cartezian (ACM ICPC NEERC, Northern, 2002)
Se dau N (1N100.000) puncte n plan; punctul i (1iN) are coordonatele (xi,yi). Un
arbore cartezian al celor N puncte are proprietatea de arbore binar de cutare pentru
coordonata x i de min-heap pentru coordonata y. Mai exact, fie Q un nod al arborelui
cartezian, ce corespunde unui punct (xQ,yQ):
xQ este mai mare sau egal dect coordonatele x ale tuturor punctelor din subarborele
stng i mai mic sau egal dect coordonatele x ale tuturor punctelor din subarborele
drept
yQ este mai mic dect coordonatele y ale punctelor din subarborele stng sau drept
Construii un arbore cartezian pentru punctele date.
Soluie: Vom sorta punctele dup coordonata lor x, astfel inct x1xN. Construcia unui
arbore cartezian se poate realiza recursiv, apelnd CartTree cu parameterii 1 i N.
CartTree(i,j):
if (i=j) then return ((xi,yi),(),())
else if (i>j) then return ()
else {
selecteaz poziia p, astfel nct yp este valoarea minim dintre valorile yk (ikj)
Tstnga=CartTree(i,p-1)
Tdreapta=CartTree(p+1,j)
return ((xp,yp),Tstnga,Tdreapta)
Pentru fiecare din cele O(n) noduri ale arborelui cartezian se execut operaia de
determinare a valorii minime dintr-un interval de indici. Dac aceast valoare este cutat n
timp liniar, complexitatea algoritmului este O(n2). Dac folosim, ns, RMQ, i calculm n
timp O(1) indicele valorii minime dintr-un interval dat, atunci complexitatea final devine
O(Nlog(N)) (de la preprocesarea necesar pentru RMQ i sortarea iniial a celor N puncte).
Problema 4-2. Coada (Olimpiada de Informatic a Europei Centrale, 2006)
Avem o coad cu X (1X109) elemente. Fiecare element are o etichet, egal cu poziia
sa (iniial) n coad (aadar, elementele sunt numerotate de la 1 la X, ncepnd de la captul
din stnga al cozii ctre cel din dreapta).
Se efectueaz N (0N50.000) operaii de felul urmtor: OP(A,B)=se scoate din coad
elementul cu eticheta A i se insereaz n coad naintea (n stnga) elementului cu eticheta B.
Dup efectuarea celor N operaii, se dau Q (1Q50.000) ntrebri dintr-unul din
urmtoarele 2 tipuri:
1) pe ce poziie n coad se afl elementul etichetat cu A ?
2) ce etichet are elementul aflat pe poziia B n coad ?
Soluie: Pentru fiecare element p din coad definim pred(p) i succ(p), predecesorul i
succesorul lui p n coad (pentru elementul p de pe prima poziie definim pred(p)=0 i
pentru elementul p de pe ultima poziie definim succ(p)=X+1; vom menine i valorile
succ(0) i pred(X+1), definite ca 1 i, respectiv X, iniial).

53

Putem mpri cele X elemente n dou submulimi U i V. Elementele p din mulimea U


au proprietatea c pred(p)=p-1 i succ(p)=p+1 (adic se afl chiar n starea iniial, ele
nefiind propriu-zis afectate de mutrile realizate). Elementele din mulimea V sunt acele
noduri afectate de mutri. Vom menine elementele din mulimea V sub forma unui arbore
echilibrat, iniial vid (n acest arbore vom ine i valorile pred(p) i succ(p) ale unui element
p).
De fiecare dat cnd efectum o mutare (lum elementul A i l punem n faa elementului
B), efectum urmtoarele aciuni:
1) succ(pred(A))=succ(A);
2) pred(succ(A))=pred(A);
3) succ(pred(B))=A;
4) pred(B)=A;
5) pred(A)=pred(B);
6) succ(A)=B.
Cnd vrem s calculm pred(p) sau succ(p), l cutm pe p n mulimea V. Dac l gsim
acolo, atunci vom lua de acolo valorile succ(p) i pred(p); dac nu l gsim, vom considera
c succ(p)=p+1 i pred(p)=p-1. Atunci cnd facem o atribuire succ(p)=z sau pred(p)=z,
nti l cutm pe p n mulimea V. Dac l gsim, efectum atribuirea. Dac nu l gsim, l
inserm pe p n z cu pred(p)=p-1 i succ(p)=p+1. Dup aceasta l cutm din nou pe p n V
i efectum atribuirea. Aadar, partea de procesare a mutrilor se poate realiza n timp
O(Nlog(N)).
Pentru a rspunde la ntrebri, vom sorta ntrebrile separat, n funcie de tip. ntrebrile
de tipul 1 vor fi sortate cresctor dup eticheta elementului interogat, iar cele de tipul 2
cresctor dup poziia interogat. Apoi vom parcurge coada comprimat, meninnd, n
timpul parcurgerii, numrul nel de elemente peste care am trecut (iniial, nel=0) i ultimul
element p din mulimea V peste care am trecut (iniial, p=0).
Ct timp p<X, n mod repetat vom proceda dup cum urmeaz. Fie q=succ(p). Dac q
este n mulimea V, atunci incrementm nel cu 1. Cutm apoi binar n mulimea ntrebrilor
de tipul 1, dac exist vreo ntrebare pentru elementul cu eticheta q; dac da, atunci rspunsul
la ntrebrile de tipul 1 cu eticheta q va fi nel. n mod similar, cutm binar ntre ntrebrile
de tipul 2 dac exist vreo ntrebare pentru poziia nel; dac da, rspunsul la toate ntrebrile
de tipul 2 pentru poziia nel este q. Apoi setm p=q.
Dac, ns, q nu se afl n mulimea V, atunci vom cuta n mulimea V cel mai mic
element q strict mai mare dect q (dac nu exist un astfel de element, setm q=X+1). tim
acum c intervalul de elemente [q,q-1] se afl n aceeai ordine ca i cea iniial. Vom cuta
n mulimea ntrebrilor de tipul 1 prima ntrebare cu o etichet eq. Ct timp eq-1 punem
rspunsul la ntrebare ca fiind nel+1+(e-q), dup care trecem la urmtoarea ntrebare din
irul sortat (i vom seta e la eticheta noii ntrebri). Vom cuta apoi n mulimea ntrebrilor
de tipul 2 prima ntrebare cu o poziie poz>nel. Ct timp poznel+(q-q), punem rspunsul la
ntrebare ca fiind poz-nel+q-1, dup care trecem la urmtoarea ntrebare (i setm poz la
poziia noii ntrebri). Dup ce rspundem la toate aceste ntrebri, incrementm nel cu (qq+1), poziionndu-ne astfel pe elementul q. Dac qX, atunci l vom trata ca mai sus
(rspunznd la ntrebrile cu eticheta q sau poziia nel). La finalul iteraiei setm p=q.
Observm c a doua parte (de rspuns la ntrebri) poate fi rezolvat in timp
O(Qlog(Q)+N(log(N)+log(Q))).

54

Problema 4-3. Planificarea activitilor


Avei la dispoziie un procesor i N (1N100.000) activiti. Fiecare activitate necesit o
unitate de timp de procesare, timp n care folosete procesorul exclusiv (nu poate fi executat
o alt activitate simultan). Fiecare activitate i are asociat un profit p(i) (1p(i)100.000) i un
timp limit tf(i) (1tf(i)100.000) pn la care trebuie ncheiat execuia activitii respective.
Determinai o submulime S de activiti care s fie executate pe procesor, astfel nct fiecare
activitate i din S s i ncheie execuia pn la momentul tf(i), iar suma profiturilor
activitilor din S s fie maxim.
Soluie: Vom prezenta o prim soluie, care are complexitatea O(Nlog(N)). Vom sorta
momentele de timp tf(i) n ordine cresctoare i vom elimina duplicatele, rmnnd cu MN
momente de timp t(1)<...<t(M). Fiecrui moment t(j) i vom asocia o list L(j) n care vom
introduce toate activitile i cu tf(i)=t(j) (atunci cnd sortm momentele de timp reinem i
indicele activitii respective, iar o list este format din activitile i consecutive n ordinea
sortat a momentelor de timp care au aceeai valoare tf(i)).
n cadrul fiecrei liste L(j) vom sorta activitile descresctor dup profit. S presupunem
c lista L(j) are na(j) activiti: L(j,1), ..., L(j,na(j)), astfel nct p(L(j,1))...p(L(j,na(j))).
Dac na(j)>t(j), vom trunchia na(j) la t(j).
Vom parcurge momentele de timp de la cel mai mic la cel mai mare i vom menine un
min-heap cu activitile planificate temporar spre a fi executate pe procesor. Cheia asociat
fiecrei activiti este profitul su. Iniial, heap-ul este gol.
Cnd ajungem la un moment t(j), tim c pn la acest moment pot fi planificate cel mult
t(j) activiti. Vom menine un indice k al activitii curente din lista L(j). Iniial, k=1. Ct
timp kna(j) i heap-ul nu conine t(j) activiti, vom aduga activitatea L(j,k) n heap (cu
cheia p(L(j,k))) i vom incrementa pe k cu 1. La sfritul acestei faze, ori avem k=na(j)+1,
ori heap-ul conine exact t(j) activiti. Dac kna(j), executm urmtorii pai: ct timp
kna(j) i cel mai mic profit pmin al unei activiti din heap este strict mai mic dect p(L(j,k)),
eliminm din heap activitatea cu profitul cel mai mic i introducem n heap activitatea L(j,k)
(cu cheia p(L(j,k))). n felul acesta, activitile planificate anterior, dar care au profituri mici,
sunt nlocuite cu alte activiti mai profitabile i care pot fi nc planificate pe procesor n
timpul alocat.
La final, activitle i din heap vor fi planificate pe procesor, n ordine cresctoare a
momentelor de timp tf(i). Complexitatea fiecrei operaii de adugare n i de tergere din
heap este O(log(N)), iar complexitatea total este O(Nlog(N)).
O alt soluie tot de complexitate O(Nlog(N)) este urmtoarea. Vom sorta activitile n
ordine descresctoare a profitului. Dac dou activiti au profituri egale, o vom plasa pe cea
cu timpul limit mai mic naintea celei cu timpul limit mai mare. Vom parcurge activitile
n aceast ordine. Vom ncerca s planificm fiecare activitate i pe procesor astfel nct s se
termine la cel mai mare moment de timp ttf(i) care este disponibil. Pentru aceasta, va trebui
s meninem o structur de date care s permit gsirea acestui moment de timp.
Vom considera momentele de timp de la 1 pn la Tmax=max{tf(j)|1jN}. Iniial, toate
aceste momente de timp sunt disponibile. O prim variant const n construirea unui arbore
de intervale peste aceste Tmax momente de timp. Fiecare moment de timp corespunde unei
frunze din arborele de intervale. Fiecare nod intern al arborelui de intervale va conine
numrul de momente de timp disponibile dintre frunzele din subarborele su. Atunci cnd
dorim s gsim cel mai mare moment de timp disponibil dintr-un interval [a,b], vom

55

determina acele noduri interne ale arborelui a cror reuniune a intervalelor (disjuncte)
acoper complet intervalul [a,b]. Vom considera aceste noduri din arbore de la cel cu
intervalul cel mai din dreapta, ctre cel cu intervalul cel mai din stnga. Pentru fiecare nod q,
verificm dac conine cel puin un moment de timp disponibil. Dac da, atunci mergem
recursiv n subarborele acestuia, uitndu-ne la fiii lui q. Dac fiul drept conine cel puin un
moment disponibil, mergem mai departe (recursiv) n fiul drept; altfel mergem (recursiv) n
fiul stng. Dac nu gsim niciun moment de timp disponibil, activitatea respectiv nu poate
fi planificat.
Dup gsirea unui moment de timp t, vom parcurge toate nodurile din arbore de pe
drumul de la frunza corespunztoare lui t pn la rdcina arborelui i vom decrementa
numrul de momente de timp disponibile din aceste noduri. Operaiile de gsire a unui
moment de timp disponibil i de ocupare aunui moment de timp au complexitatea
O(log(N)) fiecare.
n locul unui arbore de intervale putem folosi o mprire n grupuri (disjuncte) de cte
(aproximativ) sqrt(N) momente de timp consecutive fiecare. Fiecare grup menine numrul
de momente de timp disponibile din interiorul su i pentru fiecare moment de timp tim
dac e disponibil sau nu. Cnd cutm cel mai din dreapta moment de timp disponibil dintrun interval [a,b], vom determina grupele intersectate de acest interval. Fie grupa din stnga
GL, grupa din dreapta GR i grupele interioare GI(j) (1jngrint). Vom parcurge momentele
de timp de la b pn la nceputul lui GR (n ordine descresctoare) i vom cuta primul
moment disponibil. Dac nu gsim niciun astfel de moment, parcurgem grupele interioare
GI(j) de la dreapta la stnga, cutnd o grup care s conin cel puin un moment disponibil.
Dac gsim o astfel de grup, parcurgem momentele de timp din interiorul ei de la dreapta la
stnga. Dac tot nu am gsit un moment disponibil, parcurgem momentele de timp din GL,
de la cel mai din dreapta moment din GL, pn la momentul de timp a. Complexitatea
operaiei de cutare este O(sqrt(N)). Pentru a marca un moment de timp t ca fiind ocupat, l
marcm ca ocupat n vectorul caracteristic folosit (ocupat[t]=true) i decrementm cu 1
numrul de momente disponibile din grupa G ce conine momentul de timp t (pentru fiecare
moment t se menine i o asociere grupa[t]=G, creat n momentul construciei grupelor).
O a treia variant (dup arborele de intervale i mprirea n grupuri de cte sqrt(N)
momente de timp), este urmtoarea. Vom menine intervalele de momente de timp ocupate
sub forma unor mulimi disjuncte. Cnd un moment de timp t este marcat ca fiind ocupat, se
creeaz o mulime ce conine momentul t. Apoi se verific dac momentul t-1 (t2) este
ocupat. Dac da, se caut reprezentantul t al mulimii lui t-1 i se unete mulimea lui t cu
cea a lui t-1. Fiecare reprezentant menine dou cmpuri: left i right. left reprezint indicele
primului moment de timp din interval i right reprezint indicele ultimului moment de timp
din interval; la unirea lui t cu t, right[t] devine t; dac t-1 nu este ocupat, atunci setm
left[t]=right[t]=t. Verificm apoi dac momentul t+1 este ocupat (tN-1). Dac da, gsim
reprezentantul t al mulimii lui t, i t al mulimii lui t+1. Vom decide care dintre cei doi
reprezentani va fi reprezentantul mulimii reunite conform euristicii folosite. S presupunem
c t va fi noul reprezentant. Vom seta left[t]=min{left[t], left[t]} i
right[t]=max{right[t], right[t]}.
Pentru a gsi cel mai mare moment de timp t mai mic sau egal ca tf(i), verificm dac tf(i)
este ocupat. Dac nu, atunci t=tf(i); altfel, determinm tr=reprezentantul mulimii din care
face parte tf(i); t va fi egal cu left[tr]-1. Dac t=0, atunci nu exist niciun moment de timp
disponibil mai mic sau egal cu tf(i). Complexitatea unei operaii cu mulimi disjuncte poate
varia, n funcie de implementarea aleas, de la O(log(N)) la O(log*(N)).

56

Problema 4-4. ATP (Lotul Naional de Informatic, Romnia 2002)


Primii N (1N100.000) juctori de tenis din clasamentul ATP particip la un turneu de
tenis. Juctorii sunt numerotai n funcie de poziia lor n clasament, cu numere de la 1 la N
(juctorul i este mai bun dect juctorul j, dac i<j). Se tie c dac doi juctori i i j (i<j)
joac unul mpotriva altuia n turneu, atunci i ctig sigur dac |j-i|>K (1KN-1). Dac, n
schimb, |j-i|K, atunci poate ctiga oricare dintre ei. Determinai care este cel mai slab
juctor (cel mai jos n clasament) care ar putea ctiga turneul.
Se tie c N este o putere a lui 2 i c turneul se joac n etape eliminatorii. n prima etap
cei N juctori se mpart n N/2 perechi care joac unul mportiva celuilalt. Cei N/2 ctigtori
avanseaz la etapa urmtoare, unde vor fi mprii n N/4 perechi .a.m.d. pn se ajuge n
final (ultimii 2 juctori). Ctigtorul finalei este ctigtorul turneului.
Soluie: Vom cuta binar (ntre 1 i N) cel mai mare indice x al unui juctor care poate
ctiga turneul. Pentru un x fixat, trebuie s verificm dac juctorul x poate ctiga turneul.
Dac da, atunci vom testa n continuare juctori cu indici mai mari dect x; dac nu, vom
testa juctori cu indici mai mici dect x. Pentru a verifica dac x poate ctiga finala, vom
construi ntreg tabloul de joc. n final, cel mai bine ar fi ca x s joace cu cel mai bun juctor
y pe care nc l poate bate: y=max{x-K, 1}. Apoi va trebui s determinm pentru y i x cu
cine s joace n semifinale. Pentru fiecare juctor x dintre ei, n aceast ordine, vom alege
acel juctor y care nu este planificat s ctige la runda curent i care este cel mai bine
plasat n clasament (y se afl n intervalul [x-K, N]). Astfel, algoritmul se contureaz n
felul urmtor. Avem o list de juctori x(1), ..., x(Q) care trebuie s ctige meciul curent
(ordonai astfel nct x(i)<x(i+1), 1iQ-1), astfel c trebuie mperecheai cu un juctor pe
care l pot bate. Iniial, avem doar juctorul x (x(1)=x). Pentru fiecare juctor i vom menine
starea lui (ocupat sau nu). Iniial, doar x este marcat ca fiind ocupat.
Vom parcurge juctorii x(j) (n ordine, j=1,...,Q) i pentru fiecare vom cuta juctorul
liber y(j) cu indicele cel mai mic din intervalul [max{x(j)-K, 1}, N] i vom mperechea
juctorii x(j) i y(j). Dac, la un moment dat, nu reuim s gsim un juctor y(j) disponibil,
atunci nu putem construi un tablou de joc astfel nct juctorul iniial x s ctige turneul.
Dup determinarea unui jucor y(j), l marcm ca fiind ocupat. Dup determinarea tuturor
juctorilor y(j), vom interclasele listele x(*) i y(*) (amndou sunt sortate cresctor dup
indicele juctorilor) i vom obine lista x(*) cu 2Q elemente ce va fi folosit la runda
urmtoare. Algoritmul se termin cu succes atunci cnd lista x i conine pe toi cei N
juctori.
Pentru determinarea juctorului disponibil cu indicele cel mai mic dintr-un interval [a,b],
puem folosi una din tehnicile de la problema anterioar (acolo se cuta cel mai mare element
disponibil dintr-un interval [a,b], ns este evident c cele 2 probleme sunt interschimbabile
putem s privim irul de poziii din sensul cellalt i, astfel, cerina de gsire a celui mai
mic element disponibil dintr-un interval devine echivalent cu cea de gsire a celui mai mare
element disponibil dintr-un interval).
O soluie alternativ mai matematic a fost prezentat de dl. prof. Stelian Ciurea.
Descriem pe scurt soluia sa n continuare. S presupunem c notm cu a juctorul cel mai
slab care ar putea ctiga turneul. Rezolvarea problemei are la baz urmtoarea afirmaie:
Cea mai mare valoare a lui a se obine dac el ntlnete n final pe a-K. Demonstraia
afirmaiei se face prin reducere la absurd: presupunem c n final a joac cu alt juctor, fie

57

acesta b. b nu poate fi mai bine clasat dect a-K (n acest caz a nu l-ar putea nvinge!). Deci
b>a-K. Apar dou situaii:
a l ntlnete pe a-K ntr-o etap anterioar finalei. n acest caz, putem interschimba pe
a-K cu b. Dac a-K joac la un moment dat cu un adversar pe care b nu l poate invinge,
interschimbm i respectivul adversar cu un adversar a lui b i repetm respectivul
procedeu i pentru adversarii adversarilor etc. (n cel mai ru caz, interschimbm ntreg
subarborele corespunztor adversarului lui a-K pe care b nu l poate invinge cu un
subarbore al unui adversar al lui b de aceeai adncime (evident vom gsi un astfel de
subarbore, deoarece b se afl pe un nivel superior lui a-K)
a nu l ntlnete pe a-K ntr-o partid direct. n acest caz, turneul ar putea fi ctigat de
a+1, deoarece n arborele binar care reprezint schema de desfurare a turneului n
aceast situaie, putem nlocui pe a cu a+1: a+1 poate s nving toi juctorii pe care i
poate invinge a cu exceia lui a-K, iar cum a nu l ntlnete pe a-K, rezult c putem
face interschimbarea ntre a i a+1.
Am ajuns deci la o contradicie o valoare mai mare pentru ctigtorul turneului, deci
afirmaia este adevrat. Putem face o afirmaie asemntoare i pentru adversarul lui a-K
din semifinal: acesta va fi a-2K, apoi pentru adversarul lui a-2K n sfertul de final, acesta
fiind a-3K .a.m.d. Putem s extindem afirmaia i mai mult, ajungnd la concluzia c dac
completm schema de desfurare a turneului ncepnd de la final, apoi semifinalele etc i
la un moment dat trebuie s alegem un adversar pentru un juctor oarecare j, atunci din
adversarii disponibili pe care j i poate nvinge, cel mai avantajos este s l alegem pe cel
mai bine clasat n clasamentul ATP. Avnd n vedere schema de desfurare a turneului care
rezult din afirmaiile de mai sus, putem s calculm valoarea lui a n modul urmtor:
a are nevoie de x adversari (x=numrul de tururi) pe care s-i nving iar acetia sunt
o a-K n final,
o a-K+1, n semifinal
o ....
o a-K+x-1 (dac K<x) sau a-K+x dac (Kx) n primul tur.
Rezult a-K+xN (sau a-K+x-1N), iar cum valoarea cea mai mare pentru a rezult la
egalitate, deducem a = N + K x
nvinii lui a au un numr de x(x-1)/2 adversari pe care i nving: a-K joac x-1 tururi
pn s fie eliminat, a-K+1 joac x-2 tururi, etc., iar aceti adversari trebuie s fie ct
mai bine clasai, primul dintre ei fiind a-2K.
Rezult a-2K + x + x (x-1)/2N deci a = N + 2K - x - x (x-1)/2 sau notnd cu G(x1) = x (x-1)/2, a = N + 2K x G(x-1)
nvinii nviniilor lui a au un numr de adversari pe care i nving egal cu G(x-2) + G(x3) + ... + G(2) + 1 iar acetia trebuie s fie ct mai bine clasai ncepnd cu a-3K
rezultnd
a = N + 3K x G(x-1) G(x-2) - ... G(2) G(1)
Se continu, dup un raionament asemntor, calculul numrului de adversari de care au
nevoie nvinii nvinilor nvinilor, ..., n calculul acestui numr observndu-se c dac n
etapa precedent a calculului a aprut un termen de genul G(x-i), atunci n etapa curent
acesta genereaz o sum de termeni G(x-i-1) + G(x-i-2) + ... +G(2) + G(1).
Evident, din relaiile obinute se va reine valoarea cea mai mare pentru a, aceasta fiind
soluia problemei. Completarea schemei de desfurare a turneului se va face apoi exact pe
baza raionamentului anterior. n program, pentru a evita calculul repetat al unor valori, se
folosesc formule de genul

58

a1 = N + K x
a2 = a1 + K G(x-1)
a3 = a2 + K G(x-2) - ... G(2) 1
a4 = a3 + K G(x-3) 2G(x-4) 3G(x-5)
...
Pentru calculul coeficienilor care apar la un moment dat n expresiile de mai sus se poate
folosi o matrice (notat m) i o procedur denumit derivare prin care se implementeaz
observaia c G(x-i) nvini au nevoie de G(x-i-1) + G(x-i-2) + ... +G(2) + G(1) adversari pe
care s-i ntlneasc pn n momentul cnd sunt la rndul lor nvini.

Problema 4-5. Turnuri (SGU)


Gigel are n fa N (1N1.000.000) celule iniial goale. El se joac cu aceste celule,
adugnd sau eliminnd cuburi din ele. Un turn este o secven maximal de celule
consecutive, cu proprietatea c orice celul din secven conine cel puin un cub. Turnurile
pot fi numerotate de la stnga la dreapta (n ordinea n care apar), iar celulele din cadrul unui
turn [a,b] pot fi numerotate de la 1 la b-a+1. Gigel efectueaz operaii de tipul urmtor:
pune/elimin x>0 cuburi n celula y;
pune/elimin x>0 cuburi n celula y a turnului z.
n plus, din cnd n cnd, Gigel i pune diverse ntrebri, de urmtoarele tipuri:
(1) cte turnuri exist? ;
(2) cte cuburi exist n turnul z ? ;
(3) cte celule conine turnul z ? ;
(4) cte cuburi conine celula y din turnul z ?
Dndu-se o secven de M (1M1.000.000) operaii i ntrebri, determinai rspunsul la
fiecare ntrebare (innd cont doar de operaiile efectuate naintea ntrebrii respective). Se
garanteaz c numrul de cuburi din orice celul nu va depi 2.000.000.000 i nu va scdea
sub 0.
Soluie: Vom menine un vector C, unde C(y)=numrul de cuburi din celula y (1yN)
(iniial, C(*)=0). De asemenea, vom menine un arbore echilibrat T ce va conine intervalele
corespunztoare turnurilor existente la fiecare moment de timp (fiecare interval va avea i o
valoare asociat, reprezentnd numrul de cuburi din interval). Vom menine i un contor NT,
reprezentnd numrul de intervale din T (deci, numrul de turnur existente). Iniial, NT=0 i
T nu conine niciun interval. De fiecare dat cnd se adaug un interval nou n T,
incrementm NT cu 1; cnd tergem un interval din T, decrementm NT cu 1. Astfel, am
rezolvat problema determinrii rspunsului la primul tip de ntrebri.
Fiecare interval [a,b] din T va avea asociat i o valoare v, reprezentnd numrul de
cuburi din celulele din cadrul intervalului.
O operaie de tipul pune x cuburi n celula y se realizeaz dup cum urmeaz. Dac
C(y)=0, atunci setm C(y)=x i efectum urmtorii pai:
(1) introducem intervalul [y,y] n T, cu valoarea x;
(2) fie a=b=y;
(3) determinm intervalul [c,d] din T, localizat imediat n stnga lui [a,b] ;
(4) dac [c,d] exist i d=a-1, atunci eliminm intervalele [c,d] i [a,b] din T i
introducem n locul lor intervalul [c,b], cu valoarea asociat egal cu suma valorilor asociate
lui [c,d] i [a,b]; n continuare, setm a=c;
(5) determinm intervalul [e,f] din T, localizat imediat n dreapta lui [a,b] ;

59

(6) dac [e,f] exist i e=b+1, atunci eliminm intervalele [e,f] i [a,b] din T i
introducem n locul lor intervalul [a,f], cu valoarea asociat egal cu suma valorilor asociate
lui [e,f] i [a,b]; n continuare, setm b=f.
Dac C(y)>0 dinaintea operaiei curente, atunci cutm intervalul [a,b] din T care conine
celula y (determinm acel interval [a,b] unde a este cea mai mare valoare mai mic sau egal
cu y). Vom incrementa cu x att C(y), ct i valoarea v asociat intervalului [a,b] din T.
O operaie de tipul pune x cuburi n celula y a turnului z presupune determinarea
intervalului [a,b] ce corespunde turnului z. Pentru aceasta, fiecare nod q din T conine
numrul de intervale nint(q) din subarborele su. Pornim din rdcina arborelui, cutnd al zlea interval. S presupunem c suntem n nodul q i cutm al k-lea interval din subarborele
nodului q. Fie qleft i qright fiii stnga i dreapta ai lui q. Dac qleft exist i nint(qleft)k,
atunci continum cutarea celui de-al k-lea interval n qleft; dac qleft exist i nint(qleft)<k,
atunci decrementm k cu nint(qleft). Dac nu am continuat cutarea n qleft i k=1, atunci
intervalul corespunztor nodului q este intervalul cutat. Dac k>1, atunci decrementm k cu
1 i continum cutarea celui de-al k-lea interval n qright (qright sigur exist, dac indicele z
iniial este mai mic sau egal cu NT).
O dat ce am identificat intervalul [a,b] din T, determinm celula y=a+y-1.
Incrementm C(y) cu x i mrim cu x i valoarea asociat intervalului [a,b] n T.
Pentru o ntrebare de tipul (2) determinm intervalul [a,b] corespunztor celui de-al z-lea
turn i ntoarcem valoarea asociat. Pentru o ntrebare de tipul (3) determinm intervalul
[a,b] corespunztor celui de-al z-lea turn i ntoarcem (b-a+1). Pentru ntrebarea (4)
determinm celula (real) y ce corespunde celulei y din turnul z i ntoarcem C(y).
Pentru operaiile de eliminare vom proceda dup cum urmeaz. Dac nu se d celula y
relativ la un turn z, determinm (ca mai sus) celula real y ce corespunde celulei y din
turnul z i setm y=y. n continuare, vom presupune c avem de-a face doar cu primul tip de
operaie de eliminare (n care se d celula real y).
Vom determina intervalul [a,b] din T ce conine celula y. Dac C(y)>x, atunci
decrementm cu x att C(y), ct i valoarea v asociat intervalului [a,b] n T. Dac C(y)=x,
atunci turnul [a,b] va fi imprit n (cel mult) alte dou intervale [a,y-1] (dac ay-1) i
[y+1,b] (dac y+1b). Vom elimina din T intervalul [a,b]. S presupunem acum c [p,q]
(pq) este unul din cele (cel mult) dou intervale n care a fost mprit intervalul [a,b]. Va
trebui s determinm numrul total de cuburi din intervalul de celule [p,q]. Pentru aceasta,
putem menine separat un arbore de intervale peste cele N celule, n care putem actualiza o
valoare C(y) i putem calcula suma valorilor dintr-un interval n timp O(log(N)). Folosind
acest arbore de intervale, determinm valoarea v ce va fi asociat intervalului [p,q] i
introducem intervalul [p,q] n T. Procedm la fel i pentru cellalt interval care a rezultat din
mprirea lui [a,b] (dac exist).
Complexitatea fiecrei operaii este O(log(N)).
Problema 4-6. Cea mai apropiat sum (UVA)
Se dau dou secvene de M, respectiv N (1M, N100.000) numere ntregi ordonate
cresctor. Prima secven conine numerele a(i) (1iM; a(i)a(i+1)), iar cea de-a doua
numerele b(j) (1jN; b(j)b(j+1)). Dndu-se o valoare S, determinai perechea de numere
(i,j) cu proprietatea c |a(i)+b(j)-S| este minim.
Soluie: O prim soluie este urmtoarea. Vom considera, pe rnd, fiecare valoare a(i). Apoi
vom cuta binar n a doua secven cea mai mare valoare b(j), mai mic sau egal cu S-a(i)

60

(dac exist; altfel setm j=0). Vom calcula apoi S1(i)=a(i)+b(j) (dac j1) i
S2(i)=a(i)+b(j+1) (dac jN-1). Cea mai mic valoarea a modulului este min{|S1(i)-S|, |S2(i)S| |1iN}. Complexitatea acestei soluii este O(Nlog(N)).
Voi prezenta acum o a doua soluie, ce are complexitate liniar. Vom determina n timp
O(N) indicele j pentru fiecare valoare a(i). Dup determinarea acestui indice, algoritmul
calculeaz sumele S1(i) i S2(i) i determin diferena n modul minim (ca mai sus). Vom
ncepe cu i=0 i j=N. Vom incrementa apoi, pe rnd, valoarea lui i (de la 1 la N). Pentru
fiecare valoare a lui i procedm dup cum urmeaz: ct timp (j1) i (a(i)+b(j)>S),
decrementm valoarea lui j cu 1. Valoarea lui j de la sfritul acestui ciclu este indicele j
corespunztor valorii a(i). Este evident c indicele i doar crete i indicele j doar scade, astfel
c obinem complexitatea liniar dorit.

61

Capitolul 5. iruri de Caractere


Problema 5-1. Base3 (Olimpiada Naional de Informatic, 2004, cls. 11-12, Romnia)
Se dau 3 numere scrise n baza 3 (folosind cifrele 0, 1 i 2). Se dorete gsirea unui
numr N n baza 3, care s aib un numr impar de cifre, iar cifra de pe poziia din mijloc s
aib valoarea 1. Acest numr N trebuie obinut prin concatenarea celor trei numere date; n
aceast concatenare, fiecare din cele 3 numere poate fi folosit de zero sau mai multe ori.
Determinai numrul minim de cifre pe care l poate avea un numr avnd proprietile
precizate.
Numrul de cifre al fiecruia din cele 3 numere este un numr ntreg ntre 1 i 16000.
Numerele date pot conine zerouri la nceput; acestea trebuie luate n considerare, dac
numrul respectiv este folosit n concatenare.
Exemplu:
001
Se poate obine un numr avnd
020
numrul
minim de
cifre
13:
2020
2020001001001.
Soluie: Se calculeaz matricea MIN[i, x ,j], cu i ntre 1 i 3, j ntre 1 i 2, iar x ntre 0 i
lungimea numrului i, avnd urmtoarea semnificaie :
dac j=1, atunci MIN[i, x, j] reprezint lungimea celui mai scurt numr care are la
mijloc primele x cifre din al i-lea numr
dac j=2, atunci MIN[i, x, j] reprezint lungimea celui mai scurt numr care are la
mijloc ultimele x cifre din al i-lea numr
Calculul acestor valori corespunde unei determinri a numrului din exterior spre centru.
Cei 3 indici ai matricei codific o stare, iar trecerea de la o stare la alta se realizeaz prin
concatenarea unuia din numere n partea stng sau dreapt. Astfel, se poate folosi un
algoritm de drum minim (de exemplu, Dijkstra cu heap-uri). Conform acestei codificri,
numrul cerut corespunde unui drum minim n graful strilor, iar lungimea acestui drum este
limitat superior de 6 * 160002 (dar, n practic, este mai mic).
Complexitatea algoritmului este O((L1 + L2 + L3)log(L1 + L2 + L3)) (Li=numrul de cifre
al celui de-al i-lea numr, 1i3).
Problema 5-2. Sub (Lotul Naional de Informatic, Romnia, 2008)
Fie A i B dou mulimi de iruri formate doar din litere mici ale alfabetului englez (de la
a la z). Fie Na (1Na100) numrul irurilor din mulimea A, iar Nb (1Nb100)
numrul irurilor din mulimea B. Se spune c s(1)s(2)...s(k) este o subsecven a unui ir
a(1)a(2)...a(n) dac exist un numr natural i (1in-k) astfel nct s(1)=a(i), s(2)=a(i+1), ...
s(k)=a(i+k-1).
Determinai numrul irurilor care sunt subsecvene ale tuturor irurilor din A, dar nu sunt
subsecvene ale niciunui ir din B. Lungimea oricrui ir din cele dou mulimi nu depete
300.
Exemplu: Mulimea A este {abcaf, bcaf, dbdafabcaf}, iar mulimea B este {bacbc,
fbca, ca}. irurile a, b, c, f, bc, ca, af, bca, bcaf, caf sunt
subsecvene ale tuturor irurilor din A. Dintre acestea, irurile: a, b, c, f, ca,
af, bca sunt subsecvene ale cel puin unui ir din B. Rmn 3 iruri care sunt

62

subsecvene ale tuturor irurilor din A, dar nu sunt subsecvene ale niciunui ir din B: af,
caf, bcaf.
Soluie: Vom construi un trie (arbore de prefixe) ce va conine toate subsecvenele irurilor
din A. Fiecare nod x al trie-ului va stoca numrul de iruri din mulimea A din care face parte
irul S(x) corespunztor nodului x (S(x) se obine prin concatenarea etichetelor muchiilor de
pe drumul de la rdcin pn la nodul x), na(x), indicele ultimului ir din A care a introdus
S(x) n trie (sau al ultimului ir din B n urma cruia s-a trecut prin nodul x), last(x), i o
valoare nb(x), reprezentnd numrul de iruri din B ce conin S(x) ca subsecven.
Vom porni cu un trie gol (conine doar nodul rdcin). Vom parcurge cuvintele din
mulimea A n ordine cresctoare a indicelui lor i (1iNa). Pentru fiecare cuvnt CA(i)
considerm fiecare poziie j a sa (1j|CA(i)|; |CA(i)|=lungimea lui CA(i)). Introducem n
trie subsecvena lui CA(i) care ncepe la poziia j (i se termin la ultimul caracter al lui
CA(i)). Pe msur ce parcurgem aceast subsecven cu un indice k (jk|CA(i)|), va trebui
s introducem noduri noi sau doar s coborm ntr-unul din fiii nodului curent.
S presupunem c, dup parcurgerea caracterului CA(i,k) suntem la nodul x n trie. Dac
last(x)i, atunci incrementm na(x) cu 1 (last(x), na(x) i nb(x) sunt iniializate la 0, la
crearea nodului) i setm last(x)=i. Dup construcia trie-ului, resetm valorile last(x) la 0.
Vom parcurge acum irurile din mulimea B, n ordine cresctoare a indicelui lor i
(1iNb). La fel ca i n cazul cuvintelor din mulimea B, considerm fiecare cuvnt CB(i) i,
pentru fiecare astfel de cuvnt, considerm fiecare poziie j (1j|CB(i)|) din el. ncepem s
inserm n trie subsecvena ce ncepe la poziia j n CB(i) i se termin pe ultima poziie a
acestuia. Pe msur ce n cadrul subsecvenei naintm cu un indice k (jk|CB(i)|), n cadrul
trie-ului coborm din nodul curent x (iniial x este rdcina) ntr-un fiu al acestuia. S
presupunem c tocmai am ajuns la poziia k din subsecvena curent CB(i) (jk). Dac x nu
are o muchie etichetat cu CB(i,k) ctre un fiu F de-al su, atunci crem acest fiu F i l
setm pe x la valoarea lui F (iniializm na(x)=nb(x)=last(x)=0); altfel, setm valoarea x a
nodului curent la fiul F. Dac last(x)i, atunci incrementm nb(x) cu 1 i setm last(x)=i.
Pentru a da rspunsul la problem, la final numrm cte noduri x ale trie-ului au
na(x)=Na i nb(x)=0. Observm c, prin metoda folosit, am rezolvat mai multe probleme,
de fapt. De exemplu, putem determina cte subsecvene sunt subsecvene ale cel puin XA i
cel mult YA iruri din A, precum i ale cel puin XB i cel mult YB iruri din B.
Pentru problema noastr putem optimiza puin consumul de memorie. Cnd parcurgem
irurile din mulimea B, dac trebuie s crem un nod nou, ne oprim cu parcurgerea
subsecvenei curente i trecem la subsecvena urmtoare din cadrul aceluiai ir (sau la irul
urmtor, dac era ultima subsecven de considerat).
Complexitatea algoritmului este O((Na+Nb) LMAX2), unde LMAX reprezint lungimea
maxim a unui ir din cele 2 mulimi.
Problema 5-3. iruri (Stelele Informaticii 2005)
Se dau dou iruri de numere X i Y, avnd ntre 1 i 100.000 elemente. Determinai o
subsecven de lungime maxim de elemente aflate pe poziii consecutive, astfel nct:
X(p)+Y(q)=X(p+1)+Y(q+1)=...=X(p+L-1)+Y(q+L-1), unde L este lungimea secvenei (am
notat prin A(i) al i-lea element din irul A).

63

Soluie: Vom construi un ir Y ce conine elementele din Y negate: Y(i)=-Y(i) (1i|Y|).


Acum trebuie s determinm o subsecven de lungime maxim L astfel nct X(p)Y(q)=X(p+1)-Y(q+1)=...=X(p+L-1)-Y(q+L-1).
Vom construi irurile X1 i Y1, avnd |X|-1, respectiv |Y|-1 elemente, unde X1(i)=X(i+1)X(i) (1i|X|-1) i Y1(i)=Y(i+1)-Y(i) (1i|Y|-1). Observm c determinarea unei
subsecvene de lungime maxim cu proprietile cerute este echivalent cu determinarea
celei mai lungi subsecvene comune a irurilor X1 i Y1. Fie L lungimea aceste subsecvene
comune (X1(p+i)=Y1(q+i), 0iL-1). Atunci exist o subsecven de lungime L+1 care
ncepe la poziia p n irul X i poziia q n irul Y i care are proprietile cerute.
n continuare ne vom concentra pe determinarea lungimii maxime a unei subsecvene
(continue) comune a dou iruri A i B. Putem realiza acest lucru folosind programare
dinamic. Calculm Lmax(i,j)=lungimea maxim a subsecvenei comune a irurilor formate
din primele i caractere din irul A i primele j caractere din irul B, care se termin pe
poziiile i, respectiv j. Avem Lmax(0,*)=Lmax(*,0)=0. Dac A(i)=B(j) (1i|A|, 1j|B|),
atunci Lmax(i,j)=1+Lmax(i-1, j-1); altfel, Lmax(i,j)=0. Lungimea subsecvenei este egal cu
max{Lmax(i,j)}.
Aceast abordare se poate generaliza pentru cazul n care avem asociat o pondere pentru
fiecare element din irul A, respectiv B (ponderile wA(i)0 i wB(j)0) i dorim s gsim o
subsecven avnd o pondere combinat maxim. n acest caz, avem nevoie de dou
funcii f i g cu valori nenegative, care combin ponderile a dou poziii care se
potrivesc (i i j), respectiv combin valorile pentru toate poziiile din subsecven. n
acest caz, relaiile devin: dac A(i)B(j), atunci Lmax(i,j)=0; altfel, Lmax(i,j)=max{g(f(wA(i),
wB(j)), Lmax(i-1, j-1)), f(wA(i), wB(j)), 0}.
Totui, algoritmul descris mai sus are complexitatea O(|A||B|), care este prea mare
pentru limitele problemei. Pentru determinarea subsecvenei (continue) comune de lungime
maxim vom construi irul Z=A$B, format din irul A, urmat de un element $ i apoi urmat
de irul B. Elementul $ este un element care nu apare n niciunul din irurile A i B. Vom
construi apoi irul de sufixe corespunztor irului Z, adic, practic, se sorteaz lexicografic
sufixele irului Z, n ordine: s(1), s(2), ..., s(|Z|). Pentru fiecare sufix s(i) putem ti exact din
ce ir (A sau B) face parte primul su element (cunoatem poziia sa n irul Z i determinm
dac se afl naintea elementului $ sau dup acesta); sufixul care ncepe cu caracterul $ nu ne
va interesa.
Apoi, folosind informaiile pstrate la construcia irului de sufixe, putem determina irul
LCP, unde LCP(i)=cel mai lung prefix comun al sufixelor s(i) i s(i+1) (1i|Z|-1). Putem
construi irul de sufixe n timp O(|Z|log(|Z|)) i apoi putem calcula LCP(i) n timp
O(log(|Z|)) pentru fiecare poziie i.
Lungimea L maxim a unei subsecvene continue a irurilor A i B este max{LCP(i)| s(i)
are primul caracter ntr-unul din iruri (A sau B), iar s(i+1) are primul caracter n cellalt ir
(B sau A)}.
Problema 5-4. Verificarea unei secvene (TIMUS)
Se d o secven de numere A(1), ..., A(N) (1N100.000). Determinai dac orice
subsecven
A(i),
...,
A(j)
(1ijN)
verific
urmtoarea
proprietate:
A(i)+A(i+1)++A(j)P(j-i+1)+Q.
Soluie: Vom construi irul B(i)=A(i)-P. Observm c dac orice subsecven din acest ir,
B(i), ..., B(j) verific proprietatea: B(i)+...+B(j)Q, atunci orice subsecven a irului A

64

verific proprietatea din enunul problemei. Verificarea proprietii irului B se poate realiza
foarte simplu. Determinm (n timp O(N), folosind unul din muli algoritmi standard
existeni) subsecvena de sum maxim din B. Fie S suma aceste subsecvene. Dac SQ,
atunci orice subsecven verific proprietatea; altfel, nu.
Problema 5-5. Expoziie (SGU)
Dou companii, A i B, vor s i expun produsele la o expoziie. Produsele sunt expuse
n standuri localizate unul dup altul, n linie (de la stnga la dreapta). Fiecare stand poate fi
gol sau plin. Standurile goale sunt etichetate cu numele uneia din cele dou companii. La
orice moment de timp, oricare din cele dou companii poate realiza una din urmtoarele dou
aciuni:
(1) compania poate alege oricare din standurile goale etichetate cu numele su i poate
amplasa acolo un produs al celeilalte companii ;
(2) compania poate alege un stand gol etichetat cu numele su, apoi: (i) amplaseaz n
stnga acestui stand dou standuri noi, dup cum urmeaz: un stand cu un produs propriu (un
stand fr etichet) i un stand gol etichetat cu numele celeilalte companii.
tiind c iniial exista un singur stand gol etichetat cu numele uneia din cele dou
companii (numele este cunoscut) i c la final s-au umplut cu produse toate standurile
existente, determinai dac irul final de standuri umplute (pentru fiecare stand, de la stnga
la dreapta, se cunoate compania al crei produs este amplasat n stand) poate fi obinut din
starea iniial prin cele dou tipuri de aciuni descrise.
Exemplu: Iniial exist un stand gol etichetat cu A. La final exist 3 standuri, coninnd, n
ordine, produse ale companiilor A, A i B. irul final poate fi obinut din starea iniial.
Soluie: Problema poate fi scris prin definirea unei gramatici independente de context. Vom
considera un alfabet format din simbolurile {A, B, NA i NB}. NA i NB reprezit standuri
goale etichetate cu numele companiei A, respectiv B; A i B reprezint standuri pline,
coninnd un produs al companiei A, respectiv B. irul iniial conine caracterul NA sau NB.
Avem 2 reguli de gramatic:
(1) NA->B | A NB NA i
(2) NB->A | B NA NB.
X -> Y | Z are semnificaia c (caracterul) X poate fi nlocuit cu irurile Y sau Z (care pot
conine 0, 1 sau mai multe caractere). Problema care se pune este dac irul dat poate fi
obinut din irul iniial folosind aceste reguli de gramatic. Pentru aceasta, vom folosi o stiv
S. Iniial, vom pune n stiv caracterul iniial dat (NA sau NB). Vom parcurge apoi irul de la
stnga la dreapta. Dac n ir avem caracterul A (B) i n vrful stivei avem caracterul NB
(NA), atunci eliminm caracterul din vrful stivei. Dac n ir avem caracterul A (B) i n
stiv avem caracterul NA (NB), atunci adugm n vrful stivei caracterul NB (NA). La final,
stiva trebuie s fie goal. Dac stiva nu este goal, atunci irul dat nu poate fi obinut din
irul (caracterul) iniial.
Problema 5-6. abc (Happy Coding 2007, infoarena)
Alfabetul limbii Makako este compus din numai 3 simboluri: a, b i c. Orice cuvnt al
acestei limbi este un ir format dintr-un numr finit de simboluri din alfabet (la fel ca n cele
mai multe din limbile folosite n prezent). Totui, nu orice niruire de simboluri formeaz un
cuvnt cu sens. Conform dicionarului limbii Makako, numai N (1N50.000) iruri de
simboluri reprezint cuvinte cu sens (n continuare, prin cuvnt vom nelege unul dintre

65

aceste iruri de simboluri ce au sens). O particularitate a limbii Makako este c oricare dou
cuvinte au exact aceeai lungime LC (ntre 1 i 20).
De curnd s-a descoperit un text antic despre care se presupune c ar fi scris ntr-un
dialect vechi al limbii Makako. Pentru a verifica aceast ipotez, oamenii de tiin vor s
determine n ce poziii din text se regsesc cuvinte din limb. Textul poate fi privit ca o
niruire de L (1L10.000.000) simboluri din alfabetul limbii Makako, n care poziiile
simbolurilor sunt numerotate de la 1 la L. Dac un cuvnt din limb se regsete ca o
niruire continu de simboluri n cadrul textului, iar poziia de nceput a acestuia este P,
atunci P reprezint o poziie candidat. Oamenii de tiin doresc s determine numrul
poziiilor candidat din cadrul textului.
S presupunem c dicionarul limbii Makako ar conine doar urmtoarele 3 cuvinte: bcc,
aba si cba, iar textul antic descoperit ar fi cababacba. La poziiile 2 i 4 din text se regsete
cuvntul aba. La poziia 7 se regsete cuvntul cba. Cuvntul bcc nu se regsete n text.
Aadar, n text exist 3 poziii candidat.
Soluie: O prim abordare care ar prea s aib anse de a obine punctaj maxim este de a
construi un trie al cuvintelor. Cu ajutorul acestui trie putem verifica n complexitate O(L)
dac exist vreun cuvnt care s nceap la fiecare poziie i din sir. Totui, aceast solutie are
complexitate O(LCL) i nu s-ar ncadra n timp.
Optimizarea const n construirea automatului finit determinist asociat celor N cuvinte.
Acest automat poate fi construit in complexitate O(NL), conform algoritmului Aho-Corasick.
Modul de constructie este asemntor calculului funciei prefix din algoritmul KMP.
Construim trie-ul cuvintelor, apoi, pentru un nod X al trie-ului, determinm nodul din trie
care corespunde celui mai lung ir de caractere care este sufix al irului asociat nodului X.
Putem calcula aceste valori pe nivele, ntruct un nod Y de tipul celui menionat mai sus se
va afla ntotdeauna pe un nivel superior nodului X (dar nu neaprat pe calea de la rdcina
trie-ului pn la nodul X). Acest automat se poate folosi apoi n cadrul parcurgerii textului
dat.
ncepem din starea corespunztoare irului vid (rdcina trie-ului). De fiecare dat cnd
trecem la urmtorul caracter, ncercm s trecem n nodul din trie ce corespunde caracterului
respectiv i este fiu al starii curente. Dac acest nod nu exist, la fel ca la KMP, trecem n
starea corespunzatoare prefixului-sufix al strii curente i repetm acest lucru pn cnd
ajungem n rdcina trie-ului sau ntr-un nod care are un fiu ce corespunde caracterului
urmtor din ir (o variant similar a acestui algoritm se folosete i pentru calculul funciilor
prefix corespunztoare fiecrui nod). Dac ajungem ntr-un nod ce corespunde unei stri
finale, atunci am gsit o apariie a unui cuvnt.
O alt soluie const n construcia unui automat finit determinist, avand complexitate
O(NL2). Se va construi trie-ul cuvintelor, apoi, pe baza acestui trie, se va calcula un automat
care are un numr de stri egal cu numrul de noduri ale trie-ului. Pentru fiecare stare X i
fiecare caracter c, se va calcula funcia nextState[X,c], reprezentnd starea ce corespunde
celui mai lung ir care este un subir al irului corespunztor strii X, concatenat cu
caracterul c. Pentru strile X ce au fiu n trie corespunztor unui caracter c, nextState[X,c] va
fi egal cu acest fiu.
Pentru celelalte caractere i o stare X, vom avea O(L) stri candidate. Mai exact, s
considerm c TX este tatl nodului X n trie (presupunnd c X nu este rdcina trie-ului) i
c avem strile Q0, Q1, .., QP stri ce corespund sufixelor de lungime 0, 1, ..., P ale irului
corespunztor nodului TX (acest ir are P+1 caractere). Atunci mulimea de stri R1, ..., RP+1

66

avnd aceeai semnificaie pentru nodul X se calculeaz ca fiind R1=fiu[Q0,u],


R2=fiu[Q1,u], ..., RP+1=fiu[QP,u], unde X=fiu[TX,u], adic fiul nodului TX, ce corespunde
caracterului u. La aceast mulime vom aduga pe R0=radacina trie-ului (ce corespunde
irului vid). nextState[X,c] va fi egal cu irul de lungime maxim dintre irurile
corespunztoare nodurilor fiu[Ri,c] (dac exist), cu 0iP+1 (sau R0, dac niciunul din
nodurile Rp nu are un fiu corespunztor caracterului c).
Se observ uor c pentru orice nod X pot exista cel mult O(L) stri candidate, deoarece
irul corespunztor unui nod X are O(L) caractere. Observm c funcia nextState[X,c] poate
fi definit i pe baza valorilor calculate de algoritmul Aho-Corasick, ea putnd fi tabelat
(precalculat pentru toate perechile (X,c)) sau calculat atunci cnd este nevoie de ea.
O soluie mai simpl const n folosirea unor funcii de hash, ca n algoritmul Rabin-Karp.
Aceste funcii trebuie s fie calculabile uor (n timp O(1)) atunci cnd avem valoarea hashului pentru un ir S i dorim s calculm valoarea pentru irul S obinut prin adugarea unui
caracter la dreapta lui S i nlturarea unui caracter din stnga lui S. Cteva variante de
functii de hash ar putea fi urmtoarele:
funcii polinomiale, cu puteri de numere prime: (cNPN+cN-1PN-1+c1P+c0) mod Q (P i
Q fiind numere prime)
scrierea irurilor ca numere n baza 3 (ntruct alfabetul const doar din 3 litere) => este
ideea de mai sus, dar cu P=3.
Problema 5-7. Cel mai scurt subir al lui A care nu este subir al lui B (Olimpiada
Naional de Informatic, Croaia 2003)
Se dau 2 iruri, A i B, avnd cel puin 1 i cel mult 3.000 de caractere din mulimea
{1,...,K} (1K3.000). Determinai lungimea celui mai scurt subir al lui A care nu este
subir al lui B. Un ir P este subir al lui Q dac se poate obine din Q prin tergerea a 0 sau
mai multe caractere (deci, caracterele din P nu trebuie s se afle pe poziii consecutive n Q).
Soluie: Fie len(A) i len(B) lungimile irurilor A i B. Vom nota prin A(i) (B(j)) al i-lea (jlea) caracter din irul A (B) (vom considera poziiile numerotate de la 1). Pentru irul B vom
calcula valorile Prev(i,c)=poziia j (1ji) cea mai mare pe care se afl caracterul c ntre
primele i caractere ale irului B (sau 0 dac acest caracter nu se regsete printre primele i
caractere ale lui B). Avem Prev(0,c)=0 (1cK). Pentru 1ilen(B), vom avea:
Prev(i,B(i))=i i Prev(i,cB(i))=Prev(i-1,c).
n continuare vom folosi metoda programrii dinamice. Vom calcula valorile
Lmin(i,j)=lungimea minim a unui subir al primelor i caractere ale irului A care nu este
subir al primelor j caractere ale irului B. Vom avea Lmin(0,0jlen(B))=+. Pentru
1ilen(A) avem:
(1) Lmin(i,0)=1;
(2) pentru 1jlen(B), dac Prev(j,A(i))=0, atunci Lmin(i,j)=1; altfel, avem 2 cazuri:
(a) considerm c subirul determinat nu se termin la poziia i din A; i
(b) considerm c subirul determinat se termin la poziia i din A.
De aici rezult Lmin(i,j)=min{Lmin(i-1,j), 1+Lmin(i-1, Prev(j, A(i))-1)}. Cazul (a)
corespunde termenului Lmin(i-1,j) (este ca i cum nu am avea i poziii, ci i-1). Cazul (b)
corespunde termenului 1+Lmin(i-1, Prev(j, A(i))-1).
Determinm un subir al primelor i-1 caractere ale lui A care nu este subir al primelor
Prev(j, A(i))-1 caractere din irul B, la care adugm (la sfrit) caracterul A(i). Subirul

67

obinut este un subir al primelor i caractere din A, dar nu este un subir al primelor j
caractere din B. Complexitatea acestui algoritm este O((len(A)+K)len(B)).
Problema 5-8. Tunes (CPSPC 2004)
Considerm un alfabet ce conine n simboluri (1n50.000) numerotate de la 0 la n-1. Un
ir s1, ..., sk compus din caractere ale acestui alfabet se numete bun dac pentru orice valori i
i j (1ik-1 i i+2j-1k), irurile si, ..., si+j-1 i si+j, ..., si+2j-1 nu conin exact aceleai
caractere (adic exist cel puin un caracter x care apare de un numr diferit de ori n cele
dou iruri).
Un ir bun se numete neextensibil dac nu se poate obine un alt ir bun prin adugarea a
oricrui numr caractere la nceputul i/sau la sfritul acestuia. Determinai un ir bun i
neextensibil de lungime minim, care conine fiecare caracter al alfabetului cel puin o dat.
Soluie: Pentru n=1 singurul ir bun este 0, iar pentru n=2 exist 2 iruri bune i
neextensibile: 0,1,0 i 1,0,1. Pentru n=3, un ir bun i neextensibil de lungime minim este: 0,
1, 0, 2, 1, 2.
Pentru n4, o prim soluie este urmtoarea. Definim funciile u(a,b) i v(a,b), care ntorc
iruri de caractere. u(a,b) ntoarce irul de caractere a, a+1, ..., b (care conine caracterele de
la a la b, n ordine cresctoare). v(a,b) ntoarce irul a, a-1, a+1, a, ..., b, b-1 (deci irul ce
const din concatenarea irurilor k, k-1, n ordine, cu k de la a la b). Un ir bun neextensibil
de lungime minim este urmtorul: 0, v(1,n-4), n-3, n-1, n-4, n-2, u(3,n-2), 0, n-1, u(1,n-4), 1,
3, 0, 2, v(4,n-1), n-1.
O alt soluie este urmtoarea. Fie funcia q(a)=dac a este impar atunci ((a+3) div 2)
altfel a/2. Definim apoi funcia f(a), care ntoarce un ir de caractere: q(1), q(2), ..., q(a) (deci
irul format din caracterele q(i), n ordine, pentru i de la 1 la a). O soluie pentru problema
noastr este urmtoarea: 0, u(2,n-2), u(1,n-2), 0, f(n-2), 0, u(2,n-1), u(2,n-2), 0. u este aceai
funcie folosit n soluia anterioar.
Problema 5-9. iruri Fibonacci (ACM SEERC 1997, enun modificat)
S considerm irurile F(0)= (irul vid), F(1)=A, F(2)=B i
F(i3)=concatenare(F(p(i,1)), ..., F(p(i,NK(i)))) (obinut prin concantenarea irurilor
F(p(i,1)), ..., F(p(i,NK(i))), n ordine, unde p(i,j)<i). De exemplu, putem avea NK(i)=2 i
p(i,1)=i-1 i p(i,2)=i-2 (pentru i3).
Se d i un ir S (de lungime cel mult 20). Determinai de cte ori apare S n irul F(N)
(1N30.000).
Soluie: Vom genera irurile F(i) (i1) conform regulii de concatenare, pn cnd ajungem
la i=N sau pn cnd len(F(i))len(S) (len(X) reprezint lungimea irului X). S presupunem
c am ajuns la irul F(k) (kN). Vom calcula prin orice metod de cte ori apare S n fiecare
ir F(ik) (de exemplu, ncercm fiecare poziie de start i verificm dac S se potrivete
ncepnd de la acea poziie). Fie NA(i)=numrul de apariii ale lui S n F(i). Avem calculate
pn acum toate valorile NA(ik).
Fie pref(i)=prefixul de lungime (cel mult) len(S)-1 al irului F(i) i suf(i)=sufixul de
lungime (cel mult) len(S)-1 al irului F(i). Vom avea pref(ik-1)=suf(k-1)=F(k-1), iar pref(k)
i suf(k) sunt obinute prin pstrarea primelor (respectiv ultimelor) len(S)-1 caractere din F(k).
Dac k<N, atunci calculm i F(k+1), pref(k+1), suf(k+1) i NA(k+1) (tot prin metoda forei
brute), incrementnd dup aceea pe k cu 1.

68

Apoi, ct timp k<N, vom proceda dup cum urmeaz: incrementm pe k cu 1; apoi setm
NA(k)=suma valorilor NA(p(k,j)) (1jNK(k)). Construim apoi pref(k) i suf(k). Concatenm
n mod repetat irurile pref(p(k,j)) (n ordine cresctoare a lui j), pn cnd irul obinut
conine cel puin len(S)-1 caractere (sau am considerat deja toate cele NK(k) iruri). pref(k)
const din primele len(S)-1 caractere ale irului obinut (sau din ntreg irul, dac acesta
conine mai puin de len(S)-1 caractere). n mod similar, concatenm (de la dreapta la stnga)
irurile suf(p(k,j)) (n ordine descresctoare a lui j), pn cnd irul obinut conine cel puin
len(S)-1 caractere (sau am considerat deja toate cele NK(k) iruri). suf(k) const din ultimele
len(S)-1 caractere ale irului obinut (sau din ntreg irul, dac acesta conine mai puin de
len(S)-1 caractere).
Vom proceda apoi dup cum urmeaz. Iniializm un ir X=suf(p(k,1)). Apoi considerm,
pe rnd, toate poziiile j=2, ..., NK(k). S considerm poziia j la care am ajuns. Construim
irul X prin concatenarea irului X cu pref(p(i,j)). Cutm de cte ori apare irul S n irul X
i incrementm NA(k) cu acest numr de apariii. Calculul numrului de apariii se poate
realiza prin for brut. Dup aceasta, concatenm la sfritul irului X irul suf(p(i,j)). Dac
irul X are acum cel puin len(S) caractere, atunci setm X ca fiind egal cu subirul format din
ultimele len(S)-1 caractere ale sale.
Observm c, la fiecare pas, irul X are cel mult len(S)-1 caractere i, prin urmare, irul
X are cel mult 2len(S)-2 caractere.
Complexitatea acestei soluii este O(L(len(S))2), unde L este suma valorilor NK(i)
(1iN) sau, dac folosim o metod mai eficient pentru a calcula numrul de apariii al lui S
(de ex., algoritmul KMP), complexitatea poate fi redus la O(Llen(S)).

69

Capitolul 6. Geometrie Computational


Problema 6-1. Volumul reuniunii a N hiper-dreptunghiuri
Se dau N (1N50) hiper-dreptunghiuri d-dimensionale (1d10 i Nd500.000), cu
laturile paralele cu axele de coordonate. Pentru fiecare hiper-dreptunghi i se dau coordonata
minim i cea maxim n fiecare dimensiune j (x1(i,j) i x2(i,j), x1(i,j)<x2(i,j)). Determinai
volumul reuniunii celor N hiper-dreptunghiuri.
Soluie: Vom sorta independent cele 2N coordonate ale celor N hiper-dreptungiuri n fiecare
dimensiune j (1jN), eliminnd duplicatele, astel nct xs(j,1)<...<xs(j,nx(j))
(xs(j)=coordonatele sortate n dimensiunea j; nx(j)=numrul de coordonate distincte din
dimensiunea j). n timpul sortrii vom reine pentru fiecare dreptunghi i indicii ix1(i,j) i
ix2(i,j) unde apar x1(i,j) i x2(i,j) n xs(j).
Vom calcula o matrice d-dimensional V, avnd (nx(1)-1)...(nx(d)-1)=O(Nd) celule.
Elementul i din dimensiunea j a matricii V (1inx(j)-1) corespunde intervalului
[xs(j,i),xs(j,i+1)]. Astfel, fiecare celul (c(1), ..., c(d)) a lui V corespunde unui hiperdreptunghi d-dimensional [xs(1,c(1)),xs(1,c(1)+1)]x...x[xs(d,c(d)),xs(d,c(d)+1)] vom defini
volumul celulei (c(1), ..., c(d)), cvol(c(1), ..., c(d)) ca fiind volumul hiper-dreptunghiului ddimensional asociat. Vom seta valoarea fiecrei celule din V la 0.
Considerm apoi fiecare hiper-dreptunghi i dintre cele N i parcurgem toate celulele
(c(1), ..., c(d)), cu ix1(i,j)c(j)<ix2(i,j); pentru fiecare astfel de celul, incrementm V(c(1), ...,
c(d)) cu 1. La final, iniializm valoarea volumului reuniunii Vol la 0 i apoi parcurgem toate
celulele din matricea V. Dac pentru o celul (c(1), ..., c(d)) avem V(c(1), ..., c(d))>0, atunci
adunm la Vol valoarea cvol(c(1), ..., c(d)). Complexitatea acestei soluii este O(Nd+1).
O soluie mult mai simpl, dar cu dezavantajul de a fi aproximativ, este urmtoarea.
Calculm hiper-dreptunghiul minim MBR care include toate cele N hiper-dreptunghiuri date.
MBR are coordonata minim n dimensiunea j (1jd) egal cu min{x1(i,j)|1iN} i
coordonata maxim n aceeai dimensiune egal cu max{x2(i,j)|1iN}. Vom genera apoi, n
mod aleator, un numr de M puncte aflate n interiorul lui MBR. Pentru fiecare punct,
numrm n cte dintre cele N hiper-dreptunghiuri este inclus. Dac este inclus n cel puin
un hiper-dreptunghi, atunci vom incrementa un contor nin (iniializat la 0). La final, o
valoare aproximativ a volumului reuniunii este nin/MVolum(MBR) (unde Volum(MBR)
reprezint volumul lui MBR, care este uor de calculat). Pentru a obine o aproximare ct mai
bun ar trebui s generm un numr foarte mare de puncte (M foarte mare). Complexitatea
acestei abordri este, ns, O(MN).
Problema 6-2. Puncte maximale
Se dau N puncte n plan (punctul i e la coordonatele (x(i), y(i))). Oricare 2 puncte au
coordonatele x i y diferite. Un punct i se numete maximal dac nu exist un alt punct y,
astfel nct x(j)>x(i) i y(j)>y(i). Determinai mulimea de puncte maximale.
Soluie: Vom introduce punctele pe rnd, n ordine cresctoare a indicelui lor, meninnd un
arbore echilibrat cu punctele maximale de pn acum (sortate dup coordonata x). Pentru a
nu trata cazuri particulare, vom introduce la nceput un punct (-,+-) i un punct (+,-).
Aceste dou puncte vor fi mereu puncte maximale. Cnd introducem punctul (x(i),y(i)),

70

cutm n arbore punctul j cu cea mai mic coordonat x(j) mai mare dect x(i). Dac
y(j)>y(i), atunci punctul i nu este punct maximal i putem s l ignorm. Dac y(j)<y(i),
atunci vom iniializa un indice k la predecesorul punctului j gsit. Ct timp y(k)<y(i)
executm urmtoarele aciuni:
(1) gsim k, predecesorul punctului k n arbore;
(2) tergem punctul k din arbore (nu mai este punct maximal);
(3) k=k.
La sfrit, vom aduga i punctul i n arbore. Complexitatea acestui algoritm este
O(Nlog(N)).
Problema 6-3. Puncte dominate
Se dau N puncte n plan (punctul i e la coordonatele (x(i), y(i)) i are o pondere w(i)0).
Pentru fiecare punct i dorim s determinm suma ponderilor punctelor ji cu proprietatea
x(j)x(i) i y(j)y(i). Oricare 2 puncte se afl amplasate la coordonate diferite.
Soluie: O prim variant const din introducerea tuturor punctelor ntr-o structur de date
numit range tree. Aceast structur permite calcularea sumei ponderilor punctelor dintr-un
dreptunghi [xa,xb]x[ya,yb] n timp O(log2(N)) (sau O(log(N)), folosind nite tehnici speciale).
Pentru fiecare punct i, determinm suma ponderilor punctelor care se afl n dreptunghiul [,x(i)]x[-,y(i)] (i scdem din ea w(i), cci se va considera i punctul i).
O a doua variant const n sortarea punctelor cresctor dup X (i pentru X egal,
cresctor dup Y). Vom parcurge punctele n aceast ordine i vom menine o structur de
date peste coordonatele y(*) distincte i sortate ale celor N puncte (arbore de intervale sau
mprire n grupuri de cte sqrt(N) poziii). Avem dou posibiliti:
(1) pentru un punct i determinm suma ponderilor punctelor din intervalul [-,y(i)]
(range query), reprezentnd valoarea dorit; apoi incrementm cu w(i) suma ponderilor
punctelor aflate la coordonata y(i) (point update);
(2) pentru un punct i determinm suma valorilor cu care a fost incrementat poziia y(i)
(point query); apoi incrementm cu w(i) numrul de puncte din intervalul [y(i),+] (range
update).
Arborele de intervale ofer o complexitate O(log(N)) pentru ambele operaii n ambele
cazuri. Folosind mprirea n grupe de cte sqrt(N) poziii, pentru cazul (1) avem O(sqrt(N))
pentru range query i O(1) pentru point update (incrementm numrul de puncte asociate
poziiei y(i), ct i grupei din care face parte y(i)); pentru cazul (2) avem O(1) pentru point
query i O(sqrt(N)) pentru range update.
O arhitectur generic de folosirea a arborilor de intervale i a mpririi n grupe de cte
sqrt(N) a fost prezentat n [Andreica-CTRQ2008] i [Andreica-COMM2008].
Problema 6-4. Oypara (Lotul de Informatic, Romnia, 2006)
Se dau N (1N100.000) segmente verticale: capatele segmentului i au coordonatele
(x(i),yjos(i)) i (x(i),ysus(i)). Determinai dac exist o dreapt care s intersecteze toate cele
N segmente. Dac o astfel de dreapt exist, determinai ecuaia acesteia.
Soluie: Dac exist o dreapt care intersecteaz toate cele N segmente, atunci aceasta poate
fi translatat i rotit astfel nct s ating dou dintre capetele segmentelor. Astfel, putem
alege oricare dou capete de segmente i verifica n timp liniar dac dreapt determinat de

71

cele dou capete intersecteaz toate cele N segmente. Acest algoritm are complexitatea O(N3)
i este ineficient pentru limitele problemei.
Un algoritm mai bun este urmtorul. Considerm mulimea A ca fiind format din toate
capetele sus ale segmentelor i mulimea B coninnd toate capetele jos ale segmentelor.
Determinm nfurtoarea convex a punctelor din A (CHA) i infurtoarea convex a
punctelor din B (CHB). Acum trebuie s determinm dac exist o dreapt care separ cele
dou poligoane (CHA i CHB sunt n semiplane opuse ale dreptei). Pentru aceasta vom roti
dou drepte paralele n jurul lui CHA i CHB. Pornim cu o dreapt vertical DA care atinge
CHA n cel mai din stnga punct, i cu o dreapt vertical DB care atinge CHB n cel mai din
dreapta punct. Ambele drepte vor fi rotite n sens trigonometric pe conturul poligonului
corespunztor.
Pentru fiecare dreapt meninem vrful de sprijin din cadrul lui CHA (CHB). Pe msur
ce rotim dreptele, avem o serie de evenimente n care acestea i schimb punctul de sprijin.
De exemplu, dac dreapta DA se sprijinea pe punctul PA i este rotit pn cnd se
suprapune cu muchia (PA,PA+1), atunci noul ei punct de sprijin va fi PA+1. Pentru fiecare
eveniment reinem care este dreapta care i schimb punctul de sprijin (DA sau DB), precum
i cu cte grade a fost rotit dreapta din poziia iniial pentru a avea loc evenimentul.
Bineneles, evinementele vor fi sortate dup numrul de grade asociat acestora. Dac nainte
sau dup apariia vreunui eveniment se ntmpl ca PB i un punct din interiorul lui CHA (de
ex., media aritmetic a coordonatelor vrfurilor acestuia) se afl n semiplane opuse fa de
DA, atunci DA separ CHA i CHB (la fel, i DB separ CHA i CHB).
Acest algoritm are complexitate O(Nlog(N)). Calcularea celor dou nfurtori convexe
dureaz O(Nlog(N)). Exist O(N) evenimente, care pot fi sortate n timp O(Nlog(N)). Pentru
fiecare eveniment, testarea dac PB un punct din interiorul lui CHA sunt n semiplane
opuse fa de DA se realizeaz n timp O(1) (se calculeaz semnul unor ecuaii).
Problema 6-5. Puncte ntr-un poligon convex
Se d un poligon convex avnd N (1N100.000) vrfuri; vrful i are coordonatele
(x(i),y(i)). Se dau, de asemenea, M ntrebri de forma: se afl punctul (xp, yp) n interiorul
poligonului ?
Soluie: Vom alege un punct (xc,yc) aflat strict n interiorul poligonului. De exemplu, xc (yc)
ar putea fi media aritmetic a coordonatelor x (y) ale vrfurilor. Vom trasa segmentele
(xc,yc)-(x(i),y(i)) de la punctul (xc,yc) la fiecare vrf al poligonului. Vom sorta apoi aceste
segmente dup panta pe care o formeaz dreapta lor suport cu axa OX. Pentru fiecare punct
(xp,yp), vom calcula panta Pp a dreptei ce conine punctele (xc,yc) i (xp,yp), apoi vom cuta
binar segmentul (xc,yc)-(x(i),y(i)) avnd cea mai mare pant mai mic sau egal cu Pp (dac
nu exist niciun astfel de segment, atunci punctul se afl n intervalul de unghiuri dintre
ultimul segment i primul; astfel, vom considera i=N). Vom verifica apoi dac (xp,yp) se afl
n interiorul triunghiului determinat de punctele (xc,yc), (x(i),y(i)) i (x(i+1),y(i+1))
(considernd punctele de pe poligon n aceeai ordine n care apar n sortarea dup pant i
considernd c vrful N+1 este acelai cu vrful 1). Verificarea se poate face n felul
urmtor: trebuie ca (xp,yp) s se afle de aceeai parte a lui (x(i),y(i))-(x(i+1),y(i+1)) ca i
punctul (xc,yc). Complexitatea acestui algoritm este O(Nlog(N)).
Un alt algoritm avnd aceeai complexitate se bazeaz pe urmtoarea idee. Se alege o
dreapt ce trece prin fiecare punct testat (de exemplu, o dreapt orizontal). Se determin
apoi, n timp O(log(N)) (folosind un algoritm corespunztor), dac dreapta intersecteaz

72

poligonul convex i, dac da, se calculeaz punctele de intersecie; se verific apoi ca punctul
testat s se afle pe segmentul determinat de cele dou puncte de intersecie.
Problema 6-6. Intersecii ntre drepte i un poligon convex
Se d un poligon convex avnd N (1N100.000) vrfuri; vrful i are coordonatele
(x(i),y(i)). Se dau, de asemenea, M ntrebri de forma: Dndu-se o dreapt determinat de
dou puncte (x1, y1) i (x2, y2), determinai dac aceast dreapt intersecteaz sau nu
poligonul.
Soluie: Vom alege un punct (xc,yc) aflat strict n interiorul poligonului. O prim variant de
rezolvare a problemei este urmtoarea. Vom transalata sistemul de coordonate n asa fel nct
(xc,yc) s ajung n originea sistemului. Vom dualiza dreptele suport ale laturilor poligonului.
Fiecare dreapt este dualizat ntr-un punct din planul dual. Vom determina nfurtoarea
convex CH a punctelor duale (n mod normal ar trebui ca pe nfurtoare s apar toate
punctele, n ordinea n care apar dreptele suport pe conturul poligonului convex iniial).
Pentru fiecare dreapt dat, vom calcula punctul dual corespunztor acesteia. Dreapta va
intersecta poligonul iniial doar dac punctul dual nu se afl n interiorul nfurtorii
convexe duale CH. Pentru testarea rapid (n O(log(N))) a incluziunii unui punct ntr-un
poligon convex, putem folosi soluia de la problema anterioar.
Problema 6-7. Ghirland (ACM ICPC NEERC, Rusia, 2000, enun modificat)
Se d o ghirland ce const din N (1N10.000) lmpi, aezate una dup alta, la diferite
nlimi. nlimile H(i) (1iN) satisfac urmtoarele reguli:
H(1)=A (10A1000, dat)
H(i)=((xH(i-1)+yH(i+1))/p)-q (2iN-1, 0<p, q, x, y10)
H(i)0 (1iN)
Determinai cea mai mic valoare posibil pentru H(N).
Exemple:
N=8, A=15, p=2, q=1, x=1, y=1 => H(N)=9,75
N=692, A=532,81, p=2, q=1, x=1, y=1 => H(N)=446113,34
Soluie: Prima soluie const n a cuta binar cea mai mic valoare posibil pentru H(2). S
presupunem c am ales o valoare candidat HC pentru H(2). Cunoscnd pe H(i) i pe H(i-1)
(2iN-1), putem calcula pe H(i+1). Avem H(i+1)=p/y(H(i)+q)-x/yH(i-1).
Calculm toate valorile H(i) i verificm ca toate s fie mai mari sau egale cu 0. Dac
aceast condiie este ndeplinit, atunci HC este o valoare fezabil i vom testa o valoare mai
mic data viitoare; altfel, vom testa o valoare mai mare. H(N) este valoarea calculat
corespunztoate celei mai mici nlimi fezabile H(2).
Vom termina cutarea binar atunci cn intervalul de cutare are o lungime mai mic sau
egal cu o constant fixat n prealabil (de ex., 10-4). Limita superioar HMAX iniial este
aleas corespunztor (de ex., 106). Complexitatea acestei soluii este O(Nlog(HMAX)).
Un algoritm cu complexitatea liniar (O(N)) este urmtorul. Vom scrie fiecare nlime
H(i) (1iN) ca o funcie liniar de forma a(i)H(2)+b(i). Pentru i=1 avem a(1)=0 i b(1)=A,
iar pentru i=2 avem a(i)=1 i b(i)=0. Pentru 3iN, avem: a(i)=p/ya(i-1)-x/ya(i-2) i
b(i)=p/yb(i-1)+pq/y-x/yb(i-2). Din aceste ecuaii vom calcula cea mai mic valoare
fexabil pentru H(2) i cea mai mare valoare fezabil.

73

Iniializm H2min=0 i H2max=+. Din a(i)H(2)+b(i)0, obinem a(i)H(2)-b(i).


Dac a(i)=0 i (-b(i)>0), atunci nu exist soluie. Dac a(i)>0, setm H2min=max{H2min, b(i)/a(i)}; dac a(i)<0, setm H2max=min{H2max, -b(i)/a(i)}. La sfrit, dac
H2min>H2max, atunci nu exist nicio soluie. Altfel, H2min este cea mai mic valoare
fezabil pentru H(2), iar H2max este cea mai mare valoare fezabil. Dac a(N)0, setm
H(2)=H2min; altfel, setm H(2)=H2max. Pornind de la valorile H(1) i H(2) putem calcula
iterativ valorile H(3iN), obinnd, astfel, valoarea H(N) minim cutat.
Problema 6-8. Cerc cu K puncte (TIMUS, enun modificat)
Se dau N (3N50.000) puncte n plan. Determinai un cerc (de orice raz) care s
conin pe circumferin sau n interiorul su exact K (0KN) puncte. Se tie c oricare 3
puncte nu sunt coliniare i oricare 4 puncte nu sunt conciclice (nu se afl pe acelai cerc).
Soluie: Pentru K=0 putem alege un cerc de raz 0 care nu are centrul ntr-unul din punctele
date, iar pentru K=1 alegem un cerc de raz 0 cu centrul ntr-unul din punctele date.
Pentru K2 am putea ncerca toate combinaiile de 2 sau 3 puncte care determin un cerc,
iar apoi am verifica dac fiecare din celelalte puncte se afl n interiorul cercului sau n afara
acestuia. Complexitatea acestei soluii este, ns, prea mare (O(N4)). O soluie de
complexitate O(Nlog(N)) este urmtoarea. Vom alege dou puncte A i B care sunt
consecutive pe nfurtoarea convex a celor N puncte (determin o latur a acesteia).
Pentru determinarea acestor puncte nu trebuie, neaprat, s calculm nfurtoarea convex.
Putem alege, de exemplu, punctul A cu coordonata x minim, iar punctul B este cel pentru
care dreapta-suport a segmentului A-B are panta minim dintre toate celelalte drepte A-i
(1iN, iA).
Cercul determinat va avea centrul pe mediatoarea segmentului AB (mediatoare=dreapta
perpendicular pe segmentul AB i care trece prin mijlocul acestuia). Vom considera fiecare
din celelalte N-2 puncte i i vom calcula coordonatele centrului cercului determinat de
punctele A, B i i. Vom asocia fiecrui centru distana d(i) fa de mijlocul segmentului AB.
Dac centrul determinat este nspre interiorul nfurtorii convexe (adic n semiplanul
dreptei AB ce conine celelalte N-2 puncte, atunci distana va fi pozitiv); dac se afl nspre
exteriorul nfurtorii convexe (n semiplanul opus celorlalte puncte fa de dreapta AB),
vom lua distana cu semnul -.
Vom sorta apoi centrele cercurilor dup distana calculat. Avem d(1)d(2)d(N-2).
Dac avem K=2, putem alege centrul cercului la o distan mai mic dect d(1) (aceast
distan poate fi orict de aproape de -). Dac K3, atunci putem alege centrul cercului
oriunde n intervalul [d(K-2), d(K-1)) (considernd d(N-1)=+).
Problema 6-9. Puncte n triunghiuri (Lotul Naional de Informatic, 2003)
Se dau N (3N1.000) puncte n plan, oricare trei necoliniare i oricare dou avnd
coordonate X i Y diferite. Se dau i M (0M500.000) ntrebri de tipul: determinai cte
puncte sunt cuprinse strict n interiorul triunghiului cu vrfurile n punctele A, B i C
(1A,B,CN). Gsii o modalitate eficient de a rspunde la ntrebri.
Soluie: Voi prezenta pentru nceput o soluie ce rspunde n timp O(log(N)) la fiecare
ntrebare. Vom preprocesa setul de puncte n felul urmtor: considerm fiecare punct x i
sortm circular celelalte N-1 puncte y n jurul su, n funcie de panta dreptei x-y. La fiecare
ntrebare vom considera c A i C sunt punctele cu cordonata x minim i maxim, iar B este

74

localizat ntre ele. Dac B este deasupra segmentului A-C, atunci vom calcula cte puncte NA
se afl n intervalul de unghiuri determinat de semidreptele A-C i A-B, n sensul de la C spre
B (vom efectua dou cutri binare n ordinea circular a punctelor din jurul punctului A).
Apoi vom calcula cte puncte NC sunt n intervalul de unghiuri din jurul punctului C,
determinat de poriunea ce ncepe la punctul C din semidreapta AC i semidreapta CB (n
sens trigonometric). Apoi vom calcula cte puncte NB se afl n jurul punctului B, n
intervalul de unghiuri determinat de poriunea semidreptei AB ce ncepe n punctul B i
poriunea semidreptei CB ce ncepe n punctul B (n sens trigonometric). Rspunsul la
ntrebare este NA-NC+NB.
Dac B se afl sub segmentul AC, atunci calculm: NA=numrul de puncte din jurul lui A,
aflate n intervalul de unghiuri determinat de semidreptele AB i AC (n sens trigonometric) ;
NB=numrul de puncte din jurul lui B, aflate n intervalul de unghiuri determinat de
poriunea semidreptei AB ce ncepe n punctul B i semidreapta BC (n sens trigonometric) ;
NC=numrul de puncte din jurul lui C, aflate n intervalul de unghiuri determinat de
poriunea semidreptei AC ce ncepe n punctul C i poriunea semidreptei BC ce ncepe n
punctul C (n sens trigonometric). Rezultatul este NA-NB+NC.
Rspunsul la fiecare ntrebare se poate da i n timp O(1). Vom precalcula numrul de
puncte NP(i,j) aflate sub fiecare segment determinat de perechea de puncte (i,j) (unde i are
coordonata x mai mic dect j). La o ntrebare, dac B se afl ntre A i C i deasupra
segmentului A-C, rspunsul este NC(A,B)+NC(B,C)-NC(A,C). Dac B se afl sub segmentul
A-C, rspunsul este NC(A,C)-NC(A,B)-NC(B,C).
Pentru a calcula eficient (n mai puin de O(N3)) valorile dorite, vom proceda n felul
urmtor. Vom sorta punctele n ordine cresctoare a coordonatei x: p(1), ..., p(N). Vom
parcurge descresctor, cu un indice i=N-1,...,1 aceste puncte. Vom sorta circular punctele
p(i+1), ..., p(N) n jurul punctului i. S considerm aceste puncte c(i,1), ..., c(i,N-i), n ordine
cresctoare a unghiului format de dreapta p(i)-c(i,j) cu axa OX (1jN-i). Avem NC(p(i),
c(i,1))=0. Pentru 2jN-i, avem: dac x(c(i,j))>x(c(i,j-1)), atunci NC(p(i), c(i,j))=NC(p(i),
c(i,j-1))+NC(c(i,j-1), c(i,j))+1; altfel, NC(p(i), c(i,j))=NC(p(i), c(i,j-1))-NC(c(i,j), c(i,j-1)).
Astfel, preprocesarea se poate realiza n timp O(N2log(N)). Cu puin atenie, ea se poate
realiza chiar n timp O(N2), dac nu sortm de la capt toate punctele n jurul fiecrui punct
p(i) [Eppstein1992].
Problema 6-10. Ciclu hamiltonian fr intersecii (TIMUS)
Se dau N (3N1.000) puncte n plan, oricare trei necoliniare. Determinai un poligon
care are ca vrfuri cele N puncte i ale crui laturi nu se intersecteaz (cu excepia faptului c
oricare 2 laturi consecutive de pe poligon se ating n vrful comun).
Soluie: O soluie de complexitate O(N2) este urmtoarea. Se determin nfurtoarea
convex a celor N puncte. Vom nota aceast nfurtoarea cu L(1). Eliminm punctele din
L(1) i apoi determinm nfurtoarea convex a punctelor rmase. Notm aceast mulime
cu L(2). Din punctele rmase eliminm punctele din L(2) .a.m.d. Practic, calculm n mod
repetat nfurtori convexe ale punctelor rmase dup eliminarea punctelor de pe
nfurtorile convexe deja calculate.
S presupunem c am obinut k straturi de nfurtori convexe: L(1), ..., L(k). L(k)
poate s constea i dintr-un singur punct sau din dou puncte. Vom determina poligonul P
dorit dup cum urmeaz. Iniializm P(1) cu poligonul convex L(1). Apoi, pentru fiecare
i=2,...,k-1, vom uni P(i-1) cu L(i).

75

Vom cut o latur (a,b) a lui P(i-1) pe care s o eliminm din P(i-1). De asemenea, vom
cuta o latur (p,q) a lui L(i) pe care s o eliminm. Dac putem trasa segmentele (a,p) i
(b,q) (sau (a,q) i (b,p)), atunci trasm aceste segmente i unim P(i-1) cu L(i) (notnd
poligonul obinut cu P(i)).
La sfrit, dac |L(k)|3, procedm similar ca i n cazurile 2ik-1. Dac L(k)={x}, vom
cuta o latur (a,b) a lui P(k-1) pe care s o eliminm i pe care s o nlocuim cu segmentele
(a,x) i (b,x). Dac L(k)={x,y}, atunci vom cuta o latur (a,b) a lui P(k-1) pe care s o
nlocuim cu segmentele (a,x) i (y,b) (sau cu (a,y) i (x,b)), la care adugm segmentul (x,y).
Dac implementm algoritmul descris n mod direct, complexitatea sa este O(N3) (la
fiecare pas i considerm orice latur (a,b) din P(i-1) cu orice latur (p,q) din L(i) i verificm
dac se pot elimina, n timp O(N)). Complexitatea se poate reduce la O(N2) observnd c, la
fiecare pas i, putem alege orice latur (a,b) a lui P(i-1) care aparine i lui L(i-1). Astfel, la
fiecare pas, latura (a,b) este fixat mai nti i variem apoi doar latura (p,q) din L(i)). De
menionat c toate nfurtorile convexe pot fi calculate n timp O(N2) (fiind necesar doar o
singur sortare a punctelor, la nceput).
O soluie mult mai simpl, de complexitate O(Nlog(N)) este urmtoarea. Determinm
lanul inferior al nfurtorii convexe a celor N puncte. Lanul inferior conine cel mai din
stnga i cel mai din dreapta punct (pe care le denumim punctele A i B). Sortm apoi
cresctor, dup coordonata x (i, pentru x egal, descresctor dup coordonata y), punctele
care nu se afl pe lanul inferior calculat. La ordonarea obinut adugm punctul A la
nceput i punctul B la sfrit. Fie aceast ordonare extins p(1)(=A), p(2), ..., p(k)(=B). Vom
trasa segmentele (p(i), p(i+1)) (i=1,...,k-1). Poligonul obinut din lanul inferior al
nfurtorii convexe i din segmentele trasate dup aceea este poligonul dorit.
Problema 6-11. Cuplaj fr intersecii (Lotul Naional de Informatic, Romnia, 2000;
TIMUS)
Se dau N (3N1.000) puncte n plan, oricare trei necoliniare. Determinai un numr
maxim de segmente care unesc cte dou puncte dintre cele N date, astfel nct oricare dou
segmente nu se intersecteaz (i nici nu se ating ntr-un punct).
Soluie: O soluie de complexitate O(N2) este urmtoarea. Se determin nfurtoarea
convex a celor N puncte. Fie aceast nfurtoare CH(1). Dac ea conine un numr P par
de puncte, atunci alegem P/2 laturi ale lui CH(1), n mod alternativ (o latur da, apoi
urmtoarea nu). Dac ea conine un numr P impar de puncte, atunci eliminm ultimul punct
din CH(1) (i unim primul punct de penultimul), obinnd un polgon convex cu un numr Q
par de vrfuri. Pe acest poligon procedm ca i n cazul anterior (alegnd Q/2 laturi, oricare 2
neconsecutive pe conturul poligonului). Eliminm punctele astfel cuplate i repetm
procedeul pentru mulimea de puncte nc necuplate. Ne oprim doar atunci cnd rmnem cu
un singur punct sau cu 0 puncte. Astfel, se pot trasa (N/2) segmente (parte ntreag
inferioar), oriare dou neintersectndu-se n niciun punct.
O soluie mai simpl, de complexitate O(Nlog(N)) este urmtoarea. Sortm punctele
cresctor dup coordonata x (iar pentru puncte cu aceeai coordonat x, cresctor dup
coordonata y). Fie aceast ordonare p(1), p(2), ..., p(N). Vom trasa segmentele (p(2i-1),
p(2i)) (1iN/2). Se observ uor c aceste segmente nu se intersecteaz. Alternativ, putem
alege un punct (xo,yo) situat la stnga tuturor celor N puncte date, dup care vom sorta
punctele i n funcie de panta format de semidreapta (xo,yo)-(x(i),y(i)) i axa OX. Fie aceast
ordonare p(1), p(2), ..., p(N). Vom trasa segmentele n acelai mod ca i n soluia anterioar.

76

Problema 6-12. Cerc de raz minim ce conine puncte cu suma ponderilor cel puin
egal cu o valoare dat
Se dau N (3N1.000) puncte n plan. Fiecare punct i (1iN) se afl la coordonatele
(x(i),y(i)) i are o pondere w(i)0. Determinai un cerc de raz minim astfel nct suma
ponderilor punctelor din interiorul sau de pe conturul cercului s fie cel puin egal cu X.
Soluie: Vom cuta binar raza Rmin a cercului. Pentru fiecare raz R candidat, va trebui s
determinm suma maxim a ponderilor unei submulimi de puncte ce poate fi inclus ntr-un
cerc de raz R. Dac aceast valoare este mai mare sau egal cu X, vom cuta raze mai mici
n cutarea binar; altfel vom cuta raze mai mari.
Putem considera c cercul are pe conturul su unul din cele N puncte (dac nu, mutm
cercul pn cnd unul din punctele din interior ajunge pe contur). Vom considera fiecare
punct p drept punct pe conturul cercului i vom calcula suma maxim a ponderilor punctelor
ce pot fi incluse ntr-un cerc de raz R ce are punctul p pe contur. Vom considera toate
punctele ip i vom calcula pentru fiecare distana dist(i,p) dintre punctele i i p. Dac
dist(i,p)>2R, atunci vom ignora punctul i. Altfel, vom calcula dou unghiuri u1(i) i u2(i).
u1(i) i u2(i) sunt unghiurile fa de axa OX ale segmentului (p,C), unde C este centrul unui
cerc de raz R ce conine punctele p i i pe contur. Este clar c exist 2 astfel de unghiuri.
Dac considerm c centrul cercului de raz R se rotete n jurul punctului n sens
trigonometric, unul din cele 2 unghiuri corespunde cazului n care punctul i intr n cerc, iar
cellalt unghi corespunde cazului cnd punctul i iese din cerc. Vom seta u1(i) ca fiind
unghiul de intrare (unghiul mai mic) i u2(i) ca fiind unghiul de ieire (unghiul mai
mare). Fiecare punct i care nu a fost ignorat este acum echivalent cu 2 intervale disjuncte de
unghiuri [u1(i),u2(i)] i [u1(i)+2, u2(i)+2], care au fiecare o pondere w(i).
Va trebui s determinm o valoare u pentru care suma ponderilor intervalelor ce conin
valoarea u s fie maxim. Este uor de observat c u trebuie s fie unul din capetele celor
O(N) intervale. Vom sorta cele O(N) capete de intervale i apoi le vom parcurge de la stnga
la dreapta, meninnd o valoare WS, reprezentnd suma ponderilor intervalelor intersectate n
momentul curent (iniial, WS=0). Cnd ntlnim un capt stnga u1(i) (sau u1(i)+2)
corepunztor unui punct i, incrementm WS cu w(i); cnd ntlnim un capt dreapta u2(i) (sau
u2(i)+2), decrementm WS cu w(i).
Valoarea maxim pe care o atinge WS pe parcursul algoritmului (dup fiecare
incrementare sau decrementare) este suma maxim a ponderilor punctelor coninute ntr-un
cerc de raz R ce are punctul p pe contur. Pentru a rezolva problema faptului c intervalele
sunt circulare, vom considera c fiecrui punct i i corespund, de fapt, 2 intervale disjuncte:
[u1(i),u2(i)] i [u1(i)+2,u2(i)+2].
Pentru un punct p, problema se rezolv n timp O(Nlog(N)), algoritmul de calcul al
sumei maxime a ponderilor incluse ntr-un cerc de raz dat avnd complexitatea total de
O(N2log(N)). Pentru rezolvarea problemei iniiale se mai adaug la complexitate un factor
de O(log(RMAX)), corespunztor cutrii binare a razei minime (RMAX este valoarea
maxim a unei raze candidat posibile). Variante ale acestei probleme au fost propuse la
conrcursul de programare Bursele Agora i la Olimpiada de Informatic a Europei Centrale
(2006).

77

Problema 6-13. H (Happy Coding 2007, infoarena)


Se dau N (1N65535) segmente verticale, numerotate de la 1 la N. Un segment K este
caracterizat prin valorile X(K), Yjos(K) i Ysus(K). Coordonatele captului de jos al
segmentului K sunt (X(K),Yjos(K)), iar coordonatele captului de sus sunt (X(K),Ysus(K)).
Vrem s alegem dou dintre aceste segmente si s le tiem n aa fel nct ambele s
aib aceeai valoare pentru Yjos, respectiv pentru Ysus. Presupunnd c segmentele alese
sunt A i B, noua valoare a lui Yjos pentru fiecare din cele dou segmente va fi
YJ=max{Yjos(A),Yjos(B)}, iar noua valoare a lui Ysus pentru fiecare din cele dou segmente
va fi YS=min{Ysus(A),Ysus(B)}. Dac nu este adevarat relaia YJYS, atunci perechea de
segmente (A,B) nu este valid. Pentru o pereche valid de segmente (A,B), dup operaia de
tiere a segmentelor, se vor uni segmentele printr-un segment orizontal, pentru a forma o
figur care seamn foarte mult cu litera H. Segmentul orizontal va fi trasat intre
coordonatele (X(A),Y) si (X(B),Y), cu YJYYS (nu este important valoarea exact a
coordonatei Y a segmentului trasat). Dup obinerea literei H, se calculeaz lungimea
acesteia. Lungimea literei H este definit ca fiind suma celor 3 laturi ale literei: 2(YSYJ)+|XB-XA|.
Determinai o pereche valid de segmente pentru care lungimea literei H obinuite s
fie maxim.
Exemplu:
N=2
X(1)=0, Yjos(1)=0, Ysus(1)=10
X(2)=5, Yjos(2)=5, Ysus(2)=20
Lungimea maxim a unei litere H este 15.
Soluie: O prim soluie, de complexitate O(Nlog2(N)), este urmtoarea. Pentru fiecare
segment vertical (X1,Yj1,Ys1), vom dori s determinm un segment vertical din stnga sa
(X2,Yj2,Ys2), mpreun cu care formeaz o liter H de lungime maxim, n fiecare din
urmtoarele 4 cazuri (ce depind de pozitia celui de-al doilea segment fata de primul):
Yj1Ys2Ys1 i Yj2Yj1 : n acest caz, litera H va avea YJ=Yj1 i YS=Ys2
Yj2Yj1Ys1Ys2 : n acest caz, litera H va avea YJ=Yj1 i YS=Ys1
Yj1Yj2Ys2Ys1 : n acest caz, litera H va avea YJ=Yj2 i YS=Ys2
Yj1Yj2Ys1 i Ys1Ys2 : n acest caz, litera H va avea YJ=Yj2 i YS=Ys1
Constatm c, o dat ce am fixat unul din cele 4 cazuri, este foarte clar contribuia
fiecruia din cele 2 segmente la lungimea literei H:
cazul 1: contribuia segmentului 1 este L1=X1-2Yj1, iar cea a segmentului 2 este L2=X2+2Ys2
cazul 2: contribuia segmentului 1 este L1=X1+2(Ys1 - Yj1), iar cea a segmentului 2 este
L2=-X2
cazul 3: contribuia segmentului 1 este L1=X1, iar cea a segmentului 2 este L2=X2+2(Ys2-Yj2)
cazul 4: contribuia segmentului 1 este L1=X1+2Ys1, iar cea a segmentului 2 este L2=X2-2Yj2
n aceste condiii, pentru fiecare caz, putem privi fiecare segment ca un punct ntr-un alt
sistem de coordonate 2D, n care coordonata X corespunde lui Yjos, iar coordonata Y
corespunde lui Ysus. n plus, fiecare punct are asociat o pondere W. Pentru fiecare caz
construim cu toate cele N puncte un arbore de intervale 2D, care utilizeaz O(Nlog(N))
memorie. Acest arbore de intervale este, de fapt, un arbore de intervale obinuit pentru

78

coordonatele X, ns fiecare nod al arborelui menine un vector cu coordonatele Y ale


punctelor ce corespund intervalului nodului respectiv. n plus, pentru fiecare coordonat Y se
menine i ponderea asociat punctului.
Pentru fiecare caz C i fiecare segment vertical S, vom dori s gsim segmentul vertical
din stnga sa cu care poate forma o litera H de lungime maxim. Acest segment corespunde
unui punct ce se afl ntr-un dreptunghi ce corespunde constrngerilor pentru coordonatele
Yjos i Ysus corespunztoare cazului C i care are ponderea W maxim. Pentru fiecare caz,
interogrile pot fi astfel puse nct dreptunghiul [a,b]x[c,d] n care cutm punctul s aib
ori coordonat c egal cu -, ori coordonata d egal cu +. n aceste condiii, pentru fiecare
nod din arborele de intervale n care se ajunge prin spargerea segmentului [a,b], va trebui
s determinm ponderea maxim a unui punct care are coordonata Y printre primele z sau
printre ultimele z (unde z este determinat folosind cutare binar n fiecare nod al arborelui
de intervale al coordonatelor X n care ajungem). Din acest motiv, putem s meninem pentru
fiecare nod un vector wmax[z] cu ponderea maxim a unui punct dintre primele z puncte ce
corespund intervalului nodului, precum i un vector similar ce corespunde ultimelor z puncte
ale intervalului; dac unul dintre capetele c sau d nu era egal cu +/-, atunci trebuia s
folosim RMQ (Range Minimum Query) pentru fiecare nod din arbore.
Observm c, n modul n care am pus interogrile, nu am specificat nicieri c punctul
cu pondere maxim trebuie s corespund unui segment aflat n stnga segmentului pentru
care facem interogarea. Totui, dac punctul cu pondere maxim obinut nu corespunde unui
segment aflat n stnga segmentului curent, atunci vom obine n mod sigur o liter H de
lungime mai mare n momentul n care vom efectua interogarea pentru segmentul
corespunztor punctului obinut (acest lucru se datoreaz modului n care sunt definite
ponderile). Mai trebuie s avem grij ca, atunci cnd realizm interogarea, punctul de
pondere maxim s nu corespund chiar segmentului pentru care facem interogarea (ceea ce
se poate ntmpla, ntruct nu am impus nicio condiie pentru a evita aceast situaie). Pentru
a evita acest lucru, o posibilitate este s folosim nite limite ale dreptunghiului de interogare
care s excluda punctele ce corespund unor segmente ce au exact acelai Yjos i acelai Ysus
ca i segmentul curent. n felul acesta, ns, ajungem s nu lum n considerare H-uri formate
din 2 segmente care au acelai Yjos i acelasi Ysus (dar coordonate X diferite). Acest caz
trebuie tratat separat, printr-o simpl sortare (nti dup Yjos, apoi dup Ysus i apoi dup X)
i parcurgere a segmentelor (segmentele avnd acelai Yjos i Ysus aflndu-se unul dup altul
n ordinea sortat). Complexitatea acestei solutii este O(Nlog2(N)) i folosete memorie
O(Nlog(N)).
Soluia prezentat poate fi optimizat la complexitate O(Nlog(N)), folosind o tehnic
standard. Orice query corespunztor unui arbore de intervale 2D poate fi redus de la o
complexitate O(log2(N)) la o complexitate O(log(N)). Practic, se va efectua o cutare binar a
coordonatei Y inferioare i superioare numai n cadrul rdcinii arborelui de intervale. Apoi,
din construcia arborelui, vom memora pentru fiecare punct P al fiecrui nod, 4 pointeri:
(1) un pointer ctre punctul cu cea mai mic coordonat Y mai mare sau egal cu cea a
punctului P i care se afl n intervalul de coordonate X al fiului stnga ;
(2) un pointer ctre punctul cu cea mai mic coordonat Y mai mare sau egal cu cea a
punctului P i care se afl n intervalul de coordonate X al fiului dreapta ;
(3) un pointer ctre punctul cu cea mai mare coordonat Y mai mic sau egal cu cea a
punctului P i care se afl n intervalul de coordonate X al fiului stnga ;
(4) un pointer ctre punctul cu cea mai mare coordonat Y mai mic sau egal cu cea a
punctului P i care se afl n intervalul de coordonate X al fiului dreapta.

79

O parte din aceti pointeri pot fi calculai n momentul n care, n faza de construcie a
arborelui de intervale 2D, se interclaseaz coordonatele Y corespunztoare fiului stnga i
fiului dreapta. Cealalt parte a pointer-ilor se calculeaz realiznd nc 2 parcurgeri ale
coordonatelor Y sortate, una de la stnga la dreapta i alta de la dreapta la stnga (n
condiiile n care am memorat pentru fiecare coordonat Y de la care din cei doi fii provine).
O alternativ la folosirea arborelui de intervale 2D este folosirea unei structuri de date 2D
numit kd-tree, care poate oferi aceleai operaii ca i un arbore de intervale 2D. Diferena
const n cantitatea de memorie folosit (O(N), n loc de O(Nlog(N))), dar si n
complexitatea cutarii n interiorul unui dreptunghi (O(sqrt(N)), n loc de O(log2(N)) sau
O(log(N)) cu optimizarea menionat). Acest arbore memoreaz, pentru fiecare nod al su x,
ponderea maxim a unui punct din subarborele lui x.
Problema 6-14. Regiuni (infoarena)
Se dau N hiper-plane i M puncte ntr-un spaiu d-dimensional (1N,M1.000). Un
hiperplan are d-1 dimensiuni; de ex., pentru d=3, un hiperplan este un plan n spaiu, iar
pentru d=2, un hiperplan este o dreapt. Niciun punct nu se afl pe vreun hiperplan.
Hiperplanele mpart planul n regiuni. Spunem c 2 puncte sunt n aceeai regiune dac nu
exist vreun hiperplan care s le despart. Se cere s afiai numrul de grupuri de puncte,
fiecare grup coninnd toate punctele din aceeai regiune.
Soluie: Vom rezolva problema incremental, adugnd pe rnd cte un hiperplan i
meninnd informaia despre grupuri. Cnd adugm un hiperplan iterm peste toate
grupurile. Un grup va fi mprit n alte dou: punctele din stnga hiperplanului i punctele
din dreapta lui; e posibil ca unul din aceste dou grupuri s fie vid, caz n care nu l mai
reinem. Un grup i l mprim n dou n O(x(i)) operaii, unde x(i) este numrul de elemente
din grup. Toate grupurile vor avea n total x(1)+x(2)+...+x(i)+...=M elemente, deci pentru a
actualiza grupurile adugnd un hiperplan efectum O(M) operaii. Astfel, soluia are
complexitatea final O(NM).
Alt soluie ar consta n determinarea pentru fiecare punct i a unui vector v(i) cu N
elemente, unde v(i,j)=+1 sau -1 (n funcie de semispaiul n care se afl punctul i fa de
hiperplanul j). Dac doi astfel de vectori asociai la dou puncte sunt egali, atunci cele dou
puncte sunt situate n aceeai regiune. Pentru determinarea egalitii vectorilor s-ar putea
folosi o sortare naiv, obinnd o complexitate de O(MNlog(M)), sau radix sort, pentru o
complexitate de O(MN).
Alt variant const n introducerea acestor vectori ntr-un trie. Numrul de noduri
terminale (frunze) ale trie-ului va reprezenta numrul de regiuni. Aceste soluii folosesc
O(MN) memorie. O alt soluie ar fi s obinem un cod hash pentru fiecare vector; aceast
soluie are complexitatea O(MN) ca timp i O(M+N) memorie. Pentru a face ca
probabilitatea de coliziune s fie ct mai mic putem folosi cte K2 coduri diferite pentru
fiecare vector.
Alt observaie ar fi c vectorii sunt binari i pstrnd informaia pe bii folosim mai
puin memorie i avem mult mai puine operaii la comparare dac vrem s folosim soluia
n O(MNlog(M)).
Problema 6-15. Scri ncruciate (UVA)
De o parte i de alta a unei strzi se afl 2 cldiri foarte nalte. De aceste 2 cldiri se afl
rezemate dou scri. Prima scar are lungime x i are baza la nivelul strzii, atingnd cldirea

80

din dreapta, i vrful este rezemat de cldirea din stnga. A doua scar are nlimea y i are
baza la nivelul strzii, atingnd cldirea din stnga, iar vrful este rezemat de cldirea din
dreapta. Intersecia celor 2 scri este la nlimea c. Aflai limea strzii.

Exemplu: x=30, y=40, c=10 => limea strzii este 26.033.


Soluie: Vom cuta binar limea d a strzii. Se observ c pe msur ce limea strzii crete,
nlimea punctului de intersecie scade; i invers, pe msur ce limea strzii scade,
nlimea punctului de intersecie crete. Astfel, pentru o valoare fixat d, vom calcula
h(d)=nlimea punctului de intersecie, dac strada are limea d. Dac h(d)<c, atunci d este
prea mare i vom testa n continuare o valoare mai mic. Dac h(d)>c, atunci d este prea mic
i vom testa n continuare o valoare mai mare.
Pentru a calcula h(d) vom proceda dup cum urmeaz. Vom calcula lx i ly, nlimile
(verticale) ale celor dou scri: lx=sqrt(x2-d2) i ly=sqrt(y2-d2). Fie P proiecia punctului de
intersecie pe strad i fie ld distana de la captul din stnga al strzii pn la P. Din regulile
de asemnare a triunghiurilor, avem: h(d)/ly=ld/d i h(d)/lx=(d-ld)/d=1-ld/d. nlocuind,
obinem h(d)/lx=1-h(d)/ly => h(d)= lxly/(lx+ly).
Problema 6-16. Butoi cu ap (Olimpiada Baltic de Informatic 2003)
Avem un butoi cu ap de forma unui paraleliliped cu nlime HP i aria bazei SP. n
acest butoi se toarn, iniial, ap pn la nlimea HQ. Apoi se introduc n ap N
(0N100.000) paralelipipede. Paralelipipedul i are nlimea H(i) (0.01H(i)HP), aria
bazei S(i) i densitate D(i). Densitatea apei este DA. Cele N paralelipipede nu se ating, iar
suma ariilor bazelor lor nu depete SP. Dup aceasta, n partea de sus a butoiului se pune
un capac, care mpinge toate paralelipipedele care aveau partea de sus peste nlimea H n
interiorul butoiului. Determinai nivelul apei din butoi dup punerea capacului. Dac apa se
revars n afara butoiului, menionai acest lucru.

Soluie: Dac un paralelipiped i are densitatea D(i), nseamn c, n starea de echilibru,


HA(i)S(i)DA=(H(i)-HA(i))S(i)D(i), unde HA(i) este nalimea paralelipipedului care se afl

81

n
interiorul
apei.
Astfel,
obinem
HA(i)(DA+D(i))=H(i)D(i)
=>
HA(i)=H(i)D(i)/(DA+D(i)). Dac nivelul curent HQ al apei este HQHA(i) i HQHP(H(i)-HA(i)), atunci paralelipedul i este n echilibru. Dac nivelul curent HQ al apei este
HQ<HA(i), vom spune c paralelipipedul i se afl n starea -1; dac HA(i)HQHPH(i)+HA(i) vom spune c se afl n starea 0; dac HQ>HP-H(i)+HA(i), vom spune c se afl
n starea 1.
Vom considera c paralelipipedele se introduc pe rnd (de la paralelipipedul 1 la N).
Dup introducerea fiecrui paralelipiped vom calcula noul nivel al apei din butoi. Vom
menine un min-heap cu evenimente: un eveniment este de forma (nalime ap,
paralelipiped, stare) i se declaneaz atunci cnd nivelul apei ajunge sau depete
nlimea specificat n cadrul evenimentului. Vom menine, de asemenea, o valoarea SA ce
reprezint suma ariilor bazelor paralelipipedelor care se afl n strile -1 sau 1. Iniial SA=0
i heap-ul este gol.
S presupunem c am ajuns la paralelipipedul i (1iN) i nivelul curent al apei este HQ.
Mai nti calculm HA(i). Dac HQ<HA(i), vom introduce n heap evenimentul (HA(i), i, -1)
i vom incrementa SA cu S(i); apoi vom seta o variabil Vol=VA(i)=HQS(i). Dac
HA(i)HQHP-H(i)+HA(i), atunci vom aduga n heap evenimentul (HP-H(i)+HA(i), i, 0) i
vom seta Vol=VA(i)=HA(i)S(i). Dac HQ>HP-H(i)+HA(i), vom incrementa SA cu S(i) i
vom seta Vol=VA(i)=(HQ-(HP-H(i)+HA(i))+HA(i))S(i)=(HQ-HP+H(i))S(i). VA(i)
reprezint volumul din paralelipedul i care se afl n ap. Volumul din butoi ocupat de ap i
pri ale paralelipedelor aflate n ap este HQSP. Vol reprezint cu ct trebuie s creasc
acest volum, deoarece a crescut volumul prilor cuburilor care se afl scufundate n ap.
Aadar, n continuare, ct timp Vol>0, vom efectua urmtorii pai:
(1) Vom calcula HQ=HQ+Vol/(SP-SA) (dac SP=SA, setm HQ=+).
(2) Dac heap-ul conine cel puin un eveniment, atunci fie E=(HE, j, s) evenimentul cu
nlimea minim (evenimentele sunt ordonate n heap dup aceast nlime).
(2.1) Dac HEHQ atunci setm HQ=HE. HQ va fi noul nivel al apei din butoi.
(2.2) Dac HQ>HP, atunci apa se revars din butoi i ntrerupem algoritmul. Altfel, vom
decrementa Vol cu (HQ-HQ)(SP-SA), iar apoi vom seta HQ=HQ.
(3) Ct timp heap-ul nu este gol i cel mai mic eveniment din heap este E=(HE=HQ, j, s),
vom extrage evenimentul E din heap i vom efectua urmtoarele aciuni:
(3.1) dac s=-1 atunci decrementm SA cu S(j) i introducem n heap evenimentul (HPH(j)+HA(j), j, 0);
(3.2) dac s=0 atunci incrementm SA cu S(j).
(4) Dup aceste aciuni revenim la nceputul ciclului care verific dac Vol>0.
Nivelul final al apei din butoi va fi HQ. Observm c algoritmul are complexitatea
O(Nlog(N)), deoarece se parcurg N paralelipipede i se trateaz cel mult 2N evenimente din
heap (n complexitate O(log(N)) pentru fiecare).
Problema 6-17. Puncte (Olimpiada Internaional de Informatic 2006)
Se dau N+4 puncte n plan (0N50.000). Fiecare punct i (1iN+4) are o culoare C(i),
care poate fi rou sau verde. Patru dintre puncte (numerotate cu N+1, ..., N+4) sunt colurile
unui dreptunghi: (0,0), (0,YMAX), (XMAX,YMAX) i (XMAX,0). Primele 2 puncte ((0,0) i
(0,YMAX)) au culoarea roie, iar celelalte dou au culoarea verde.
Dorim s determinm un arbore parial de acoperire T(R) al punctelor roii i un arbore
parial de acoperire al punctelor verzi T(V), astfel nct segmentele care formeaz cei 2 arbori

82

s nu se intersecteze. Dac 2 puncte de aceeai culoare u i v sunt adiacente n arborel parial


corespunztor, atunci se traseaz segmentul u-v.
Se tie c oricare 3 puncte dintre cele N+4 sunt necolineare.
Soluie: Vom ncepe prin a mpri dreptunghiul format din ultimele 4 puncte n dou
triunghiuri, prin trasarea unei diagonale. Fiecare dintre aceste 2 triunghiuri conine 2 vrfuri
de aceeai culoare i un vrf de cealalt culoare. Fie S(a,b,c) mulimea punctelor incluse n
triunghiul cu vrfurile n punctele a, b i c. Vom aplica urmtorul algoritm fiecruia din cele
2 triunghiuri (pentru care determinm, n timp O(N), mulimile S(N+1, N+2, N+4) i S(N+2,
N+3, N+4)).
S considerm c tratm triunghiul cu vrfurile n punctele a, b i c, pentru care am
calculat deja S(a,b,c). S presupunem, de asemenea, c vrfurile a i b au aceeai culoare P,
iar vrful c are cealalt culoare, Q. Vom aduga muchia a-b la arborele parial de acoperire
T(P) (dac nu a fost adugat deja). Dac toate punctele din S(a,b,c) au culoarea P, atunci
vom uni fiecare astfel de punct u cu unul din punctele a sau b (adugnd muchia u-a sau u-b
la T(P)). Dac exist cel puin un punct v de culoarea Q n triunghiul (a,b,c), atunci vom uni
acest punct cu punctul c (adugnd muchia v-c la arborele parial de acoperire T(Q)). Apoi
vom construi triunghiurile (a,b,v), (a,v,c) i (b,v,c). Fiecare astfel de triunghi are 2 vrfuri de
aceeai culoare (a i b; v i c; v i c) i cellalt de culoare diferit. Vom determina S(a,b,v),
S(a,v,c) i S(b,v,c) dintre punctele din (S(a,b,c)\{v}) (ntr-un timp proporional cu
O(|S(a,b,c)|)). Apoi vom aplica recursiv algoritmul pentru fiecare cele trei triunghiuri
construite: (a,b,v), (a,v,c) i (b,v,c).
Cnd algoritmul se termin avem cei doi arbori pariali T(R) i T(V) gata construii, iar
muchiile lor nu se intersecteaz. Algoritmul are complexitatea O(N2) n cel mai ru caz. Dac
am alege vrful v din interiorul unui triunghi (a,b,c) astfel nct cardinalele mulimilor
S(a,b,v), S(a,v,c) i S(b,v,c) s fie echilibrate, atunci am ajunge la o complexitate de ordinul
O(Nlog(N)). n practic, putem folosi doar nite euristici. Putem alege punctul v aleator
dintre toate punctele v din triunghiul (a,b,c) care au culoarea Q. Sau, dintre aceste puncte, l
putem alege pe cel care este cel mai aproape de: (1) centrul de greutate al triunghiului (care
are drept coordonate mediile aritmetice ale coordonatelor x i, respectiv, y, ale punctelor a, b
i c) ; sau (2) intersecia mediatoarelor celor 3 laturi ale triunghiului ; sau (3) intersecia
medianelor celor 3 laturi ale triunghiului; sau (4) intersecia nlimilor celor 3 laturi ale
triunghiului.
Problema 6-18. A K-a diagonal a unui poligon convex
Se d un poligon convex cu N (4N100.000) vrfuri. Considernd toate diagonalele sale
sortate dup lungime, determinai lungimea celei de-a K-a diagonale (1KN(N-3)/2).
Soluie: Vom determina pentru fiecare vrf i (0iN-1) al poligonului vrful Far(i) care se
afl la cea mai mare distan fa de i. Pentru aceasta, avem 2 posibiliti. Observm c, dac
am parcurge vrfurile poligonului ncepnd de la vrful urmtor lui i i am merge circular
pn la vrful dinaintea lui i, lungimea segmentelor de la i la fiecare vrf crete, dup care
scade. Vom considera funcia dist(i, j)=distana dintre vrfurile numerotate cu i i j. Pentru
fiecare vrf i, definim funcia di(j)=dist(i, (i+j) mod N) (j=1,...,N-1). Funcia di este
unimodal, adic este cresctoare (descresctoare) pn la un maxim (minim), dup care este
descresctoare (cresctoare). Pentru a gsi punctul ei de maxim, putem folosi cutare binar
pe derivata funciei. Dac di(j)-di(j-1)0, atunci considerm c suntem nc n partea

83

cresctoare a funciei; dac di(j)-di(j-1)<0, atunci ne aflm n partea descresctoare a ei; n


felul acesta, putem determina cel mai mare indice jmax, pentru care di(jmax)-di(jmax-1)0
(1jmaxN-1; considerm di(0)=0). Vom seta Far(i)=(i+jmax) mod N.
O alt modalitate de a determina indicele jmax este folosirea unei cutri ternare. S
presupunem c, n cadrul cutrii, am decis c jmax se afl n intervalul [a,b] (iniial,
[a,b]=[1,N-1]). Vom calcula valorile di((a+b)/3) i di(2(a+b)/3). Dac di(2(a+b)/3)
di((a+b)/3), atunci vom pstra, n continuare, intervalul [a,b]=[(a+b)/3, b]. Dac
di(2(a+b)/3)<di((a+b)/3), atunci vom pstra, n continuare, intervalul [a,b]=[a,
2(a+b)/3].
Putem calcula valorile Far(i) i n timp total O(N). Vom considera valoarea virtual Far(1)=0. Vom considera apoi toate vrfurile 0iN-1 (n ordine cresctoare). Pentru a calcula
Far(i), vom porni cu un indice z=Far(i-1) i, atta timp ct ct dist(i,z)-dist(i, (z+1) mod
N)0 i (z(i-1+N) mod N), l vom incrementa pe z cu 1 (modulo N). Atunci cnd ieim din
ciclu, setm Far(i)=z. Observm c indicele z este incrementat, per total (pentru toate
vrfurile), de O(N) ori.
Dac K=N(N-1)/2, atunci lungimea diagonalei cutate este max{dist(i, Far(i))}. Pentru
alte valori ale lui K, vom cuta binar lungimea dorit. Fie L lungimea selectat n cadrul
cutrii binare i fie LK lungimea dorit (necunoscut). Vom calcula numrul Q(L) de
diagonale care au lungimea mai mic sau egal cu L. Dac Q(L)K, atunci LLK; dac
Q(L)<K, atunci L<LK. Vom determina, astfel, cea mai mic lungime L pentru care Q(L)K.
Pentru a calcula Q(L), vom considera, pe rnd, fiecare vrf i (0iN-1) i vom calcula
ND(i,L)=numrul de diagonale care au un capt n i i lungimea mai mic sau egal cu L.
Pentru aceasta, vom cuta binar cel mai mare indice jmax1, ntre 0 i ((Far(i)-i+N) mod N)
pentru care di(jmax1)L. Apoi vom cuta binar cel mai mare indice jmax2 ntre 0 i ((iFar(i)+N) mod N) pentru care di(N-jmax2)L (considerm di(N)=0). Vom seta apoi
ND(i,L)=jmax1+jmax2. Q(L) este egal cu (ND(0,L)+...+ND(i,L)+...+ND(N-1,L))/2 (deoarece
fiecare diagonal i-j cu lungime mai mic sau egal cu L, este numrat att n ND(i,L), ct i
n ND(j,L)).
Complexitatea ntregului algoritm este dominat de partea de cutare binar a lungimii
celei de-a K-a diagonale, fiind de ordinul O(Nlog(N)log(LMAX)) (unde LMAX este
lungimea maxim posibil a unei diagonale). ntruct lungimile diagonalelor sunt numere
reale, cutarea binar a lungimii se va termina cnd intervalul de cutare are o lungime mai
mic dect o constant foarte mic, stabilit n prealabil.
Problema 6-19. Numrarea ptratelor
Se dau N (4N3.000) puncte (distincte) n plan. Punctul i (1iN) are coordonatele (x(i),
y(i)) Determinai cte ptrate cu laturile paralele i cu vrfurile n 4 din cele N puncte date
exist.
Soluie: Vom considera fiecare pereche de puncte (i,j) i vom verifica dac formeaz
colurile opuse ale unui ptrat. Dac |x(i)-x(j)|=|y(i)-y(j)|, atunci exist ansa ca ele s fie
colurile opuse ale unui ptrat. Mai trebuie doar s verificm dac exist i celelalte 2 puncte
(celalte 2 coluri opuse) printre cele N puncte date. Cel mai uor ar fi s verificm dac
punctele (min{x(i), x(j)}, min{y(i), y(j)}), (min{x(i), x(j)}, max{y(i), y(j)}), (max{x(i), x(j)},
min{y(i), y(j)}), (max{x(i), x(j)}, max{y(i), y(j)}) exist printre cele N. Dac toate aceste 4
puncte exist, atunci incrementm un contor NP cu 1 (iniial, NP=0). Valoarea final a lui
NP este numrul de ptrate cutat.

84

Pentru a verifica dac un punct (a,b) exist n mulimea noastr de puncte, putem sorta
toate cele N puncte (cresctor dup x i, n caz de egalitate, cresctor dup y). Apoi, putem
cuta binar punctul (a,b) n vectorul de puncte sortate. O soluie de complexitate mai bun ar
fi s folosim un hash, n care introducem toate punctele (x(i), y(i)). Apoi ar trebui doar s
verificm dac o pereche (a,b) exist n hash, verificare ce poate fi realizat n timp O(1).
Complexitatea ntregului algoritm este O(N2log(N)) (dac folosim cutare binar) sau
O(N2) (dac folosim hash-ul).
Algoritmul poate fi extins pentru a calcula numrul de ptrate avnd orice orientare. Cnd
se consider o pereche de puncte (i,j), ne gndim c acestea ar putea reprezenta una dintre
diagonalele unui ptrat. n acest caz, calculm coordonatele celorlalte dou vrfuri ale
ptratului i verificm dac acestea se afl printre cele N puncte date. Complexitatea soluiei
rmne neschimbat.
Problema 6-20. Cutii (infoarena)
Se dau N (1N3.500) cutii d-dimensionale (1d5). Fiecare cutie i (1iN) are
dimensiunile (l(i,1), , l(i,d)) i o pondere w(i). Dimensiunile celor N cutii n fiecare
dimensiune j reprezint o permutare a numerelor {1,...,N}. Dorim s determinm o secven
de cutii cu suma maxim a ponderilor, a(1), ..., a(K), astfel nct cutia a(i+1) s poat fi
introdus n cutia a(i) (1iK-1). Cutia a(i+1) poate fi introdus n cutia a(i) dac exist o
permutare p a dimensiunilor sale, astfel nct l(a(i),j)>l(a(i+1),p(j)) (pentru fiecare 1jd).
Soluie: Vom genera un ir S ce conine M=Nd! cutii. Fiecare cutie este introdus n ir de
d! ori, cte o dat pentru fiecare permutare a dimensiunilor sale (dimensiunile asociate
fiecrei apariii a ei fiind permutate corespunztor). Fiecare apariie a unei cutii i n S are
ponderea w(i). Problema cere acum determinarea unei secvene a(i), ..., a(K), de sum
maxim a ponderilor, astfel nct l(a(i),j)>l(a(i+1),j) (1iK-1; 1jd). Observm c dei o
cutie i apare de d! ori, nicio apariie a cutiei i nu va putea fi introdus ntr-o alt apariie a
aceleiai cutii.
Vom sorta cutiile dup prima dimensiune, astfel nct s avem l(S(1),1)l(S(M),1). De
asemenea, vom construi un arbore multi-dimensional (range tree sau kd-tree) peste toate cele
M cutii, considernd doar dimensiunile 2,...,d. Fiecrei (apariii a unei) cutii i (1iM) i se
asociaz un punct p(i)=(l(i,2), ..., l(i,d)), care are iniial ponderea wp(i)=-. Cu ajutorul
arborelui vom putea determina n mod eficient cea mai mare pondere a unui punct din cadrul
unui dreptunghi multidimensional R (n timp O(logd-1(M)) pentru range tree, sau O(M1-1/d)
pentru kd-tree). Fiecare nod al arborelui va menine ponderea maxim asociat unui punct
din subarborele su i are asociat un interval multidimensional. Cnd se ajunge la un nod din
arbore care este coninut n R, se ntoarce valoarea memorat n acel nod.
Vom parcurge apoi cutiile n ordinea sortat. Cnd ajungem la o cutie i, vom determina
ponderea maxim a unui punct din arbore care are coordonatele (x(2), ..., x(d)) n intervalul
l(i,j)<x(j)N (1jd). Fie aceast pondere wmax (dac nu se gsete niciun punct n
intervalul multidimensional, se ntoarce wmax=-). Setm wp(i)=w(i)+max{0, wmax} i
modificm valoarea wp(i) asociat punctului i din arbore: pornim de la punct (care se afl
ntr-o frunz a arborelui) i mergem n sus, actualiznd valorile meninute n fiecare nod al
arborelui (valoarea maxim dintre toate punctele din subarbore) ; cum ponderile asociate
punctelor pot doar s creasc, actualizarea unei valori v se face setnd v=max{v, wp(i)}.
Rspunsul la problem este max{wp(i)|1iM}.

85

Problema 6-21. Grsanul 1


Se d un coridor 2D de lungime infinit i nlime H. n interiorul acestui coridor se
gsesc N puncte: punctul i la coordonatele (x(i), y(i)). Un grsan (avnd forma unui cerc)
se afl n interiorul coridorului la coordonata x=- i vrea s ajung la coordonata x=+.
Determinai raza maxim pe care o poate avea grsanul, astfel nct acesta s se poat
deplasa din poziia iniial n poziia final fr ca vreun punct s intre n interiorul acestuia.
Soluie: Vom cuta binar raza R a grsanului, n intervalul [0,H/2]. Pentru o raz R fixat,
vom verifica dac grsanul poate trece printre puncte cu raza respectiv. Vom asocia
fiecrui punct i un cerc de coordonate (x(i), y(i)) i raz R. Vom construi un graf ce va
conine N+2 noduri, corespunztoare celor N cercuri i a pereilor de sus i de jos ai
cordidorului. ntre 2 cercuri avem muchie dac acestea se intersecteaz. Peretele de sus este
mutat cu R uniti n jos, iar cel de jos este mutat cu R uniti n sus. Avem muchie ntre un
perete i un cerc dac cercul intersecteaz peretele (considernd poziia mutat a peretului).
Vom verifica apoi dac nodurile corespunztoare celor 2 perei sunt n aceeai component
conex a grafului construit. Dac da, atunci raza R este prea mare i va trebui s cutm o
raz mai mic; dac nu, raza R este fezabil i vom testa n continuare raze mai mari.
Complexitatea acestei soluii este O(N2log(RMAX)), unde RMAX este lungimea intervalului
n care are loc cutarea razei.
Un algoritm de complexitate mai bun este urmtorul. Construim graful complet ce
conine N+2 noduri: cele N puncte i cei 2 perei. ntre oricare 2 puncte ducem o muchie
avnd costul egal cu jumtatea distanei dintre puncte. ntre orice punct i fiecare din cei 2
perei ducem o muchie egal cu jumtatea distanei de la punct la perete (jumtate din
lungimea perpendicularei de la punct la perete). Costul muchie dintre cei 2 perei este egal cu
jumtatea distanei dintre ei. Acum vom calcula un drum de la peretele de jos la cel de sus, n
care costul maxim al unei muchii este minim posibil (adic este cel mai mic dintre toate
drumurile). Acest drum se poate determina n timp O(N2) (modificnd uor algoritmul lui
Dijkstra). Costul maxim al unei muchii de pe acest drum este egal chiar cu raza maxim a
grsanului.
Problema poate fi generalizat la cazul n care grsanul nu este un cerc, ci un poligon
convex oarecare, pentru care vrem s determinm factorul de scalare maxim relativ la un
punct din interiorul poligonului (de ex., centrul acestuia). De asemenea, coridorul poate
consta din mai multe segmente, nu doar din 2 perei (de ex., din 2 linii poligonale). Putem
cuta binar factorul maxim de scalare F. Construim apoi cte un poligon convex identic ca
cel al grsanului, scalat cu factorul F, n jurul fiecrui punct. Apoi construim acelai graf ca
i mai nainte: dac poligoanele a 2 puncte se intersecteaz, ducem muchie ntre aceste 2
puncte. Segmentele ce formeaz cele 2 linii poligonale ce delimiteax coridorul trebuie i ele
ngroate cu forma poligonului convex, folosind o tehnic ce se numete suma
Minkovski.
Cel mai simplu caz este cnd robotul este un ptrat iar segmentele liniilor poligonale sunt
ortogonale: segmentele se vor translata cu o distan corespunzoare factorului de scalare, n
aa fel nct s micoreze grosimea coridorului; capetele segmentelor vor fi translatate pe
diagonala ptratului, iar apoi vor fi unite de segmentele translatate (n aa fel, unele segment
pot crete sau scdea n lungime). Apoi, dac cel puin un segment al lanului poligonal i
(i=1,2) intersecteaz poligonul corespunztor unui punct j, ducem muchie de la nodul
corespunztor lanului poligonal i la nodul corespunztor punctului j. Dac exist un drum n

86

graf ntre cele 2 lanuri poligonale, atunci grsanul nu poate trece de la un capt la cellalt al
coridorului, factorul de scalare F fiind prea mare.
i a doua metod, bazat pe determinarea unui drum minim, poate fi generalizat n acest
caz. ntre 2 puncte i i j ducem o muchie de cost F, unde F este factorul de scalare minim
pentru care poligoanele construite n jurul punctelor i i j s-ar intersecta. Apoi, s considerm
un lan poligonal i (i=1,2). Vom considera toate segmentele q ce compun lanul poligonal i
fiecare punct j. Vom calcula F(i,q,j)=factorul de scalare minim pentru care poligonul
construit n jurul punctului j ar intersecta segmentul q al lanului i, dac acesta ar fi
modificat conform factorului de scalare. Costul muchiei ntre lanul i i punctul j este
min{F(i,q,j)}.
Problema 6-22. Numrul de intersecii ale unor segmente pe cerc
Se d un cerc de raz R, cu centrul n origine. Se dau, de asemenea, N segmente, avnd
ambele capete pe circumferina cercului. Determinai numrul de intersecii ntre segmente.
Soluie: Alegem 2 puncte diferite A i B pe circumferina cercului i mprim circumferina
n 2 pri: partea de la A la B, i partea de la B la A. Cele N segmente se mpart n 3 categorii:
1) cele care au ambele capete n partea de la A la B ;
2) cele care au ambele capete n partea de la B la A ;
3) cele care un capt n partea de la A la B i cellalt capt n partea de la B la A.
Segmentele din categoriile 1) i 2) sunt tratate foarte simplu (fiecare caz n mod
independent). Vom considera c ntindem fiecare din cele 2 pri, pn cnd acestea ajung
nite segmente orizontale (de lungime egal cu partea respectiv din circumferin). Dup
aceast ntindere, fiecare segment a devenit un interval pe partea respesctiv (putem obine
acelai rezultat dac asociem fiecrui capt al unui segment o coordonat x egal cu distana
de la nceputul prii din circumferin pn la captul respectiv; distana este calculat de-a
lungul circumferinei). Problema s-a redus acum la determinarea numrului de perechi de
intervale care se intersecteaz.
Vom sorta capetele stnga i dreapta ale intervalelor. Vom parcurge apoi aceste capete n
ordinea sortat, meninnd un contor nopen i un contor nint (ambele sunt iniial 0). La
fiecare capt stnga ntlnit incrementm nopen cu 1. Cnd ntlnim un capt dreapta
incrementm nint cu (nopen-1), dup care decrementm nopen cu 1. Pentru segmentele din
categoria 3 vom proceda dup cum urmeaz. Vom sorta aceste segmente n funcie de
distana captului lor din partea de la A la B fa de punctul A (distana e msurat pe
circumferina cercului, n sensul de la A pn la captul segmentului). Vom sorta apoi aceste
segmente dup distana calculat i le vom asocia numere de la 1 la M (M=numrul de
segmente din categoria 3). Vom calcula apoi distana captului de pe partea de la B la A, tot
fa de punctul A, msurat pe circumferina cercului, n sensul de la punctul A pn la
captul respectiv. Vom sorta apoi segmentele dup aceast a doua distan calculat. n acest
fel am obinut o permutare a numerelor de la 1 la M (considernd numerele asociate la prima
sortare, n ordinea de la a doua sortare). Numrul de intersecii ntre segmentele din categoria
3 este egal cu numrul de inversiuni ale acestei permutri. Aadar, numrul total de
intersecii ntre N segmente avnd capetele pe circumferina unui cerc se poate calcula n
timp O(Nlog(N)).
Problema poate fi extins dup cum urmeaz. Considerm un poligon convex cu S laturi
i N segmente avnd capetele pe perimetrul poligonului. Dorim s determinm numrul de
intersecii dinre segmente. Vom proceda la fel ca n cazul cercului, mprind conturul

87

poligonului n 2 pri, n funcie de 2 puncte A i B. Diferena const n faptul c acum


distanele se vor calcula de-a lungul conturului poligonului, i nu de-a lungul circumferinei
unui cerc. Pentru simplitate vom alege A i B ca fiind 2 vrfuri consecutive ale poligonului
(de ex., vrfurile B=1 i A=2). Vom considera c partea de la A la B este cea ce conine
laturile 2-3, ..., (N-1)-N, N-1. Vom calcula distanele d(i)=d(i-1)+lungimea laturii (i-1)-i,
pentru fiecare vrf al poligonului (d(2)=0 i d(1)=d(N)+lungimea laturii N-1). Pentru a
calcula distana de la un punct de pe latura 1-2 la vrful A, calculm direct distana
Euclidean. Pentru a calcula distana de la un punct aflat pe latura i-(i+1) (inclusiv latura N1) la vrful A, calculm distana euclidean la vrful i, la care adugm valoarea d(i).
Problema poate fi extins i la alte tipuri de curbe nchise i convexe.
Problema 6-23. Triunghiuri de arie numr ntreg
Se dau N (1N100.000) puncte n plan, aflate la coordonate ntregi (x(i), y(i)) (1iN).
Determinai numrul de triunghiuri cu vrfurile n 3 puncte diferite dintre cele N puncte, a
cror arie este un numr ntreg.
Soluie: S presupunem c am ales 3 puncte distincte, a, b i c. Fie S(a,b,c)=|x(a)y(b)x(b)y(a)+x(b)y(c)-x(c)y(b)+x(c)y(a)-x(a)y(c)|. Aria triunghiului determinat de cele 3
puncte este: S(a,b,c)/2. Aadar, aria triunghiului este un numr ntreg dac S(a,b,c) este un
numr par. Paritatea lui S(a,b,c) depinde doar de paritile coordonatelor celor 3 puncte.
Aadar, vom mpri cele N puncte n 4 clase. Clasa (p,q) conine acele puncte i pentru care
x(i) mod 2=p i y(i) mod 2=q (p=0,1; q=0,1). Vom calcula np(p,q)=numrul de puncte ce
aparin clasei (p,q). Vom considera apoi orice combinaie de cte 3 clase: (p(1),q(1)),
(p(2),q(2)), (p(3),q(3)) (vom considera clasele ordonate lexicografic nti dup p(*), apoi
dup q(*); cele 3 clase nu trebuie s fie neaprat distincte). Vom considera c al j-lea punct
al triunghiului (1j3) aparine clasei (p(j),q(j)). Vom calcula acum expresia S(a,b,c), pentru
cazul n care cele 3 puncte a, b i c aparin celor 3 clase considerate (n loc de x(a), y(a), x(b),
y(b), x(c), y(c), vom folosi p(1), q(1), p(2), q(2), p(3) i q(3)). Dac expresia calculat este
par, vom incrementa un contor ntri (iniial 0) cu numrul de triunghiuri de arie ntreag
obinute: dac cele 3 clase sunt distincte (p(j)p(k) sau q(j)q(k) pentru orice 1j<k3),
atunci incrementm ntri cu np(p(1),q(1))np(p(2),q(2))np(p(3),q(3)); dac 2 dintre clase sunt
identice ntre ele i a treia e diferit, atunci: fie j i k indicii celor 2 clase identice i l=6-j-k
indicele clasei diferite => vom incrementa ntri cu np(p(l),q(l))(np(p(j),q(j))(np(p(j),q(j))1))/2; dac toate cele 3 clase sunt identice, atunci vom incrementa ntri cu
np(p(1),q(1))(np(p(1),q(1))-1)(np(p(1),q(1))-2)/6. Complexitatea algoritmului este O(N).
Problema 6-24. Graful zonelor unui graf planar
Se d un graf neorientat cu N (1N1.000) noduri, desenate ca puncte n plan, i M (N-1
M3N-6) muchii. Muchia dintre 2 noduri i i j este desenat sub forma segmentului care
unete punctele corespunztoare celor 2 noduri. Fiecare muchie (i,j) are un cost c(i,j)>0.
Segmentele corespunztoare a oricare 2 muchii nu se intersecteaz, iar graful este conex. Se
dau apoi NP puncte (x,y) i dorim s determinm pentru fiecare dintre ele costul agregat
minim al segmentelor ce trebuie intersectate n cazul n care vrem s ajungem din punctul
(x,y) dat undeva la infinit (de ex., la (+,+)). Agregarea costurilor se realizeaz folosind o
funcie de agregare comutativ i cresctoare, agg (de ex., agg=adunare, nmulire, max,
etc.).

88

Soluie: Vom sorta circular muchiile adiacente fiecrui nod i, n ordinea unghiurilor formate
cu axa OX. S presupunem c nodul i este adiacent cu deg(i) muchii. Sortarea dup unghi a
muchiilor n jurul nodului i determin deg(i) intervale de unghiuri (al k-lea interval de
unghiuri este ntre a k-a i a (k+1)-a muchie adiacent cu nodul i, n ordinea sortat;
considerm c muchia deg(i)+1 este muchia 1 n ordinea sortat, iar muchia 0 este muchia
deg(i) n ordinea sortat).
Vom construi un graf nou GZ, neorientat, n care fiecare nod este o pereche (i,k) ce
corespunde celui de-al k-lea interval de unghiuri al nodului i (1jdeg(i)). S considerm o
muchie (i,j) i s presupunem c ea se afl pe poziia a n ordinea sortrii n jurul nodului i i
pe poziia b n ordinea sortrii n jurul nodului j. Vom introduce muchii de cost 0 n noul graf
ntre perechile (i,a) i (j,b-1), precum i ntre perechile (i,a-1) i (j,b). Vom introduce apoi
muchii de cost c(i,j) ntre perechile (i,a) i (j,b), precum i ntre perechile (i,a-1) i (j,b-1).
Vom alege cel mai din stnga punct q i vom considera intervalul su de unghiuri ce
conine unghiul ; fie acesta intervalul cu numrul p. Vom calcula apoi costul agregat minim
al unui drum de la perechea (q,p) la toate celelalte perechi din graful GZ (folosind muchiile
lui GZ). Pentru fiecare pereche (q,p) se calculeaz, astfel, cmin(q,p)=costul agregat minim
pentru a ajunge la perechea (q,p)=costul agregat minim pentru a ajunge n exteriorul grafului
i, deci, inclusiv la (+,+). Pentru aceasta folosim orice algoritm de calcul al drumurilor
de cost minim, n care 2 costuri CA i CB nu se adun pentru a obine costul unui drum mai
lung CC=CA+CB, ci se agreg: CC=agg(CA,CB). Toate perechile (q,p) la care s-a putut
ajunge cu costul cmin(q,p)=0 (inclusiv (q,p), care are, prin definiie, cmin(q,p)=0) au un
drum ctre exterior fr s intersecteze niciun segment. Complexitatea acestui pas este
O((N+M)log(N+M)).
Dac valorile cmin(i,j) sunt limitate superior de o constant CMAX mic, atunci putem
folosi CMAX+1 cozi de prioritate, coada Qu(co) corespunznd perechilor (q,p) care, pn
la momentul respectiv din cadrul rulrii algoritmului, au cmin(q,p)=co; astfel,
complexitatea pasului se reduce la O(N+M+CMAX).
n continuare, pentru fiecare punct (x,y) dat, va trebui s determinm o pereche (i,k) cu
proprietatea c unghiul format de segmentul S(i,x,y) ce unete nodul i i punctul (x,y)
formeaz cu axa OX un unghi ce se afl n al k-lea interval de unghiuri al nodului i, precum
i c segmentul S(i,x,y) nu intersecteaz vreo muchie a grafului. Varianta cea mai simpl
const n considerarea, pe rnd, a fiecrui nod i al grafului. Calculm unghiul u(i,x,y) format
de S(i,x,y) cu axa OX i cutm binar (sau liniar) intervalul k de unghiuri al nodului i n care
se gsete unghiul u(i,x,y). Apoi considerm pe rnd fiecare muchie a grafului i verificm
dac S(i,x,y) se intersecteaz cu muchia respectiv.
O metod mai bun se bazeaz pe folosirea unor tehnici de point location. Apoi, dup
gsirea unei perechi (i,k) corespunztoare, costul total minim al segmentelor ce trebuie
intersectate de un drum ce pleac din (x,y) i ajunge la (+,+) este cmin(i,k).
Problema 6-25. Acoperire cu poligoane
Se dau N (1N10.000) poligoane (nu neaprat convexe) avnd cel mult M100.000 de
vrfuri n total. Se d, de asemenea, un poligon mare. Verificai dac reuniunea celor N
poligoane este egal cu poligonul mare i, n acelai timp, suprafaa comun a oricare 2
poligoane este 0. Niciunul din poligoane (inclusiv cel mare) nu au unghiuri interioare fix
egale cu (adic laturi consecutive aflate una n prelungirea celeilalte) sau cu 2.

89

Soluie: Pentru nceput, vom verifica c suma ariilor celor N poligoane este egal cu cea a
poligonului mare (n caz contrar, rspunsul este negativ). Dac rspunsul este afirmativ,
vom considera toate vrfurile celor N poligoane (plus cele ale poligonului ,mare) i le vom
asocia identificatori unici (de la 1 la M=numrul total de vrfuri). Putem realiza acest lucru
folosind o tabel hash (iniial vid). Parcurgem toate vrfurile (n orice ordine) i, dac gsim
o cheie n tabela hash egal cu coordonatele vrfului, atunci identificatorul vrfului va fi
valoarea asociat cheii; altfel, incrementm cu 1 un contor cnt (iniial 0) i adugm n tabela
hash perechea (cheie=coordonatele vrfului, valoare=cnt) (identificatorul vrfului va fi cnt).
Pentru fiecare poligon mic p, vom considera fiecare vrf i al su (i este identificatorul
unic) i vom calcula intervalul de unghiuri [u(p,i), v(p,i)] pe care le formeaz cele 2 laturi ale
poligonului adiacente vrfului i cu axa OX. Vom asocia acest interval vrfului i. Vom sorta
apoi (dup captul stnga), pentru fiecare vrf i, toate intervalele de unghiuri asociate
acestuia. Intervalele asociate trebuie s nu se intersecteze (dect s se ating la capete), iar
suma lungimilor lor s fie 2 (acoper tot planul n jurul vrfului i) sau (acoper un
semiplan n jurul lui i; acest caz apare dac i se afl pe o latur a poligonului mare sau pe o
latur a unui poligon p, al crui vrf nu este) sau, dac i este un vrf al poligonului mare,
trebuie ca reuniunea intervalelor de unghiuri ale poligoanelor mici din jurul lui i s fie
egal cu intervalul de unghiuri format de laturile poligonului mare n vrful i (iar suma
lungimilor acestor intervale de unghiuri trebuie s fie egal cu unghiul format de poligonul
mare n vrful i).
Mai trebuie s verificm i c fiecare latur a unui poligon mic se suprapune peste o
latur a poligonului mare sau peste o alt latur a unui alt poligon mic. Pentru aceasta, vom
sorta laturile n funcie de unghiul format de dreapta lor suport cu axa OX (i, n caz de
egalitate, n funcie de punctul de intersecie al dreptei suport cu axa OX ; dac dreapta suport
este orizontal, vom folosi intersecia cu OY). Toate laturile ce formeaz acelai unghi i
dreptele lor suport au acelai punct de intersecie cu OX (sau, dac sunt orizontale, cu OY)
formeaz o grup i vor fi sortate dup coordonata x minim a lor (i, n caz de egalitate,
dup coordonata y minim a lor). n cadrul sortrii vom considera i laturile poligonului mare.
Vom mpri apoi fiecare grup n subgrupe. Laturile dintr-o grup pot fi privite ca nite
intervale. Vom calcula reuniunea intervalelor din fiecare grup. Dac aceast reuniune const
din mai multe intervale disjuncte, atunci vom mpri grupa n mai multe subgrupe, fiecare
corespunznd laturilor incluse ntr-unul din intervalele reuniunii (altfel, vom avea o singur
subgrup ce conine ntreaga grup).
Trebuie s verificm acum c laturile din aceeai sungrup pot fi colorate n dou
culori, astfel nct reuniunea laturilor de aceeai culoare s fie identic cu reuniunea laturilor
de cealalt culoare. Pentru aceasta, putem folosi soluia problemei 2-13, unde K=2
aplicnd algoritmul de acolo, trebuie ca rspunsul s fie afirmativ i, n plus, fiecare latur s
fac parte dintr-un din cele K submulimi.
Complexitatea ntregului algoritm este O(Mlog(M))).
Problema 6-26. Frontiera unui poligon (ACM ICPC NEERC 2000)
Se d un poligon convex cu N (1N200) vrfuri; vrful i are coordonatele (x(i), y(i)). n
interiorul poligonului se afl M (1M10.000) de puncte speciale. Dorim s eliminm o
parte dintre punctele de pe frontiera poligonului astfel nct poligonul convex obinut din
punctele rmase s conin n interiorul su toate cele M puncte speciale i: (a) s aib
perimetru minim ; sau (b) s aib arie minim.

90

Soluie: Vom considera graful orientat complet G cu N noduri, unde fiecare nod i corespunde
vrfului i al poligonului i fiecare muchie orientat (i->j) corespunde segmentului orientat (i>j) (sunt N(N-1) segmente n total).
Pentru segmentul (1->2) vom calcula semnul S (pozitiv sau negativ) al punctelor speciale
fa de segment. Pentru fiecare segment orientat (i->j) vom verifica c toate punctele
speciale au acelai semn S fa de segmentul (i->j) ca i n cazul segmentului (1->2). Dac
nu au toate acelai semn egal cu S, asociem segmentului (i->j) costul c(i,j)=+. Dac au
acelai semn, vom asocia urmtorul cost muchiei (i->j): n cazul (a), c(i,j)=lungimea
segmentului (i,j); n cazul (b), c(i,j)=(x(j)-x(i))((y(i)-ymin)+(y(j)-ymin))/2 (aria cu semn a
trapezului ce are dou laturi paralele cu axa OY, latura de sus este segmentul (i->j), iar latura
de jos este proiecia segmentului (i->j) pe dreapta orizontal y=ymin), unde
ymin=coordonat y minim a unui vrf al poligonului. Folosind algoritmul Floyd-Warshall
(cunoscut i ca algoritmul Roy-Floyd), vom calcula costul total minim al unui drum n G
ntre oricare dou vrfuri i i j (D(i,j)). Vom considera iniial c D(i,i)=+. Astfel, dup
rularea algortmului, D(i,i) va fi egal cu costul celui mai scurt ciclu orientat ce conine nodul i.
Vom alege nodul i pentru care D(i,i) este minim. Ciclul corespunztor lui D(i,i) va determina
noua frontier a poligonului (vrfurile ce rmn pe frontier, celelalte fiind eliminate). S
observm c, n cazul (a), costul ciclului reprezint perimetrul minim, iar n cazul (b),
reprezint aria total minim.
S observm c putem considera i problema mai general, n care costul segmentului
dintre o pereche de puncte (i,j) este dat ca fiind c(i,j) (i nu trebuie s fie neaprat lungimea
segmentului sau costul modificat din cazul ariei). n acest caz, am dori ca costul total al
laturilor poligonului rmas dup eliminarea unor vrfuri (i care conine n interior toate
punctele speciale) s fie ct mai mic.
Dac am dori s minimizm costul maxim al unui segment (i,j) ce face parte din soluie,
atunci putem cuta binar acest cost maxim Cmax. S presupunem c n cutare binar am
fixat un cost maxim C. Vom pstra doar segmentele i->j unde c(i,j)C, apoi vom verifica
dac n graful orientat obinut exist vreun ciclu. O variant pentru verificarea acestui lucru
const n calcularea componentelor tare conexe ale grafului. Dac exist cel puin o
component tare conex care conine dou vrfuri, atunci graful conine un ciclu (orientat). O
alt soluie const n utilizarea algoritmului de detecie a ciclurilor prezentat n soluia
problemei 3-1. O variant mult mai simpl n acest caz este s ignorm sensurile segmentelor,
s determinm componentele conexe ale grafului i s verificm c exist cel puin o
component conex care nu este arbore.
O versiune mai complex a problemei este urmtoarea: Dorim ca poligonul convex
obinut s aib exact K laturi, iar costul agregat al laturilor sale s fie minim (unde putem
folosi o funcie de agregare aggf, precum suma, maxim, etc.). n acest caz, vom utiliza un
algoritm de programare dinamic. Vom calcula Cmin(i,j,p)=costul total minim pentru a
selecta p segmente din intervalul de vrfuri i, i+1, , j (circular), captul primului segment
s fie n vrful i, iar captul celui de-al p-lea segment s fie n j. Vom calcula aceste valori n
ordine cresctoare a lungimilor intervalelor (circulare) ij. Avem Cmin(i,j,0)=0,
Cmin(i,j,1)=c(i,j) i Cmin(i,j,p)=min{aggf(Cmin(i,q,p-1), c(q,j)) | q se afl n intervalul
circular ij i qj}. Rspunsul este min{aggf(Cmin(i,j,K-1), c(j,i))}.
Dac aplicm direct algoritmul, obinem o complexitate O(N3K). Pentru anumite funcii
de agregare i modaliti de definire a costurilor c(*,*) ale segmentelor, putem s utilizm
structuri de date eficiente pentru determinarea lui Cmin(i,j,p), reducnd astfel complexitatea
(eventual, chiar pn la O(N2K)).

91

O soluie mai ineficient (de complexitate O(N3K2) se poate obine utiliznd urmtoarea
recuren: Cmin(i,j,p2)=min{aggf(Cmin(i,q,r), Cmin(q,j,p-r)) | q se afl n intervalul
circular ij, qj, 1rp-1}. O astfel de formulare ar fi necesar dac costurile nu ar fi
asociate segmentelor, ci, eventual, unor alte tipuri de structuri (de ex., triunghiuri).
Dac limita K nu este impus, atunci putem renuna la al treilea termen al strii calculate
de programrea dinamic (vom renuna la parameterul p), reducnd complexitatea soluiei la
O(N3) (sau mai puin, eventual chiar pn la O(N2), n funcie de funcia de agregare i
funciile de cost date). n acest caz, vom ncepe cu Cmin(i,j)=c(i,j) i vom ncerca apoi s
micorm aceast valoare: Cmin(i,j)=min{Cmin(i,j), min{aggf(Cmin(i,q), c(q,j)) | q este n
intervalul ij i qj} (dac utilizm al doilea tip de recuren, atunci vom avea
Cmin(i,j)=min{Cmin(i,j), min{aggf(Cmin(i,q), Cmin(q,j)) | q este n intervalul ij i qj}).
Problema 6-27. Distane punct-poligon
Se d un poligon convex fixat cu N vrfuri (3N100.000) i M (1M200.000) ntrebri
de forma: determinai distana de la un punct dat (x,y) la poligon (distana este 0 dac punctul
este inclus n poligon).
Soluie: nti trebuie s determinm dac punctul este n poligon sau nu (folosind una din
tehnicile deja discutate la alt problem). Apoi, dac punctul se afl n exterior, atunci
trebuie s determinm punctele de tangen low i high. low (high) este cel mai de jos (sus)
vrf al poligonului cu proprietatea c dreapta care unete punctul (x,y) de vrful low (high)
are ntreg poligonul convex de aceeai parte. Mai nti vom gsi latura (q,q+1) a poligonului,
cu proprietatea c punctul se afl n intervalul de unghiuri determinat de aceste dou vrfuri
(relativ la un punct central fixat din interiorul poligonului, (xc,yc)). Considerm c vrful q
este mai jos dect vrful q+1. Apoi vom efectua dou cutri binare, pentru a determina
vrfurile low i high. Proprietatea pe care o folosim n cutarea binar este c pentru orice
punct p de la q+1 la high (fr high) sau de la q la low (fr low), avem c punctele p-1 i
p+1 sunt de pri opuse ale dreptei determinate de punctul p i punctul (x,y) din ntrebare.
Dup determinarea vrfurilor low i high, folosim proprietatea c funcia de distan de la
punctul dat n ntrebare i pn la poligon este o funcie uni-modal (cu un singur minim)
ntre punctele low i high de pe poligonul convex (de pe partea dinspre punct). n acest caz
putem folosi cutare ternnar sau cutare pe baza derivatei.

92

Capitolul 7. Combinatoric i Teoria Numerelor


Problema 7-1. Furnica (Happy Coding 2007, infoarena)
O furnicu se afl ntr-un muuroi de form ptratic, alctuit din ncperi care au la
rndul lor form ptratic. ntr-o zi, furnicua pleac din ncperea ei, i ncepe s se plimbe
prin muuroi. n fiecare zi, ea va trece din ncperea n care se afl ntr-o ncpere alturat,
prin care, eventual, a mai trecut ntr-o zi anterioar. O ncpere alturat se definete ca fiind
un ptrat cu care camera (ptratul) n care se afl furnicua are o latur n comun. Furnicua
nu rmne dou zile la rnd n aceeai camer. Poziia iniial a furnicuei este ori n centrul
muuroiului, ori n colul din stnga-sus al acestuia, ca n figur:
Dndu-se numrul de zile t care au trecut de la nceputul
plimbrii furnicuei i poziia sa iniial (centru C sau stnga-sus
S), s se determine numrul minim de ncperi din muuroi n
care trebuie cutat furnicua, pentru a fi siguri c aceasta va fi
gsit. Numrul de ncperi de pe laturile muuroiului se consider
a fi mult mai mare dect numrul de zile n care se plimb furnicua

Soluie:
dac poziia de start este C, atunci rspunsul este (t+1)2
dac poziia de start este S, atunci:
o dac t este par, atunci rspunsul este ((t/2)+1)2
o dac t este impar, rspunsul este ((t+1)(t+2)/2)-((t+1)/2)2
Aceste formule (sau altele echivalente) pot fi obinute folosind urmtorul raionament:
furnica se poate afla n orice poziie aflat la o distan care are aceeai paritate ca i t, fa
de poziia iniial. Pentru pozitia de start C, aceste poziii formeaz niste romburi, iar
pentru poziia de start S, aceste poziii formeaz nite diagonale secundare. Dac
furnicua ar putea rmne n aceeai ncpere de la o zi la alta, observm c este suficient s
considerm cazul n care aceasta rmne n camera iniial la sfritul primei zile. Astfel,
rspunsul ar fi suma dintre rspunsurile pentru t i t-1, considernd constrngerile din enun
(furnica nu rmne 2 zile la rnd n aceeai camer).
Problema 7-2. Mulimi (Happy Coding 2007, infoarena)
Considerm mulimea [n]={1,...,n} a primelor n (1n100.000) numere naturale nenule.
Multimile A1, ..., Am acoper [n] dac i numai dac oricare ar fi 1in exist 1jm astfel
nct Aj s conin pe i. Mulimile A1, ..., Am separ pe [n] dac i numai dac oricare ar fi
1k,pn exist 1jm astfel nct cardinalul interseciei dintre Aj i {k,p} s fie 1 (practic
exist cel puin o mulime n care nu se afl ambele elemente simultan). Pentru n dat, s se
gseasc m minim astfel nct A1, ..., Am s acopere i s separe mulimea [n]. De asemenea,
s se afieze m mulimi A1, ..., Am care verific aceast proprietate.
Soluie: Se consider matricea M cu n linii i m coloane, unde M[i][j]=1, dac i este n Aj, i
0, altfel. Deoarece A1, ..., Am separ multimea [n], rezult c oricare 2 linii ale matricei sunt
diferite (dac liniile k i l ar fi egale, atunci k i l nu pot fi separate). De aici rezult c n2m
(numrul de linii posibile, astfel nct oricare 2 s fie diferite). Aadar, mlog2n. Vom arta

93

c m=(log2n)+1. Presupunem prin absurd c m=log2n. Din principiul lui Dirichlet se obine
cu uurin faptul c fie apare n matrice linia 00...0 (contradicie cu condiia de acoperire),
fie matricea conine 2 linii identice, ceea ce este absurd.
Pentru m=(log2n)+1 se poate da exemplul urmtor: Aj este mulimea numerelor mai mici
sau egale cu n care au 1 pe bitul (j-1) din reprezentarea lor binar pe m bii (am numerotat
biii de la cel mai puin semnificativ la cel mai semnificativ, ncepnd cu bitul 0).
Problema 7-3. Expresii Algebrice (Selecie echipe ACM ICPC, UPB 2006)
O expresie algebric poate fi reprezentat printr-un arbore. Putem evalua expresia
parcurgnd arborele ei corespunztor. Reprezentarea sub form de arbore a unei expresii
algebrice nu este obligatoriu unic. De exemplu, expresia 1+2+3*4 poate fi reprezentat prin
urmtorii doi arbori:

La o privire atent observm c succesiunea operaiilor + i * se menine, iar ordinea


operanzilor rmne neschimbat. n primul arbore ordinea evalurii va fi: 3*4 = 12; 2+12 =
14; 1+14 = 15. n al doilea arbore, expresia va fi evaluat astfel: 1+2 = 3; 3*4 = 12; 3+12
= 15. Ambele reprezentri produc rezultatul dorit. n aceast problem vom considera
expresii algebrice simple ce conin doar numere dintr-o singur cifr, +, * i paranteze.
Expresia se evalueaza dupa regulile algebrice normale. Determinai numrul de reprezentri
sub form de arbore care evalueaz expresia correct.
Exemple:
1+2+3+4
Numrul de arbori = 5.
(1+2)+(3+4)
Numrul de arbori = 1.
1+2+3*4
Numrul de arbori = 2.
1+2+(3*4)
Numrul de arbori = 2.
1+*7
Numrul de arbori = 0.
1+2*(3+(4*5)
Numrul de arbori = 0.
Soluie: Vom calcula o matrie T[i][j] reprezentnd numrul de arbori de evaluare a subexpresiei dintre poziiile i i j. Dac sub-expresia dintre aceste poziii nu este valid (nu este
parantezat corect, nu are o structur corespunztoare de operanzi i operatori, etc.), atunci
T[i][j] va fi 0. n caz contrar, dac expresia dintre poziiile i i j este inclus ntre paranteze,
atunci T[i][j]=T[i+1][j-1]. Dac nu este complet inclus ntr-o pereche de paranteze, atunci
exist cel puin un operator care nu este inclus n vreo parantez. Se caut nti operatorii +
care nu sunt inclui ntre paranteze i pentru fiecare astfel de operator aflat pe o pozitie k,
T[i][j] se incrementeaz cu valoarea T[i][k-1]T[k+1][j]. Dac nu se gasete niciun +
neinclus ntre paranteze, atunci se caut un '*' i se realizeaz aceleai aciuni ca i n
cazul +.

94

Problema 7-4. Fracii (Olimpiada Naional de informatic, Romnia 2001)


O proprietate interesant a fraciilor ireductibile este c orice fracie se poate obine dup
urmtoarele reguli:
pe primul nivel se afl fracia 1/1
pe al doilea nivel, n stnga fraciei 1/1 de pe primul nivel, plasm fracia 1/2, iar n
dreapta ei, fracia 2/1
pe fiecare nivel k se plaseaz, sub fiecare fracie i/j de pe nivelul de deasupra, fracia
i/(i+j) n stnga i fracia (i+j)/j n dreapta.
nivelul 1:
1/1
nivelul 2:
1/2
2/1
nivelul 3: 1/3 3/2 2/3 3/1
Dndu-se o fracie oarecare prin numrtorul i numitorul su, determinai numrul
nivelului pe care se afl fracia sau o fracie echivalent (avnd aceeai valoare) cu aceasta.
Exemple:
13/8 => nivelul 6
12/8 => nivelul 3
Soluie: Pentru nceput, vom reduce fracia A/B dat la o fracie ireductibil. Calculm d, cel
mai mare divizor comun al lui A i B, apoi calculm P=A/d i Q=B/d. Acum trebuie s
calculm nivelul pe care se afl fracia P/Q. S observm c urmtorul algoritm calculeaz
corect nivelul:
nivel=1
ct timp PQ execut
dac P>Q atunci P=P-Q
altfel Q=Q-P
nivel=nivel+1
Totui, s considerm urmtorul caz: P=2.000.000.000, Q=1. n acest caz, algoritmul va
executa 2.000.000.000 de iteraii pentru a calcula corect nivelul, depind astfel limita de
timp. Algoritmul poate fi mbuntit, dup cum urmeaz:
nivel=1
ct timp PQ execut
dac P>Q atunci
nivel=nivel+(P div Q)
P=P mod Q
altfel
nivel=nivel+(Q div P)
Q=Q mod P
Complexitatea algoritmului este identic cu cea a algoritmului de calcul a celui mai mare
divizior comun a dou numere.
Problema 7-5. Codificare (SGU)
Se d funcia phi(W) a unui ir W:
dac lungimea lui W este 1, atunci phi(W)=W
fie W=w1w2...wN i K=N/2 (parte ntreag inferioar) => phi(W) = phi(wNwN-1...wK+1)+
phi(wKwK-1...w1) (unde + reprezint concatenarea)
Exemple: phi(Ok)=kO; phi(abcd)=cdab

95

Dndu-se lungimea N (1N109) a irului W, determinai poziia pe care ajunge


caracterul wq (1qN) din W n phi(W).
Soluie: Vom iniializa valoare p a poziiei la 0, apoi vom apela urmtoare funcie recursiv,
cu parametrii N i Q. La sfritul execuiei, p va conine valoarea poziiei pe care ajunge
litera wq din W n phi(W).
Compute(N,Q):
dac (N=1) atunci p=p+1
altfel
K=N/2
dac (qK) atunci
p=p+N-K
Compute(K, K-Q+1)
altfel
Compute(N-K, N-K-(Q-K)+1)
Problema 7-6. Arbore de cutare (Lotul Naional de Informatic, Romnia, 1999)
Se consider un arbore binar de cutare A avnd n noduri coninnd cheile 1,2,,n. O
permutare p = [p1,,pn] a numerelor ntregi 1,2,,n se numete consistent cu arborele A
dac arborele de cutare poate fi construit pornind de la arborele vid prin inserarea numerelor
ntregi p1, p2, , pn n aceast ordine. S se determine numrul permutrilor mulimii
{1,2,,n} care sunt consistente cu un arbore dat. (Altfel spus: cte secvene distincte de chei
exist pentru ca arborii binari de cutare obinui prin inserarea cheilor n ordinea dat s
fie identici cu arborele dat?)
Exemplu
2
Arborele din figur are exact 8 permutri
consistente. De exemplu, permutrile 2, 1, 4, 3,
4
1
5 i 2, 4, 5, 3, 1 sunt consistente cu arborele din
5
3
figur. Insernd elemente consecutive din
permutarea 2, 4, 5, 3, 1 se obine arborele dat:
2

2
1

4
5

4
3

Soluie: Se parcurge arborele de jos n sus. Se calculeaz, pentru fiecare nod x, numrul de
permutri posibile NP(x) care produc subarborele al crui vrf este nodul respectiv. Numrul
corespunzator rdcinii arborelui este numrul cautat. Pentru a determina cte permutri
exist care produc subarborele cu vrful p se procedeaz astfel:
1) Dac p este nod terminal, NP(p)=1.
2) Dac p nu este nod terminal i are un singur fiu p1, atunci NP(p)=NP(p1).
3) Dac p nu este nod terminal i are 2 fii, atunci fie p1 si p2 fiii si. Numrul de permutri
corespunztoare subarborelui de vrf p este numrul de permutri rezultate n urma
interclasrii oricror 2 permutri corespunztoare vrfurilor p1 i p2. Fiecare element al unei
permutri (din subarborii lui p1 sau p2) i pstreaz poziia relativ fa de celelalte elemente
ale permutrii corespunztoare subarborelui din care face parte. Numrul de posibiliti de a
interclasa 2 iruri de lungime a, respectiv b, este C(a+b,a) (combinri de a+b luate cte a).
Fiecare permutare a subarborilor lui p1 sau p2 are nv(p1), respectiv nv(p2) elemente

96

(nv(x)=numrul de noduri din subarborele cu rdcina x; nv(x)=1, dac x e nod terminal;


nv(x)=1+nv(p1), dac x are un singur fiu p1; nv(x)=1+nv(p1)+nv(p2), dac x are doi fii, p1 i
p2). Aadar, NP(p)=NP(p1)NP(p2)C(nv(p1)+nv(p2), nv(p1)). Elementul din vrful p trebuie
s se afle tot timpul naintea oricrui element din subarborii fiilor si n cadrul unei permutri
consistente.
Complexitatea algoritmului este O(N2NrMari(N)), unde NrMari(N) este complexitatea
de a efectua adunri cu numere mari avnd lungime O(N) (de obicei, NrMari(N)=O(N) i,
astfel, complexitatea devine O(N3)).
Problema 7-7. Urmtorul ir de paranteze (SGU)
Se d un ir de paranteze deschise nchise corect (de lungime cel mult 10.000).
Determinai urmtorul ir de paranteze nchise corect, n ordine lexicografic, care are
aceeai lungime ca i irul dat. Considerm c o parantez deschis ( este mai mic
lexicografic dect o parantez nchis.
Exemplu: Pentru irul (())(), urmtorul ir este ()(()).
Soluie: Fie N lungimea irului dat. Este evident c el conine N/2 paranteze deschise i N/2
paranteze nchise. Vom parcurge irul de la sfrit ctre nceput i vom menine dou valori:
nd i ni, numrul de paranteze deschise i nchise ntlnite pn la momentul respectiv n
cadrul parcurgerii (iniial, cele dou valori sunt 0). S presupunem c am ajuns la o poziie i.
Dac pe poziia i este o parantez deschis, incrementm nd cu 1; altfel, incrementm ni cu 1.
Dac pe poziia i este o parantez deschis, vom verifica dac exist un ir care s aib
primele i-1 caractere ca i irul dat, iar pe poziia i s aib o parantez nchis. ntre primele
i-1 caractere exist (N/2-nd) paranteze deschise i (N/2-ni) paranteze nchise. Dac (N/2nd)>(N/2-ni), atunci putem pune pe poziia i o parantez nchis. n ir mai trebuie s
adugm, pe poziiile i+1, ..., N, nd=nd paranteze deschise i ni=ni-1 paranteze nchise.
Vom aduga nti cele nd paranteze nchise, urmate de cele ni paranteze nchise. n felul
acesta, am obinut urmtorul ir n ordine lexicografic.
S extindem un pic problema i s presupunem c irul conine K tipuri de paranteze (de
exemplu, paranteze rotunde, ptrate, acolade, etc.) i vrem s determinm urmtorul ir n
ordine lexicografic care este parantezat corect. Vom presupune c exist o ordine o(1), ...,
o(2K) ale celor 2K tipuri de paranteze (K tipuri de paranteze, deschise i nchise). Vom
parcurge irul de la 1 la N i pentru fiecare poziie i vom calcula nd(i,j)=cte paranteze
deschise de tipul j sunt pe poziiile 1,...,i i ni(i,j)=cte paranteze nchise de tipul j sunt pe
poziiile 1,...,i. n general, aceste valori sunt identice cu cele de la poziia i-1, cu o singur
excepie: dac pe poziia i e o parantez deschis (nchis) de tipul j, atunci avem
nd(i,j)=nd(i-1,j)+1 (ni(i,j)=ni(i-1,j)+1).
Vom parcurge apoi irul de la sfrit ctre nceput. Pentru fiecare poziie i, vom efectua
urmtoarele aciuni. S presupunem c pe aceast poziie se afl caracterul cu numrul de
ordine q n cadrul alfabetului de 2K caractere. Vom ncerca s punem pe poziia i caracterul
cu cel mai mic numr de ordine q>q pentru care nu se obin contradicii. O contradicie se
obine doar dac caracterul q este o parantez nchis de tipul j i nd(i,j)<ni(i,j)+1. Dac nu
se obine nicio contradicie, vom amplasa pe poziia i caracterul q. n continuare, vom
menine contoarele ndc(j) i nic(j), reprezentnd numrul curent de paranteze deschise,
respectiv nchise, de tipul j. Iniializm ndc(j)=nd(i-1,j) i nic(j)=ni(i-1,j). Mai mult, dac pe
poziia i am amplasat o parantez deschis (nchis) de tipul j, incrementm ncd(j) (nic(j)) cu

97

1. Acum urmeaz s amplasm caracterele de pe poziiile i+1, ..., N, n ordine lexicografic


minim. Avem aici dou variante:
n prima variant suntem obligai s pstrm acelai numr de paranteze din fiecare tip ca
i n irul iniial. Aadar, pentru fiecare caracter q (1q2K), avem un numr de apariii al
su nap(q) care mai trebuie amplasate n ir. Pe fiecare poziie p (de la i+1 la N) vom alege
caracterul q minim, astfel nct nap(q)>0 i nu se obin contradicii (se obine o contradicie
dac caracterul q este parantez nchis de tipul j i ndc(j)<nic(j)+1). Dup amplasarea sa,
decremntm cu 1 nap(q) i incrementm cu 1 ndc(j) (nic(j)) dac caracterul q este o
parantez deschis (nchis) de tipul j. n acest caz, atunci cnd selectm prima parantez q
de amplasat pe poziia i, trebuie ca nu toate apariiile lui q s se afle ntre poziiile 1,...,i-1.
n a doua variant, nu suntem obligai s pstrm acelai numr de paranteze din fiecare
tip ca i n irul iniial. Vom reduce acest caz la cazul precedent. Pentru fiecare tip de
paranteze j, dac ndc(j)>nic(j), va trebui s avem neaprat nap(q) caractere cu numrul de
ordine q, unde acest caracter este paranteza nchis de tipul j. Pe lng aceste caractere ale
cror apariii sunt forate, mai avem de amplasat nc 2h0 caractere (obinut ca diferen
dintre N-i i numrul total de apariii forate). Vom alege caracterul cu cel mai mic numr de
ordine q ce reprezint o parantez deschis. Fie q caracterul ce reprezint paranteza nchis
corespunztoare. Vom incrementa nap(q) i nap(q) cu cte h, apoi vom aplica algoritmul
descris anterior.
Complexitatea soluiei prezentate este O(NK).
Problema 7-8. Umplerea unui ptrat NxN cu numr maxim de dreptunghiuri 1xK
(TIMUS)
Se consider un ptrat alctuit din NxN (1N10.000) ptrele unitare. Determinai
numrul maxim de dreptunghiuri de dimensiuni 1xK (sau Kx1) (1KN) care pot fi
amplasate fr suprapuneri n interiorul ptratului (fiecare dreptunghi ocup K ptrele
unitare din interiorul ptratului)
Exemplu: N=5, K=4 => Rspunsul este 6.
Soluie: Vom defini funcia NrMax(N,K), al crei rezultat este chiar rspunsul dorit. Dac (N
mod K)=0, atunci NrMax(N,K) ntoarce ((NN) div K) (se pot ocupa toate ptrelele unitare).
Altfel, vom calcula dou valori. V1=(N mod K)(N div K)4+NrMax(N-2(N mod K),K).
Aceast valoare corespunde cazului n care se bordeaz ptratul cu un contur de grosime
(N mod K), format din dreptunghiuri de dimensiune 1xK i Kx1, iar apoi se reapeleaz funcia
NrMax pentru zona rmas liber (un ptrat de latur N-2(N mod K)).
A doua valoare este V2=(N+(N mod K))(N div K). Acest caz corespunde amplasrii a (N
div K) dreptunghiuri pe fiecare linie a ptratului. Pe fiecare din ultimele (N mod K) coloane
rmase libere se amplaseaz, din nou, cte (N div K) dreptunghiuri. Valoarea ntoars de
NrMax(N,K) este max{V1,V2}.
Exist i o soluie mai eficient, care funcioneaz pentru dreptunghiuri de dimensiuni
arbitrare PxQ (nu doar pentru ptrate NxN). Vom considera cele P linii mprite n CP=P
div K grupuri de cte K linii (plus, eventual, nc un grup, ce conine RP=P mod K linii, dac
P mod K>0). n fiecare grup de linii vom numerota liniile de la 0 la K-1. Pentru fiecare linie i,
pe coloana C (0CQ-1) vom considera (conceptual) c este scris numrul (i+C) mod K. Va
trebui s numrm n cte elemente este scris numrul K-1. Dac K=1, acest numr este KQ.
Altfel, pe fiecare linie exist CQ=Q div K intervale ntregi de numere consecutive 0, 1, ..., K1. Astfel, avem cel puin KCQ elemente egale cu K-1. Fie RQ=Q mod K. Dac RQ>0,

98

atunci primul element egal cu K-1 pe una din ultimele RQ coloane ale unei linii din grup
apare abia pe linia K-1-RQ. Pe urmtoarele RQ-1 linii va aprea elementul K-1 n continuare
printre ultimele RQ coloane. Astfel, ntre primele K-1 linii din grup, elementul K-1 apare n
ultimele RQ coloane de RQ ori. Aadar, numrul total de apariii ale elementului K-1 ntr-un
grup este KCQ+RQ.
Vrem s calculm acum de cte ori apare elementul K-1 ntre ultimele RP<K linii.
Evident, acesta apare de cel puin RPCQ ori. Dac RPK-RQ, atunci elementul K-1 mai
apare de nc RP-(K-RQ)+1 ori pe ultimele RQ coloane ale ultimelor RP linii. Numrul total
de apariii ale elementului K-1 este egal chiar cu numrul maxim de dreptunghiuri 1xK (sau
Kx1) ce pot fi amplasate n interiorul dreptunghiului dat. Observm c algoritmul descris are
ordinul de complexitate O(1) (efectund doar O(1) mpriri, adunri i nmuliri), sau
O(log(P)+log(Q)) (dac numerele P, Q i/sau K sunt numere mari).
Problema 7-9. iruri cu intervale cu lungimi minime i maxime
Determinai numrul de iruri de lungime N, n care fiecare element ia valori din
mulimea {0,1,...,B-1} i n care nu exist mai mult de K (0KN) elemente de 0 consecutive,
dar exist cel puin X i cel mult Y (0XYN) secvene de cel puin Q zerouri consecutive
(0QK). O secven este un interval maximal ca numr de 0-uri. Gsii un algoritm eficient
pentru Q=0 (cnd valorile lui X i Y nu conteaz).
Soluie: Vom calcula NSC(i,j,p)=numrul de iruri de lungime i care se termin cu j 0-uri i
care conin p secvene de cel puin Q i cel mult K 0-uri consecutive (exclusiv ultima
secven de j 0-uri) (0iN, 0ji, 0pY). Avem NSC(0,0,0)=1. Pentru i1 avem:
NSC(i,0,p)=(B-1)(NSC(i-1,0,p)+NSC(i-1,1,p) +...+NSC(i-1,min{i-1,Q-1},p)) i
NSC(i,j1,p)=NSC(i-1,j-1,p).
Pentru p1 i j=0, vom aduga la valoarea NSC(i,j,p) calculat conform formulelor
anterioare, valoarea (B-1)(NSC(i-1,Q,p-1)+NSC(i-1,Q+1,p-1) +...+NSC(i-1,min{i,K},p-1)).
Rezultatul este suma valorilor NSC(N, 0jQ-1, XpY), la care adugm suma valorilor
NSC(N, QjK, X-1pY-1). Complexitatea unui algoritm care implementeaz aceste
formule este O(N3).
Pentru cazul Q=0, vom calcula NS(i)=numrul de iruri de lungime i, ce conin cel mult
K elemente de 0 consecutive i care se termin cu un element diferit de 0. NS(0)=1. Vom
considera fiecare lungime i (1iN), n ordine cresctoare. NS(i)=(B-1)(NS(i-1)+NS(i2)+...+NS(max{0,i-(K+1)})). O implementare direct ar avea complexitatea
O(N2)NumereMari(N). Pentru a ajunge la complexitatea O(N)NumereMari(N), vom
menine o sum SNS a ultimelor cel mult K+1 valori NS(j) calculate. Iniializm SNS cu
NS(0). Apoi, pentru fiecare lungime i (1iN), avem NS(i)=(B-1)SNS. Dup aceea, adugm
NS(i) la SNS, iar dac i-(K+1)0, setm SNS=SNS-NS(i-(K+1)). Rezultatul final este NS(N0)+NS(N-1)+...+NS(N-K) (variem lungimea j=0,...,K a ultimei secvene de elemente 0).
Dac lungimea irurilor ar fi foarte mare (de ex., 109), K-ul ar fi mai mic (de ex.,
0K100) i am avea nevoie doar de rezultat modulo un numr P, atunci am putea folosi
urmtoarea metod. Am defini un vector-coloan x(i), ce const din K+1 elemente.
Elementele acestui vector sunt, n ordine, NS(i), NS(i-1), ..., NS(i-K). Vom defini o matrice
de transformare T, avnd K+1 linii i coloane. Prima linie a lui T conine numai valori de (B1), iar pe urmtoarele linii i (2iK+1) avem T(i,i)=1 i T(i,ji)=0. Observm c, pentru a
calcula x(i), putem nmuli matricea T cu vectorul-coloan x(i-1). Dac pornim de la vectorul
x(0)=(1, 0, 0, ..., 0), putem scrie x(i)=Tix(0). Rezultatul dorit este suma elementelor

99

vectorului x(N). Pentru a calcula x(N) este suficient s ridicm la puterea N matricea T i s
nmulim TN cu x(0). Putem realiza acest lucru n timp logaritmic folosind O(log(N))
nmuliri de matrici (deci putem obine o complexitate de O((K+1)3log(N)). Toate operaiile
(de adunare i nmulire) se realizeaz modulo P.
Probleme asemntoare au fost propuse la diverse concursuri, precum concursuri online
de pe TIMUS sau baraje din cadrul lotului naional de informatic.
Problema 7-10. Ture (ACM ICPC NEERC 2004, Southern Subregion)
Se d o tabl de ah mai special. Aceasta are N (1N300) linii, dar fiecare linie i are un
numr de coloane C(i) (1C(i)300) (coloanele de pe aceast linie sunt coloanele 1, 2, ...,
C(i)). Determinai n cte moduri pot fi amplasate K ture pe tabla de ah, n aa fel nct
oricare dou ture s nu se atace. Dou ture se atac dac sunt amplasate pe aceeai linie sau
aceeai coloan. Dou ture de pe aceeai coloan j se atac chiar dac ntre liniile lor exist
linii i cu C(i)<j.
Exemplu: N=2, K=2, C(1)=2, C(2)=3 => Rspunsul este 4.
Soluie: Pe o tabl de ah dreptunghiular cu P linii i Q coloane se pot amplasa K ture n
C(P,K)C(Q,K)K! moduri (C(x,y)=combinri de x luate cte y), deoarece liniile pe care se
aleg aceste ture se pot alege n C(P,K) moduri i, independent, coloanele se pot alege n
C(Q,K) moduri; pentru K linii i coloane alese exist K! moduri de a amplasa cele K ture.
Pentru o tabl n care nu au toate liniile acelai numr de coloane, vom sorta liniile
cresctor dup numrul de coloane, astfel nct s avem C(1)C(2)...C(N). Apoi vom
calcula valorile NT(i,j)=n cte moduri se pot amplasa, fr s se atace, j ture pe primele i
linii. Avem NT(0,0)=1 i NT(0,j>0)=0. Pentru 1iN avem: NT(i, 0)=1, NT(i,
1jmin{i,K,C(i)})=NT(i-1, j)+NT(i-1,j-1)(C(i)-(j-1)). Primul termen corespunde cazului
cnd nu amplasm nicio tur pe linia i, iar al doilea termen corespunde cazului cnd
amplasm o tur pe linia i.
Dac avem j ture n total, atunci (j-1) ture au fost amplasate pe liniile 1,...,i-1 i acestea
ocup j-1 coloane dintre cele C(i) ale liniei i. Prin urmare, tura de pe linia i poate fi
amplasat pe una din cele (C(i)-(j-1)) coloane libere.
Problema 7-11. Coliere frumoase (SGU)
S considerm un colier alctuit din 2N-1 (52N-1231-1) perle, dintre care K perle sunt
negre (celelalte fiind albe). Un colier este frumos dac putem alege dou perle negre (nu
neaprat diferite) n aa fel nct una dintre cele dou pri de colier dintre cele dou perle s
conin exact N perle (indiferent ce culori au acestea). Determinai numrul K minim pentru
care fiecare colier format din 2N-1 perle este frumos.
Exemple:
2N-1=5 => Valoarea minim pentru K este 3.
2N-1=7 => Valoarea minim pentru K este 4.
Soluie: Din numrul X=2N-1 dat calculm valoarea lui N (N=(X+1)/2). Dac (N mod 3)=2,
atunci valoarea minim a lui K este N-1; altfel, valoarea minim a lui K este N.
Problema 7-12. Cicluri hamiltoniene n grafuri multipartite (TIMUS)
Se d un graf multipartit complet. Graful conine N (2N5) pri . Fiecare parte i
(1iN) conine B(i) (1B(i)30) noduri. Graful este format n felul urmtor: exist cte o

100

muchie ntre oricare dou noduri situate n pri diferite i nu exist nicio muchie ntre
nodurile din aceeai parte. Determinai numrul de cicluri Hamiltoniene din graf (modulo un
numr prim P; 3P100.000). Nodurile se consider numerotate i avem (1+max{B(i)})N
5.000.000.
Exemplu: N=3, B(1)=B(2)=B(3)=2, P=997 => Rspunsul este 16.
Soluie: Vom considera c ciclul ncepe ntr-unul din nodurile din prima parte. Pentru
nceput vom considera c ordinea n care sunt traversate pe ciclu nodurile din aceeai parte
este fixat. Astfel, ciclul poate fi descris prin numrul de noduri din fiecare parte prin care sa trecut i de partea curent la care s-a ajuns. Vom calcula NC(x(1), ..., x(N), k)=numrul de
drumuri care ncep la primul nod din partea 1, trec prin x(i) noduri din partea i (0x(i)B(i))
i ajung n partea k (1kN).
Iniial, avem NC(1, 0, ..., 0, 1)=1 i celelalte valori sunt iniializate la 0. Vom considera
tuplurile (x(1), ..., x(N)) n ordine cresctoare a sumei (x(1)+...+x(N)) (de la suma 2 ncolo).
Tuplurile cu aceeai sum pot fi considerate n orice ordine. Pentru un tuplu (x(1), ..., x(N)) i
o valoare k (1kN i x(k)1), NC(x(1), ..., x(N), k) este egal cu suma valorilor NC(x(1), ...,
x(k-1), x(k)-1, x(k+1), ..., x(N), j) (1jN, jk). Numrul total de cicluri hamiltonien (cu
ordinea fixat a nodurilor n cadrul fiecrei pri) este NH=suma valorilor NC(B(1), ..., B(N),
j) (2jN).
Pentru a obine rezultatul final vom calcula NHF=(NH(B(1)-1)!B(2)!...B(N)!)/2.
Factorul B(i)! determin toate modalitile de ordonare a nodurilor din partea i n cadrul
ciclului. Factorul (B(1)-1)! Indic faptul c primul nod de pe ciclu rmne fixat, dar, n cazul
prii 1, ordinea pe ciclu a celorlalte (B(1)-1) noduri poate fi aleas oricum. mprirea la 2
este necesar, deoarece fiecare ciclu este calculat de dou ori, cte o dat pentru fiecare sens
de parcurgere al su. Toate operaiile de adunare i nmulire se efectueaz modulo P. Pentru
mprirea la 2, trebie s calculm inversul multiplicativ al lui 2, adic acel numr x cu
proprietatea c x2=1 (mod P) (putem ncerca fiecare valoare a lui x, ntre 1 i P-1, sau putem
calcula pe x direct, folosind algoritmul lui Euclid extins).
Problema 7-13. Combinri cu restricii de sum (SGU)
Se d un numr prim P (3P1000). Determinai n cte moduri se pot alege P elemente
distincte din mulimea {1,2,...,2P}, astfel nct suma lor s fie multiplu de P.
Exemple: N=3 => Rspunsul este 8; N=5 => Rspunsul este 52.
Soluie: Voi prezenta nti o soluie general, care nu ine cont de faptul c P este numr
prim. Vom calcula valorile NP(i,j,k)=numrul de posibiliti de a alege j elemente din
mulimea {1,...,i} (jmin{i,P}), astfel nct suma elementor alese, modulo P, s fie egal cu k
(0kP-1). Avem NP(0,0,0)=1 i NP(0,j>0,*)=NP(0,*,k>0)=0. Pentru i1 avem:
NP(i,j,k)=NP(i-1,j,k)+NP(i-1,j-1,(k-i+P) mod P). Primum termen al sumei corespunde
cazului cnd elementul i nu este ales, iar al doilea termen corespunde cazului cnd alegem
elementul i. Rspunsul este NP(2P, P, 0). Complexitatea acestui algoritm este
O(P3NumereMari(P)). Memoria folosit pare a fi de oridnul O(P3), dar, ntruct pentru
calculul valorilor NP(i,*,*) avem nevoie doar de valorile NP(i-1,*,*), ea poate fi redus la
O(P2).
Dac studiem valorile NP(2P, P, *) pentru P numr prim, vom observa c valorile
NP(2P, P, 1jP-1) sunt egale ntre ele, iar NP(2P, P, 0)=NP(NP(2P, P, 1)+2. ntruct
suma tuturor acestor valori este C(2P, P) (combinri de 2P luate cte P), obinem c

101

rspunsul este (C(2P, P)-2)/P+2. Vom calcula C(2P, P) folosind O(P) operaii pe numere
mari (nmulirea numr mare cu numr mic sau mprirea numr mare la numr mic). Vom
folosi urmtoarele relaii: C(X,0)=1 i C(X,1jX)=(X-j+1)/jC(X,j-1). Cealalt relaie
binecunoscut (C(X,1jX)=C(X-1,j-1)+C(X-1,j)) nu este folositoare n acest caz, deoarece
ar conduce la un algoritm ce folosete O(P2) operaii (adunri) pe numere mari.
Problema 7-14. Parantezri cu adncime dat (Olimpiada Baltic de Informatic 1999)
Determinai cte iruri ce conin N (1N38) perechi de paranteze nchise corect exist,
astfel nct adncimea irului s fie D (1DN). Adncimea D(S) a unui ir S de paranteze se
definete n felul urmtor:
dac S este irul vid, D(S)=0
dac S e de forma (S), unde S este un ir de paranteze, D(S)=1+D(S)
dac S=AB, unde A i B sunt dou iruri de paranteze, atunci D(S)=max{D(A), D(B)}
Exemplu: N=3, D=2 => Rspunsul este 3. irurile de adncime 2 sunt: (())() ; ()(()) ;
(()())
Soluie: Vom calcula NS(i,j)=numrul de iruri formate din i perechi de paranteze nchise
corect, avnd adncime j. Avem: NS(i0,j>i)=0, NS(0,0)=1 i NS(i1, 1)=1.
Pentru i2 i 2ji avem urmtoarele posibiliti. irul poate fi format dintr-un ir A ce
conine k perechi de paranteze, avnd adncime j-1, pe care l includem ntre o alt pereche
de paranteze; acest ir este urmat de un ir B format din i-k-1 perechi de paranteze i orice
adncime lj. Vom nota prin N1(i,j)=suma valorilor (NS(k, j-1)NS(i-k-1,l)) (0ki-1; 0lj).
O a doua posibilitate este ca irul de i perechi de paranteze i adncime j s fie format
dintr-un ir A format din k perechi de paranteze i adncime l<j-1, pe care l includem ntr-o
alt pereche de paranteze, urmat de un ir B format din (i-k-1) paranteze i adncime j. Vom
nota cu N2(i,j) suma valorilor (NS(k,l)NS(i-k-1,j)) (0ki-1; 0lj-2). Avem apoi
NS(i,j)=N1(i,j)+N2(i,j).
Dac aplicm formulele direct, obinem un algoritm cu complexitatea O(N4). Putem
reduce complexitatea la O(N3) n felul urmtor. Dup ce am calculat toate valorile NS(q,*),
vom calcula nite sume prefix: SNS(q,-1)=0 i SNS(q,j0)=SNS(q,j-1)+NS(q,j). Apoi, n
cadrul formulelor de calcul pentru N1(i,j) i N2(i,j), vom considera, pe rnd, fircare valoare a
lui k. Dup fixarea lui k, pentru N1 trebuie s nmulim valoarea NS(k,j-1) (fixat) cu suma
valorilor NS(i-k-1,l) (0lj); aceast sum este egal cu SNS(i-k-1,j). Pentru calculul lui
N2(i,j), dup alegerea valorii lui k, trebuie s nmulim NS(i-k-1,j) cu suma valorilor NS(k,l)
(0lj-2); aceast sum este egal cu SNS(k,j-2). Astfel, fiecare valoare N1(i,j), N2(i,j) i
NS(i,j) se calculeaz n timp O(N), complexitatea total devenind O(N3).
Problema 7-15 Suma cifrelor (TIMUS)
Fie S(N) suma cifrelor unui numr N. Determinai pentru cte perechi (A,B) de numere n
baza Q (2Q50) de exact K (1K50) cifre are loc egalitatea: S(A+B)=S(A)+S(B) (n baza
Q). La numrare trebuie s inei cont de urmtoarele fapte: (1) numerele A i B nu pot fi 0 i
nici nu pot ncepe cu cifra 0; (2) ordinea numerelor n cadrul unei perechi conteaz => de ex.,
perechile (12,26) i (26,12) (n baza Q7) sunt diferite.
Exemplu: K=2, Q=10 => Rspunsul este 1980.
Soluie: Rspunsul este (Q-1)(Q-2)/2((Q+1)Q/2)(K-1). Ajungem la acest rspuns observnd
c atunci cnd adunm cele dou numere nu trebuie s avem niciodat transport. Exist (Q-

102

1)(Q-2)/2 de perechi de cifre din mulimea {1,...,Q-1} care adunate nu depesc valoarea Q1. Pentru poziiile 2,...,K, se poate folosi i cifra 0, astfel c exist (Q+1)Q/2 de perechi de
cifre din mulimea {0,...,Q-1} pentru care nu se obine transport la adunare.
Problema 7-16. Anticip (Lotul Naional de Informatic, Romnia 2005)
Un sumator pe un bit este un mic dispozitiv cu 3 intrri i 2 ieiri. El primete la intrare
X1, X2 i Ti. X1 i X2 sunt biii ce trebuie adunai, iar Ti este transportul anterior (ca intrare).
La ieire furnizeaz Y i To. Y este suma, iar To este transportul urmtor (ca ieire). Pentru a
formaliza aceste lucruri putem scrie:
Y = (X1 + X2 + Ti) mod 2 (mod este restul mpririi ntregi)
To = (X1 + X2 + Ti) div 2 (div este ctul mpririi ntregi)
Pentru a aduna numere pe N bii se folosesc N astfel de sumatoare. Ele sunt legate ca n
figura de mai jos, adic transportul de ieire al unui sumator este transportul de intrare pentru
urmtorul. Problema cu aceste sumatoare pe mai multi bii este c un sumator trebuie s
atepte transportul de la unitatea anterioar (exceptnd primul sumator). Dac un sumator pe
un bit face calculul ntr-o secund, atunci pentru un sumator pe N bii (format din N
sumatoare pe un bit) vor fi necesare N secunde. Pentru a mbunti performana acestor
sumatoare pe N bii s-au introdus nite uniti capabile s anticipeze transportul, adic
intrarea Ti. Aceste uniti verific datele de intrare precedente X1(i-1) i X2(i-1). Dac
amndou sunt 0 atunci Ti va fi 0, indiferent de ce primete acea unitate ca transport de
intrare. De asemenea, dac amndou sunt 1, atunci Ti va fi 1. Toate sumatoarele care
folosind anticipaia pot calcula transportul de la sumatorul precedent ncep calculul odat cu
primul sumator. Comunicarea transportului de la un sumator la urmtorul se realizeaz
instantaneu.
Cercettorii care au inventat aceste uniti de transport vor s tie cu ct mbuntesc
performana sistemului i au hotrt s se fac toate adunrile posibile, pentru a compara cu
vechiul sistem. Prin toate adunrile posibile se nelege c se va aduna orice numr pe N bii
cu orice numr pe N bii fix o dat (n total 4N adunri). Ei vor s tie ct au durat aceste
operaii, adic suma tuturor timpilor pentru fiecare adunare.
Exemplu: N=3 => Rspunsul este 128.

Soluie: Observm c o adunare se mparte n mai multe blocuri continue (n funcie de unii
sumatori care anticipeaz transportul) care se efectueaz n paralel (adic fiecare bloc ncepe
adunarea n acelai timp). Timpul de execuie al unei adunri este deci maximul dintre
lungimile blocurilor care se formeaz. Construim urmtoarea matrice:
A[i][j][k] = cte posibiliti de a aduna primii i bii, cu timpul maxim j (adic lungimea
maxim a unui bloc) i ultimul bloc de lungime k (bloc care poate continua), pentru k1
A[i][j][0] = cte posibiliti de a aduna primii i bii, cu timpul maxim j (adic lungimea
maxim a unui bloc) i ultimul bloc se termin dup sumatorul i)
Atunci cnd la bitul i+1 se vor aduna biii 0+1 sau 1+0, deoarece acetia nu pot fi
anticipai, nu vor crea un nou bloc i se va actualiza valoarea A[i+1][max(j,k+1)][k+1].

103

Atunci cnd la bitul i+1 se vor aduna biii 0+0 sau 1+1, deoarece acetia vor fi anticipai, se
va crea un nou bloc dup ei i se va actualiza valoarea A[i+1][max(j,k+1)][0].
Iniializm A[1][1][1] = A[1][1][0] = 2 (2 dintre posibiliti formeaz un bloc care se
termin, pentru c sumatorul nu poate fi anticipat, iar celelalte 2 formeaz un bloc care poate
continua). Deci recurena este urmtoarea:
A[i+1][max(j,k+1)][k+1] += 2A[i][j][k]
A[i+1][max(j,k+1)][0] += 2A[i][j][k]
Rspunsul cerut se va afla astfel:
R += j (A[N][j][0] + A[N][j][1] + + A[N][j][N]), 1jN.
Problema 7-17. J-Arbore (Happy Coding, infoarena)
J-arborele este un arbore infinit cu urmtoarele proprieti:
pe nivelul 1 al arborelui exist un singur nod (rdcina)
fiecare nod de pe nivelul i are exact i fii
muchiile arborelui se eticheteaz cu numere ntregi consecutive, mergnd pe nivele de
sus n jos (ncepnd cu primul nivel al arborelui) i pe fiecare nivel mergnd de la stanga
la dreapta
toate nodurile n afara rdcinii vor fi etichetate cu numere ntregi egale cu suma
muchiilor de pe drumul de la rdcina la nodul respectiv
Mai jos aveti primele nivele ale unui astfel de arbore.

Dndu-se un numar natural X (1X1018), vi se cere s spunei dac exist un nod


etichetat cu valoarea X i s afiai etichetele muchiilor de pe drumul de la rdcina spre
nodul respectiv.
Exemple:
X=100 => Nu exist.
X=1 => 1
X=2 => Nu exist
X=12 => 1 3 8
X=17 => 1 2 4 10
X=89 => 1 2 5 16 65
X=666 => 1 3 7 22 97 536

104

Soluie: Vom calcula N[i], reprezentnd cte noduri are arborele pe fiecare nivel i (ncepnd
de la 1), precum i valoarea de pe prima muchie i de pe ultima muchie dintre nivelul i-1 i
nivelul i (v1[i] i v2[i]). Avem N[1]=1 i v1[1]=v2[1]=0. n cazul general, N[i]=N[i-1](i-1),
v1[i]=v2[i-1]+1 i v2[i]=v1[i]+N[i]-1. De asemenea, vom calcula cea mai mic i cea mai
mare etichet a unui nod de pe nivelul i: vmin[i]=vmin[i-1]+v1[i] i vmax[i]=vmax[i1]+v2[i] (vmin[1]=vmax[1]=0).
Vom observa c 24 de nivele ale arborelui ajung pentru limitele date. Pentru fiecare
numr X dat vom gsi nivelul pe care s-ar afla (dac numrul exist n arbore), folosind
valorile vmin[i] i vmax[i] (cutm acel nivel i pentru care vmin[i]Xvmax[i]; o cutare
secvenial este suficient, deoarece exist doar 24 de nivele care ne intereseaz pentru
limitele date; totui, se poate utiliza i cutarea binar, deoarece avem vmin[i]>vmax[i-1]).
Dac nu gsim niciun nivel cu proprietatea dorit, numrul X nu exist ca etichet n arbore.
Apoi, pentru a determina unde se afl numrul X, vom ncerca s determinm poziia
acestuia in cadrul nivelului i. Pentru aceasta vom realiza o cutare binar. Vom scrie o
funcie care va determina ce valoare se afl pe poziia p de pe nivelul q: aceast valoare este
1, dac nivelul este 1 (deoarece exist un singur nod pe nivelul 1), sau valoarea de pe poziia
p/q de pe nivelul q-1, la care se adaug v1[q]+p (considernd poziiile numerotate de la 0 n
cadrul unui nivel). Vom determina astfel dac numrul X exist i, dac da, vom reconstitui
drumul de la el pn la radacina arborelui (ceea ce facem, oricum, n cadrul funciei de
determinare a valorii de pe o poziie p din cadrul unui nivel q; ultima muchie are valoarea
v1[q]+p, dup care ne mutm pe poziia corespunztoare de pe nivelul de deasupra, .a.m.d.
pn ajungem pe nivelul 1).
Problema 7-18. Numrul punctelor de intersecie ale diagonalelor (infoarena)
Se consider un poligon convex cu N (3N100.000) vrfuri. tiind c oricare trei
diagonale ale poligonului nu se intersecteaz n acelai punct, determinai numrul total de
puncte de intersecie ale diagonalelor poligonului.
Exemplu: N=4 => Rspunsul este 1.
Soluie: Oricare 4 vrfuri ale poligonului determin dou diagonale ale poligonului care se
intersecteaz. Deci rspunsul este C(N,4) (combinri de N luate cte 4). O soluie cu
complexitatea O(N) este urmtoarea. Vom calcula NP(i)=numrul punctelor de intersecie ale
diagonalelor unui poligon cu i vrfuri. Vom ncepe cu NP(3)=0 i vom calcula NP(i), cu i
variind cresctor de la 4 la N. Pentru a calcula NP(i) pe baza lui NP(i-1) va trebui s
calculm cte puncte de intersecie noi aduce adugarea unui nou vrf. Vrful i are i-3
diagonale adiacente. Numrul de puncte de intersecie suplimentare NPS(i) este suma
valorilor j(i-2-j) (1ji-3). Dac am calcula aceast sum n timp liniar, am obine o
complexitate O(N2). Putem, ns, s calculm NPS(i) n O(1), pe baza lui NPS(i-1) (ncepnd
cu NPS(3)=0). Avem NPS(i)=NPS(i-1)+(i-4)(i-3)/2+i-3.
Problema 7-19. Numrul de zone interioare determinate de diagonalele unui poligon
convex (UVA)
Se consider un poligon convex cu N (3N100.000) vrfuri. tiind c oricare trei
diagonale ale poligonului nu se intersecteaz n acelai punct, determinai numrul total de
zone delimitate de diagonale n interiorul poligonului.
Exemplu: N=4 => Rspunsul este 4.

105

Soluie: Rspunsul este (N-1)(N-2)(N2-3N+12)/24 (demonstrai !).


Problema 7-20. Codificare numeric a unui ir de paranteze (UVA)
ntruct irurile formate din paranteze sunt greu de urmrit cu ochiul liber, s-a propus
nlocuirea parantezelor prin numere. Astfel, o pereche de paranteze care se nchid reciproc
sunt nlocuite n ir prin acelai numr x. De exemplu, irul (()(())) poate fi scris ca 1 2 2 1 3
3 1 1. Vedem, ns, imediat, c irul 1 2 2 1 3 3 1 1 nu are o interpretare unic c ir de
paranteze. De exemplu, el ar putea proveni i de la irul de paranteze (())()(). Pentru un ir de
numere dat, determinai dac exist mai mult de K1 interpretri ale sale ca iruri de
paranteze.
Soluie: Vom calcula NP(i,j)=numrul de iruri de paranteze din care poate rezulta
subsecvena de numere dintre poziiile i i j din irul S dat. Avem NP(i,i-1)=1. Vom
considera perechile (i,j) n ordine cresctoare a lui j-i. Dac S(i)=S(j) (numrul de pe poziia i
din S este egal cu numrul de pe poziia j din S), atunci iniializm NP(i,j)=NP(i+1, j-1);
altfel, iniializm NP(i,j)=0. Apoi considerm toate poziiile p (i+1pj-1). Dac S(i)=S(p),
atunci incrementm NP(i,j) cu NP(i+1,p-1)NP(p+1, j) (considerm c paranteza care se
deschide pe poziia i se nchide pe poziia p). Dup fiecare incrementare, dac NP(i,j)>(K+1),
setm NP(i,j)=K+1. Dac NP(1,N)=K+1, atunci exist cel puin K+1 iruri de paranteze
care pot fi codificate folosind irul S dat (N=lungimea irului S).
Problema 7-21. Grdin liniar (Olimpiada Internaional de Informatic, 2008, enun
modificat)
Se consider iruri formate din caracterele L i P (unde L este lexicografic mai
mic dect P), cu proprietatea c diferena (n valoare absolut) dintre numrul de L-uri
i numrul de P-uri din orice subsecven de caractere consecutive este cel mult D
(1D5). Dndu-se un astfel de ir cu N caractere (1N1.000.000), determinai al ctelea ir
este (modulo un numr M) n ordine lexicografic, dintre toate irurile care au proprietile
menionate.
Exemplu: irul PLPPL, D=2, M=7 => Rspunsul este 5. irul este, de fapt, al 12-lea
ir n ordine lexicografic, iar 12 mod 7=5.
Soluie: Vom considera c unui caracter L i corespunde valoarea -1, iar unui caracter P
i corespunde valoarea +1. Astfel, vom considera doar iruri alctuite din numerele -1 i +1.
Vom calcula NS(k, pmin, pmax)=numrul de iruri (cu elemente egale cu +1 sau -1), pentru
care cea mai mic sum prefix (de la stnga la dreapta) este mai mare sau egal cu pmin, iar
cea mai mare sum prefix este mai mic sau egal cu pmax. Observm c prima sum prefix
este ntotdeauna 0, obinnd c pmin0 i pmax0. De asemenea, din condiiile impuse de
problem, vom avea pmin-D i pmaxD.
Pentru k=0, avem NS(k, pmin, pmax)=1 mod M (-Dpmin0; 0pmaxD). Pentru k1 i
fiecare pereche (pmin, pmax), vom proceda dup cum urmeaz. Vom iniializa NS(k, pmin,
pmax)=0. Apoi vom considera, pe rnd, fiecare din cele 2 caractere (-1 sau +1) care ar putea
fi primul caracter din ir. S presupunem c acest caracter este Q. Vom calcula valorile
nextpmin=pmin-Q i nextpmax=pmax-Q. Dac nextpmin>0 sau nextpmax<0, nu vom
considera mai departe cazul caracterului Q (pentru tuplul (k, pmin, pmax)). Altfel, vom seta
nextpmin=max{nextpmin, -D} i nextpmax=min{nextpmax, D}. nextpmin i nextpmax

106

reprezint suma prefix minim i, respectiv maxim, dac am ncepe calcularea sumelor
prefix de la al doilea caracter ncolo. Astfel, vom seta NS(k, pmin, pmax)=(NS(k, pmin,
pmax)+NS(k-1, nextpmin, nextpmax)) mod M. NS(N, -D, D) reprezint numrul de iruri de
lungime N care au diferena (n valoare absolut) dintre numrul de L-uri i numrul de
P-uri din fiecare subsecven continu, cel mult egal cu D.
O generalizare a problemei s-ar fi putut realiza dac impuneam ca diferena dintre
numrul de L-uri i numrul de P-uri din orice subsecven continu s fie cel mult LP,
iar cea dintre numrul de P-uri i cel de L-uri s fie cel mult PL. n algoritmul folosit
am fi calculat pmin ntre LP i 0, pmax ntre 0 i PL, iar naintea de mrirea valorii lui NS(k,
pmin, pmax), am fi nlocuit instruciunile nextpmin=max{nextpmin, -D} cu nextpmin=
max{nextpmin, -LP}, i nextpmax=min{nextpmax, D}, cu nextpmax=max{nextpmax, PL}.
NS(N, -LP, PL) ar fi fost numrul de iruri de lungime N cu proprietile impuse.
S vedem acum cum vom determina, pentru un ir S(1), ..., S(N) dat, al ctelea ir n
ordine lexicografic este. Vom menine un contor cnt (iniializat la 0), care, la sfrit (dup
parcurgerea irului S), va reprezenta numrul de iruri mai mici din punct de vedere
lexicografic dect irul S. Aadar, rspunsul va fi (cnt+1) mod M. Vom menine i valorile p,
pmin i pmax. p reprezint suma prefix curent, iar pmin i pmax reprezint suma minim,
respectiv maxim, a unei sume sufix, calculat de la caracterul curent al irului, spre stnga.
Iniial, p=pmin=pmax=0. n continuare, vom parcurge irul de la stnga la dreapta, cu o
variabil i (1iN).
S presupunem c am ajuns la poziia i. Dac S(i)=L, atunci vom efectua doar
urmtoarele aciuni:
(1) p=p-1;
(2) pmin=min{pmin-1, -1};
(3) pmax=max{pmax-1, 0}.
Dac S(i)=P, vom calcula cte iruri S cu proprietile date exist, astfel nct
S(j)=S(j), pentru 1ji-1, dar S(i)=L. Fie nextpmin=min{pmin-1, -1} i
nextpmax=max{pmax-1, -1}. Dac nextpmin-D i nextpmaxD, atunci vom continua,
efectund urmtorii pai:
(1) nextpmin=min{0, nextpmin} i nextpmax=max{0, nextpmax};
(2) nextpmin=-D-nextpmin i nextpmax=D-nextpmax;
(3) dac Dnextpmin0 i 0nextpmaxD, atunci vom seta cnt=(cnt+NS(N-i, nextpmin,
nextpmax)) mod M.
Dup aceti pai (pentru cazul S(i)=P), va trebui s actualizm valorile p, pmin i
pmax, nainte de a trece la poziia i+1. Vom seta:
(1) p=p+1;
(2) pmin=min{pmin+1, 0};
(3) pmax=max{pmax+1, 1}.
Complexitatea algoritmului descris este O(N(D+1)2+N).
Problema 7-22. Munte
Linia orizontului dintr-un peisaj se poate desena pe un caroiaj, cu ajutorul caracterelor '/'
i '\', aceasta conturndu-se ntr-un zig-zag obinuit. O linie a orizontului este corect dac
este desenat cu acelai numr de caractere '/', respectiv '\' i fiecare coloan a caroiajului
conine un singur caracter. De asemenea, aceast linie trebuie s porneasc dintr-o celul a
caroiajului aflat la nivelul mrii i se termin tot ntr-o celul aflat la nivelul mrii. Pe
parcursul trasrii, linia nu coboar niciodat sub nivelul mrii. Linia orizontului ncepe cu

107

caracterul '/' i se termin cu caracterul '\'. Dup caracterul '/' poate fi plasat pe coloana
urmtoare caracterul '/' pe linia superioar sau caracterul '\' pe aceeai linie. Analog, dup
caracterul '\' poate fi plasat pe coloana urmtoare caracterul '\' pe linia inferioar sau
caracterul '/' pe aceeai linie. Definim vrful muntelui ca fiind format din dou caractere
/\ situate pe aceeai linie i pe coloane alturate. Calculai numrul de posibiliti de a trasa
linii ale orizontului cu un numr precizat (n) de perechi de caractere '/' i '\', astfel nct s
existe exact k vrfuri.
Exemplu: n=4, k=3 => Rspunsul este 6.
Soluie: Vom calcula urmtoarele valori Num(i,j,q,l)=numrul de iruri de caractere formate
din i caractere /, j caractere \, conine q vrfuri, iar ultimul caracter al irului este l (l=/
sau \); avem 0jin i 0qmin{j,k}. Vom calcula valorile Num(i,j,q,l) n ordine
cresctoare a sumei (i+j). Iniial avem Num(1,0,0,/)=1 i Num(1,0,0,\)=Num(0,1,*,*)=0.
Pentru (i+j)2 (ji) i orice valoare a lui q (0qj) avem:
1) Num(i,j,q,/)=Num(i-1,j,q,/)+Num(i-1,j,q,\);
2) Num(i,j,q,\)=(Num(i,j-1,q,\) (sau 0, dac j=0)) + (Num(i,j-1,q-1,/) (sau 0, dac j=0
sau q=0)). Rezultatul final l avem n Num(n,n,k,\).
Problema 7-23. Numrul de Cuplaje Perfecte ntr-un Graf Bipartit aproape Complet
Considerm un graf bipartit ce are N noduri n partea stng i N noduri n partea dreapt.
Exist muchie (i,j) ntre oricare nod i (1iN) din partea stng i oricare nod j (1jN) din
partea dreapt, cu excepia muchiilor (1,1), ..., (P,P) (0PN). Determinai numrul de
cuplaje perfecte ce se pot forma n acest graf.
Soluie: Vom folosi principiul includerii i excluderii. Vom genera toate submulimile
mulimii {1, ..., P}. Fie S submulimea curent i fie |S| numrul de elemente din S (0|S|P).
Fie NC(S)=numrul de cuplaje care conin muchiile (i,i), cu i S. Avem NC(S)=(N-|S|)!.
Rspunsul este egal cu suma valorilor (-1)|S|NC(S) (S {1,...,P}). Aceast abordare are
complexitatea O(2P). Observnd c toate valorile NC(S) sunt egale pentru toate mulimile S
avnd acelai numr de elemente, rspunsul devine egal cu suma valorilor (-1)iC(P,i)(N-i)!
(0iP). Am notat prin C(a,b)=combinri de a elemente luate cte b. Complexitatea acestui
algoritm este O(P). La calculul complexitilor am ignorat factorul ce presupune lucrul cu
numere mari, avnd O(N) cifre. Pentru o analiz corect, complexitile menionate trebuie
nmulite cu O(N).
Problema 7-24. Numere (TIMUS)
Se consider irul infinit X format prin concatenarea tuturor numerelor naturale n baza B
(2B10). De exemplu, primele cifre ale acestui ir pentru B=10 sunt:
123456789101112131415161718192021... Dndu-se un ir S (coninnd numai cifre de la 0
la B-1), determinai la ce poziie n X apare S pentru prima dat. Poziiile lui X sunt
numerotate ncepnd de la 1. irul S apare la o poziie p n X dac X(p+i-1)=S(i) (1ilen(S)).
Lungimea lui S este cel mult 300.
Soluie: Vom dori s determinm cel mai mic numr natural M n interiorul cruia poate
ncepe irul S, astfel nct acesta s se potriveasc peste restul cifrelor din M, ct i peste
cifrele numerelor ce l urmeaz pe M n X. Vom iniializa pe M la S (dac S(1)>0) sau la
numrul care are prima cifr 1, iar restul cifrelor sunt cele corespunztoare lui S (dac

108

S(1)=0). De asemenea, vom reine i poziia minim poz din cadrul lui M la care poate
ncepe irul S (pentru iniializare vom avea poz=1 dac S(1)>0, respectiv poz=2, dac
S(1)=0).
Vom considera acum dou cazuri. n primul caz vom considera c exist un numr Q
complet n interiorul lui S. Pentru aceasta, vom considera toate posibilitile pentru acest
numr Q (adic toate perechile (i,j), cu 1ijlen(S), unde Q=S(i)S(i+1)...S(j)). Dup fixarea
acestui numr Q, trebuie s verificm dac presupunerea fcut este valid. Pentru aceasta
vom iniializa Q=Q i poz=j. Ct timp poz<len(S) vom efectua urmtorii pai:
(1) Q=Q+1;
(2) verificm dac Q se potrivete peste cifrele lui S, ncepnd de la poziia poz+1 i
pn la min{len(S), poz+len(Q)};
(3) dac rspunsul este afirmativ, atunci setm poz=min{len(S), poz+len(Q)}, altfel
oprim iteraiile ciclului.
Dac la final am obinut poz=len(S), atunci S se potrivete peste numerele ce i urmeaz
lui Q. Vom verifica acum, n mod similar, dac S se potrivete peste numerele ce i preced lui
Q. Iniializm Q=Q, poz=i i pozQ=1. Ct timp poz>1 i Q>1 efectum urmtorii pai:
(1) Q=Q-1;
(2) verificm dac Q se potrivete peste poziiile lui S, ncepnd de la poz-1 i pn la
max{poz-len(Q), 1}, efectund comparaiile de la ultima cifr a lui Q spre prima (respectiv
de la poz-1 descresctor, pentru poziiile lui S);
(3) dac rspunsul este afirmativ, atunci: dac poz>len(Q) atunci pozQ=1 altfel
pozQ=len(Q)-poz+2; apoi setm poz=max{poz-len(Q), 1} (dac rspunsul nu e afirmativ,
oprim ciclul).
Dac verificrile n ambele sensuri au determinat rezultate valide, atunci: dac (Q<M)
sau (Q=M i pozQ<poz) vom seta M=Q i poz=pozQ.
Al doilea caz consider c nu exist niciun numr Q aflat complet n interiorul lui S.
Pentru acest caz vom considera toate prefixele Q=S(1)...S(i) (len(S)/2ilen(S)-1 i
S(i+1)>0). Fie Q=Q+1. Dac len(Q)>len(Q) (la adunarea cu 1 s-a generat transport),
atunci pstrm n Q doar ultimele len(Q) cifre, i setm t=1 (altfel lsm Q aa cum e i
setm t=0). Vom ncerca acum toate poziiile j (i+2jlen(S)+1) i vom verifica dac Q se
potrivete peste cifrele S(j)S(j+1)...S(len(S)), adic dac aceste cifre reprezint un prefix al
lui Q (dac j=len(S)+1, atunci Q se potrivete n mod implicit). Dac am obinut o potrivire
pentru o poziie j, atunci fie Q=S(i+1)...S(j-1). Setm Q=Q-t, apoi obinem MQ prin
concatenarea lui Q i a lui Q i setm pozQ=len(Q)+1. Dac (Q>0) i ((MQ<M) sau
(MQ=M i pozQ<poz)) atunci setm M=MQ i poz=pozQ.
Dup considerarea tuturor acestor cazuri am gsit cel mai mic numr M n interiorul
cruia poate ncepe numrul S (i poziia minim poz la care ncepe). Mai trebuie doar s
determinm cte cifre au n total numerele de la 1 pn la M-1. Fie ndigits(M-1) acest numr.
Rezultatul final va fi ndigits(M-1)+poz.
Pentru a calcula ndigits(Q) (pentru un numr oarecare Q), vom proceda dup cum
urmeaz. Dac Q=0, rezultatul este 0. Altfel, iniializm rez=0. Pentru i=1,...,len(Q)-1
incrementm rez cu i(B-1)Bi-1 (exist (B-1)Bi-1 numere de i cifre, care nu ncep cu cifra 0).
Apoi mai trebuie s adunm la rez suma cifrelor tuturor numerelor de len(Q) cifre mai mici
sau egale cu Q. Vom parcurge, pe rnd, cifrele numrului Q (cu i de la 1 la len(Q)). Pentru
i=1 adunm la rez valoarea len(Q)(Q(i)-1)Blen(Q)-i. Pentru i>1, adunm la rez valoarea
len(Q)Q(i)Blen(Q)-i. La final mai adugm la rez valoarea len(Q) (pentru a aduna i cifrele
numrului Q). rez va reprezenta rezultatul ntors de ndigits(Q).

109

Trebuie menionat c o implementare a acestei probleme trebuie s lucreze cu numere


mari (de sute de cifre). Dup fiecare operaie, rezultatul trebuie s fie un numr valid (adic
fr 0-uri la nceput). De asemenea, toate operaiile trebuie s se efectueze n baza B.
Problema 7-25. Borg (ONI 2006)
Oricine a urmrit serialul Star Trek i aduce aminte de borgi i de nava lor spaial n
form de cub. Una dintre problemele pe care i-au pus-o nainte de a construi nava a fost
urmtoarea. Nava borgilor are forma unui paralelipiped dreptunghic de dimensiuni NxMxH,
mprit n camere de dimensiune 1x1x1. Pentru ca nava s poat funciona, n aceste camere
trebuie plasate K motoare de propulsie, n fiecare camer putndu-se plasa cel mult un motor.
O camer poate fi identificat printr-un triplet (a, b, c), unde 1 a N, 1 b M, 1 c H,
reprezentnd coordonatele sale. Un plan al paralelipipedului este o mulime de camere de
unul dintre urmtoarele 3 tipuri:
{(a, b, c) | a fixat, 1 b M, 1 c H} n total sunt N plane de acest tip;
{(a, b, c) | b fixat, 1 a N, 1 c H} n total sunt M plane de acest tip;
{(a, b, c) | c fixat, 1 a N, 1 b M} n total sunt H plane de acest tip.
Se cere s se gseasc R, numrul de moduri (modulo 30103) n care se pot plasa cele K
motoare, astfel nct orice plan al paralelipipedului s conin cel puin o camer ocupat de
un motor.
Soluie: Numrul total de moduri n care se pot plasa K motoare n paralelipiped, fr
restricia ca fiecare plan s conin cel puin un motor, este

C NK*M *H . Din acestea, trebuie s

le scdem pe cele care nu sunt bune. Dac notm cu

X i (1iN) numrul de moduri n care


se pot plasa cele K motoare astfel nct planul i (de tip 1) s fie gol, cu Yi (1iM) numrul
de moduri astfel nct planul i (de tip 2) s fie gol i cu
astfel

nct

C NK*M *H

planul

UX
1 i N

(de

UY

tip

1i M

3)

UZ

fie

gol,

Z i (1i H) numrul de moduri


atunci

numrul

cutat

va

fi

. Cardinalul reuniunii se poate dezvolta cu

1i H

principiul includerii i excluderii, fiecare mulime rezultat coninnd o intersecie de a


mulimi X, b mulimi Y i c mulimi Z. Cardinalul unei astfel de mulimi ar reprezenta
numrul de moduri n care se pot pune K motoare, astfel nct a dintre planele de tip 1 s fie
goale, b dintre planele de tip 2 s fie goale i c dintre planele de tip 3 s fie goale, adic ar fi

C (KN a )*( M b )*( H c ) . n dezvoltarea produs de principiul includerii i excluderii vor fi


C Na * C Mb * C Hc astfel de mulimi.
N

Aadar numrul total va fi

(1)

a +b+c

* C Na * C Mb * C Hc * C (KN a )*( M b )*( H c ) .

a =1 b =1 c =1

Se observ c este nevoie de toate combinrile pn la maximul dintre N, M i H, dar numai


de cele care au K sus pentru restul. Acestea se pot calcula n complexitatea O(NMHK)
folosind regula general

C nk = C nk11 + C nk1 (kK i nNMH). Pentru a reduce

complexitatea la O(NMH), putem calcula

C nK direct din C nK1 , folosindu-ne de faptul ca

110

numrul 30103 este prim i deci orice numr are un invers modular (care nmulit cu el d
restul 1 la mprirea la 30103).

111

Capitolul 8. Teoria Jocurilor


Problema 8-1. Jocul cu pietre (TIMUS)
Avem la dispoziie N (1N100.000) grmezi. Fiecare grmad i (1iN) conine P(i)
pietre (0i101000). Doi juctori efectueaz mutri alternativ. O mutare const n alegerea
unei grmezi i i eliminarea a X pietre din grmad, unde X este o putere a lui 2 (1, 2, 4, 8,
16, ...), cu condiia ca grmada s mai conin cel puin X pietre. Juctorul care nu mai poate
efectua nicio mutare atunci cnd i vine rndul pierde jocul. Determinai cine ctig
(juctorul 1 fiind cel care efectueaz prima mutare), considernd c ambii juctori joac
optim.
Soluie: Un joc este echivalent cu o grmad de pietre. O stare a unui joc simplu este
determinat prin numrul de pietre din cadrul grmezii. Vom ncerca s calculm
G(Q)=numrul Grundy asociat unei grmezi ce conine Q pietre.
Avem G(0)=0. Pentru Q1, putem ajunge n orice stare Q0, cu proprietatea c Q-Q=2i
(i0). Aplicnd teoria numerelor Sprague-Grundy, obinem G(1)=1, G(2)=2, G(3)=0,
G(4)=1, G(5)=2, G(6)=0, G(7)=1, G(8)=2, .a.m.d. Observm uor un tipar: G(Q)=Q mod 3
(restul mpririi lui Q la 3). Aceast regul poate fi demonstrat prin inducie. Dintr-o stare
Q putem ajunge numai n stri Q astfel nct (Q mod 3)(Q mod 3). Pentru Q2 putem
ajunge mereu n stri cu resturi din mulimea {0,1,2}\{Q mod 3} (de exemplu, strile Q-1 i
Q-2 sunt strile cu 2 resturi diferite de (Q mod 3)). Presupunnd c regula este adevrat
pn la un numr de pietre R, atunci, folosind aceast observaie, ea va fi adevrat i pentru
R+1.
Pentru jocul compus calculm valoarea Z=G(P(1)) xor G(P(2)) xor ... xor G(P(N)) (unde,
dup cum am artat deja, G(P(i))=P(i) mod 3). Dac Z>0, primul juctor va ctiga jocul;
altfel, al doilea juctor are strategie sigur de ctig.
Problema 8-2. DoiPatru (Lotul Naional de Informatic, Romnia 2002)
Membrii Lotului Naional de Informatic sunt foarte mndri de noul joc inventat de ei, pe
care l-au denumit asemntor cu o problem de la Olimpiada Internaional de Informatic
din 2001, care le-a plcut foarte mult. Astfel, jocul se numete DoiPatru. Pentru acest joc se
folosesc N (1N30) grmezi, fiecare coninnd cel puin 0 i cel mult 4 bile. Numrul total
de bile din toate grmezile este 2N. Doi juctori mut alternativ. Atunci cnd i vine rndul,
fiecare juctor este obligat s efectueze o mutare valid. O mutare valid const din alegerea
a dou grmezi, dintre care prima grmad are mai multe bile dect cea de a doua. Juctorul
ia o bil din prima grmad i o mut n cealalt. Mutarea se consider valid, doar dac
numrul de bile rezultat n a doua grmad dup mutarea bilei nu este mai mare dect
numrul de bile rmas n prima grmad. Jocul se termin atunci cnd nu mai poate fi
efectuat nici o mutare valid (dac v gndii puin, vei constata c acest lucru se ntmpl
atunci cnd fiecare grmad conine dou bile).
Ctigtorul jocului este desemnat cel care deine mai multe grmezi la sfritul jocului.
Bineneles, dac cei doi juctori dein un numr egal de grmezi, jocul se consider a fi
remiz.
Un juctor deine o grmad dac grmada are dou bile, iar acest numr (de dou bile) a
rezultat n urma unei mutri efectuate de juctorul respectiv. De exemplu, dac un juctor

112

alege o grmad cu 4 bile i una cu o bil, n urma efecturii mutrii, el va deine cea de-a
doua grmad (care va avea dou bile), dar prima nu va aparine deocamdat nici unuia
dintre juctori. Dac alege o grmad cu 3 bile i una cu 0 bile, juctorul va deveni
proprietarul primei grmezi, deoarece, n urma mutrii efectuate, grmada respectiv va
rmne cu dou bile. n cazul n care alege o grmad cu 3 bile i una cu o bil, dup
efectuarea mutrii, el va deine ambele grmezi (amndou au acum dou bile).
Dac un juctor este proprietarul unei grmezi la un moment dat n timpul jocului, nu
nseamn c aceast grmad va rmne n posesia lui pn la sfrit. De exemplu, s
presupunem c juctorul 1 deine o grmad cu dou bile i este rndul juctorului 2 s mute.
Dac acesta alege o grmad cu 4 bile i grmada cu dou bile ce aparine juctorului 1, dup
efectuarea mutrii, ambele grmezi vor avea 3 bile, iar numrul de grmezi aflate n posesia
juctorului 1 va scdea cu 1 (grmada deinut de el anterior nu mai aparine nici unuia din
cei doi juctori, cci nu mai are dou bile).
Dac la nceputul jocului exist unele grmezi avnd dou bile, acestea sunt distribuite n
mod egal celor doi juctori. Dac numrul de grmezi cu dou bile este impar, atunci
juctorul 2 va primi cu o grmad mai mult dect juctorul 1. Juctorul 1 este cel care
efectueaz prima mutare. Pentru un N dat i un set de configuraii iniiale ale jocului cu N
grmezi, decidei rezultatul fiecrei configuraii de joc (considernd c ambii juctori joac
optim).
Exemple:
N=5
0 3 4 1 2 => Ctig primul juctor.
2 2 2 2 2 => Ctig cel de-al doilea juctor.
1 1 2 2 4 => Ctig primul juctor.
4 3 2 1 0 => Ctig primul juctor.
Soluie: O stare a jocului este o pereche (C, k), unde C este o configuraie a jocului (un ir de
N numere ntre 0 i 4, sortate cresctor, deoarece ordinea lor nu este important, a cror sum
este 2N), iar k reprezint numrul de grmezi cu 2 bile deinute de juctorul aflat la mutare
(observm c nu conteaz care grmezi cu 2 bile sunt deinute de juctorul aflat la mutare i
care de adversar; putem presupune c primele k grmezi cu 2 bile din configuraia C aparin
juctorului aflat la mutare, iar celelalte grmezi cu 2 bile aparin adversarului). Pentru N=30
exist aproximativ 1000 de configuraii C, iar k poate lua valori ntre 0 i N. Astfel, graful
strilor conine n jur de 30.000 de noduri.
Pentru fiecare stare S=(C,t) vom calcula bestRes(S), conform algoritmului descris la
nceputul capitolului. Vom ncerca, pe rnd, fiecare mutare posibil i, dac mutarea poate fi
efectuat, vom genera starea S n care ajungem. Dac nu am calculat nc bestRes(S),
apelm recursiv funcia de calcul pentru S (aceasta este o versiune recursiv a algoritmului
descris la nceputul capitolului). Dac dintr-o stare S=(C,t) nu se poate ajunge n nicio alt
stare S, atunci C conine numai grmezi cu cte 2 bile. Dac N e par i k>N/2, atunci
bestRes[S]=victorie;
dac
k=N/2,
atunci
bestRes[S]=remiz;
dac
k<N/2,
bestRes[S]=nfrngere. Pentru N impar, dac k>N/2, atunci bestRes[S]=victorie, altfel
bestRes[S]=nfrngere. Pentru celelalte stri S, dup ce am calculat bestRes[S] pentru toate
strile S n care putem ajunge din S, vom folosi regulile din algoritmul descris la nceputul
capitolului.

113

Problema 8-3. Maxi-Nim (TIMUS)


Se dau N (1N100.000) grmezi cu pietre. Fiecare grmad i (1iN) conine P(i) pietre
(0P(i)2.000.000.000). Doi juctori efectueaz mutri alternativ. O mutare const n
alegerea unei grmezi j cu proprietatea c P(j)P(i) (oricare ar fi 1iN) (adic alegerea
uneia dintre grmezile care conin un numr maxim de pietre) i extragerea a unui numr X
de pietre (X poate fi orice numr ntre 1 i P(j)). Cel care extrage ultima piatr ctig.
Determinai ce juctor va ctiga, n condiiile n care ambii vor juca optim (juctorul 1 este
cel care ncepe jocul).
Soluie: S presupunem c Z este numrul maxim de pietre din orice grmad
(Z=max{P(i)|1iN}). Fie NZ numrul de grmezi i astfel nct P(i)=Z. Dac NZ mod 2=1,
atunci juctorul 1 are strategie sigur de ctig. Altfel, juctorul 2 are strategie sigur de
ctig. Demonstraia este simpl. Ct timp NZ>1 juctorul 1 poate lua orice numr de pietre
din orice grmad cu Z pietre. Cnd NZ=1 va fi rndul juctorului 1 s mute (deoarece
numrul iniial de grmezi cu Z pietre era impar). Dac grmada cu Z pietre este singura
grmad cu numr nenul de pietre, atunci el va lua toate pietrele i va ctiga jocul. Altfel,
fie Z al doilea numr maxim de pietre dintr-o grmad (Z=max{P(i)|1iN, P(i)<Z}) i fie
NZ numrul de grmezi cu Z pietre. Dac NZ este impar, atunci el va lua din grmada cu Z
pietre (Z-Z) pietre, reducnd-o la o grmad cu Z pietre i lsndu-i adversarul ntr-o stare
n care numrul de grmezi cu numr maxim de pietre este par. Dac NZ este par, atunci el
va reduce grmada cu Z pietre la o grmad cu Z<Z pietre (lund Z-Z pietre din ea).
Dac juctorul 1 are la nceput n fa un numr par de grmezi cu numr maxim Z de pietre,
atunci dup prima mutare juctorul 2 se va afla n situaia n care are un numr impar de
grmezi cu numr maxim de pietre i va putea aplica staregia descris mai sus.
Din punct de vedere al implementrii, se poate menine un hash (sau arbore echilibrat) cu
perechi (cheie=Z, valoare=numr de grmezi cu numr de pietre egal cu Z) i un heap cu
perechi (P(i), i). Elementele din heap sunt ordonate dup P(i). Astfel, se poate afla imediat
numrul maxim de pietre dintr-o grmad, precum i numrul de grmezi care au acest
numr. Atunci cnd se iau X pietre dintr-o grmad i, se terge din heap perechea (P(i), i) i
se decrementeaz n hash numrul de grmezi cu P(i) pietre (dac acest numr ajunge la 0,
atunci perechea respectiv se terge din hash). Apoi se setaz P(i)=P(i)-X i, dac P(i)>0, se
insereaz n heap perechea (P(i), i). n hash se incrementeaz cu 1 numrul de grmezi cu
P(i) pietre (dac acest numr era 0, atunci se insereaz perechea (P(i), 1)). Atunci cnd
juctorul aflat la mutare rmne cu o singur grmad cu numr maxim Z de pietre, acesta
trebuie s verifice dac este ultima grmad verific dac este singurul element din heap.
Dac nu este ultima grmad, el trebuie s determine numrul maxim de pietre Z<Z. Pentru
aceasta se poate uita la cei (maxim) 2 fii ai nodului rdcin din max-heap. Al doilea maxim
se afl ntr-unul din aceti doi fii. Apoi caut perechea (Z, NZ) n hash, pentru a determina
numrul de grmezi NZ care au Z pietre.
Problema 8-4. Leftist Nim (TIMUS)
Se dau N (1N100.000) grmezi cu pietre, aezate n ordine cresctoare de la stnga la
dreapta. Fiecare grmad i (1iN) conine P(i) pietre (1P(i)2.000.000.000). Doi juctori
efectueaz mutri alternativ. Fie j grmada cu indice cel mai mic care conine P(j)>0 pietre.
O mutare const n extragerea a unui numr X de pietre (X poate fi orice numr ntre 1 i
P(j)) din grmada j. Cel care extrage ultima piatr ctig. Determinai ce juctor va ctiga,
n condiiile n care ambii vor juca optim (juctorul 1 este cel care ncepe jocul).

114

Soluie: Vom calcula win(j)=1, dac juctorul aflat la mutare are strategie sigur de ctig, n
cazul n care jocul const doar din grmezile j, j+1, ..., N (i 0, altfel). Avem win(N)=1
(deoarece juctorul aflat la mutare poate lua toate pietrele din grmada N). Pentru 1jN-1
(n ordinea descresctoare) avem: dac P(j)=1 atunci win(j)=1-win(j+1); altfel (dac P(j)>1),
win(j)=1.
Jocul se va desfura astfel. S presupunem c juctorul care are strategie sigur de ctig
este primul care urmeaz s ia pietre din grmada j, cu win(j)=1 (1jN-1). Dac
win(j+1)=0, atunci el va lua toate cele P(j) pietre. Dac win(j+1)=1, atunci el va lua P(j)-1
pietre; astfel, la urmtoarea mutare, adversarul va lua ultima piatr din grmada j, iar
juctorul 1 va fi primul juctor care va lua pietre din grmada j+1 (care are win(j+1)=1).
Problema 8-5. Vot public (UVA)
n societatea indienilor Uxuhul, votul asupra chestiunilor celor mai importante din
societate se desfura dup cum urmeaz. Consiliul celor mai nelepi indieni se adunau i
cei N (1N10.000) membri ai si se aranjau n linie, n ordine cresctoare a nelepciunii
(cel mai nelept membru al consilului era ultimul). Apoi, n aceast ordine, membrii
consilului i exprimau votul, n felul urmtor. Votul poate avea M (1M50) stri. Iniial,
starea votului este Q (1QM). Cnd vine rndul unui membru i, acesta poate schimba starea
curent a votului. Pentru fiecare membru i (1iN) i fiecare stare curent posibil s (1sM),
se cunoate lista L(i,s) a strilor n care poate fi modificat starea curent s (L(i,s) va conine
cel puin un element; s poate face parte din L(i,s)).
Dup ce voteaz i ultimul membru, rezultatul final al votului este starea n care a fost
adus votul de ultimul membru. Fiecare membru i are, de asemenea, o preferin (distinct)
pentru fiecare stare posibil s, Pref(i,s). Mai exact, dac Pref(i,sa)>Pref(i,sb), atunci el ar
dori ca rezultatul final al votului s fie sa, mai degrab dect sb. Atunci cnd voteaz, fiecare
membru modific starea curent a votului n aa fel nct rezultatul final s aib o preferin
ct mai mare pentru el. Determinai rezultatul final al votului.
Soluie: Vom calcula un tabel Rez(i,s)=rezultatul final al votului, dac atunci cnd i vine
rndul membrului i s voteze, votul se afl n starea s. Avem Rez(N+1,s)=s. Pentru 1iN
(n ordine descresctoare) i orice stare s (1sM), vom calcula Rez(i,s) dup cum urmeaz.
Vom considera toate strile s din L(i,s) i vom evalua rezultatul r=Rez(i+1,s), dac
membrul i schimb starea votului n s. Fie Rezset(i,s)=mulimea rezultatelor r ce pot fi
obinute astfel. Rez(i,s)=rmax, cu proprietatea c Pref(i,rmax)>Pref(i,r) (cu rmax din
Rezset(i,s) i oricare ar fi rrmax fcnd parte tot din Rezset(i,s)).
Rez(1,Q) reprezint rezultatul final al votului. Complexitatea algoritmului este
O(NM+Msum), unde Msum este suma cardinalelor mulimilor L(i,s) (1iN; 1sM). Msum
poate fi de ordinul O(NM2), dar, pentru anumite situaii speciale (de ex., L(i,s) conine doar
un numr de elemente limitat de o constant, indiferent de valoarea lui M), Msum poate fi
mai mic.
Problema 8-6. Pietre pe o tabl infinit (TIMUS)
Se d o tabl bidimensional infinit. Undeva pe aceast tabl se afl MN pietre, aezate
ntr-un dreptunghi cu M linii i N coloane (1M,N1.000). Se pot efectua mutri de tipul
urmtor: se alege o piatr A i se sare cu ea peste o piatr vecin B (pe orizontal sau
vertical). Dup sritur, piatra A i schimb poziia; noua poziie trebuie s fie liber

115

naintea sriturii; de asemenea, n urma sriturii, piatra B este eliminat de pe tabl. Dac o
piatr nu are nicio piatr vecin pe orizontal sau vertical, atunci ea nu poate sri.
Determinai numrul minim de pietre care mai pot rmne pe tabl, n urma efecturii unei
secvene de mutri corespunztoare.
Exemplu: M=3, N=4 => Rspunsul este 2.
Soluie: n mod evident, nu conteaz care din cele dou numere (M sau N) reprezint liniile
sau coloanele. Vom considera c M<N. Dac M=1, atunci toate pietrele sunt aezate n linie.
n acest caz, s presupunem pietrele numerotate de la 1 la N (de la stnga la dreapta). Vom
efectua urmtoarele mutri: piatra 2 sare peste piatra 1, piatra 4 peste piatra 3, ..., piatra 2i
peste piatra 2i-1 (1iN/2). La final, vor rmne ((N+1) div 2) pietre.
Dac M2 (implicit i N2), atunci avem 2 cazuri: dac (M mod 3=0) sau (N mod 3=0),
atunci rspunsul este 2; altfel, rspunsul este 1. Demonstraia acestor cazuri este lsat drept
exerciiu cititorului (gsii o strategie care garanteaz c rmn 2, respectiv 1 piatr la sfrit;
pentru cazul n care rmn 2 pietre, artai c nu exist o alt strategie n urma creia s
rmn o singur piatr).

116

Capitolul 9. Probleme cu Matrici


Problema 9-1. Staii radio (TIMUS)
Se d o matrice H avnd M linii i N coloane (1M,N100). Fiecare element H(i,j) al
matricii reprezint o altitudine (0H(i,j)30.000; H(i,j) este un numr ntreg). n K
(1K1.000) ptrele din matrice se afl amplasat cte o staie radio. Staia i (1iK) se
afl amplasat pe linia L(i) (1L(i)M), coloana C(i) (1C(i)N) i are o raz de transmisie
R(i) (R(i) poate fi un numr real). Dorim s amplasm un receptor radio ntr-unul din
ptrelele n care nu se afl amplasat nicio staie radio. Receptorul poate fi amplasat la
nlimea ptrelului respectiv sau la orice nlime mai mare, care s fie, ns, numr ntreg.
Receptorul radio trebuie s recepioneze semnalele de la toate cele K staii radio (adic s se
afle amplasat n raza lor de transmisie). Determinai cte modaliti diferite exist pentru
amplasarea receptorului radio (dou modaliti se consider diferite i dac receptorul este
amplasat n acelai ptrel, dar la nalimi diferite). Se consider c semnalul unei staii
radio i poate fi recepionat oriunde n sfera de raz R(i) cu centrul la (L(i), C(i), H(L(i),
C(i))); se folosete distana euclidian (norma L2).
Soluie: Vom considera fiecare ptrel (i,j) din matrice i vom calcula Npos(i,j)=numrul
posibilitilor de amplasarea a receptorului n ptrelul (i,j). Dac exist deja o staie radio
amplasat n ptrelul (i,j), atunci Npos(i,j)=0. Altfel, pentru fiecare staie radio q (1qK)
vom calcula un interval [hmin(q), hmax(q)] n care poate fi amplasat receptorul pentru a
recepiona semnalul staiei i. Calculm nti distana n planul XOY:
dxoy(q)=sqrt((i-L(q))2+(j-C(q))2).
Dac dxoy(q)>R(q), atunci setm hmin(q)=0 i hmax(q)=hmin(q)-1. Altfel, vom calcula
dH=sqrt(R(q)2-dxoy2).
Receptorul poate fi amplasat oriunde n intervalul [hmin(q)=H(L(q),C(q))-dH,
H(L(q),C(q))+dH] deasupra ptrelului (i,j). Dup calcularea tururor acestor intervale vom
mai aduga i intervalul [hmin(K+1)=H(i,j), hmax(K+1)=+] i vom calcula intersecia
celor K+1 intervale: hminint=max{hmin(q)|1qK+1}, hmaxint=min{hmax(q)|1qK+1}.
Vom rotunji apoi hminint la cel mai apropiat ntreg hmihminint i hmaxint la cel mai
apropiat ntreg hmahmaxint. Dac hmi>hma, atunci Npos(i,j)=0; altfel, Npos(i,j)=hmahmi+1. Rspunsul este suma valorilor Npos(*,*). Complexitatea algoritmului este O(MNK).
Problema 9-2. Matrice binar cu sume date pe linii i pe coloane
Se dorete construcia unei matrici binare (cu elemente 0 sau 1) cu M linii i N coloane
(1M,N1.000), astfel nct suma elementelor de pe fiecare linie i s aparin intervalului
[Slinmin(i), Slinmax(i)] i suma elementelor de pe fiecare coloan j s aparin intervalului
[Scolmin(j), Scolmax(j)]. Valorile unor elemente (i,j) sunt fixate la 0 sau la 1.
Soluie: Vom ncepe prin a decrementa cu 1 valorile Slinmin(i), Slinmax(i), Scolmin(j) i
Scolmax(j), pentru fiecare poziie (i,j) care este fixat la valoarea 1. Vom construi apoi o
reea de flux, dup cum urmeaz. Vom considera nodurile l(1), ..., l(M) i c(1), ..., c(N). Vom
avea o muchie de capacitate superioar 1 i capacitate inferioar 0 ntre l(i) i c(j), dac
elementul (i,j) nu este fixat la nicio valoarea (fie ea 0 sau 1). Vom aduga apoi alte dou
noduri, S i D. Vom aduga muchii de la S la fiecare nod l(i), care au capacitate inferioar

117

Slinmin(i) i capacitate superioar Slinmax(i). Vom duce, de asemenea, muchii de la fiecare


nod c(j) la nodul D, de capacitate inferioar Scolmin(j) i capacitate superioar Scolmax(j).
Vom ncerca apoi s gsim un flux valid, care respect restriciile inferioare i superioare de
pe fiecare muchie. Vom folosi algoritmul descris n [CLRS], care se reduce la determinarea
unui flux maxim ntr-o reea de flux modificat. Putem implementa algoritmul de flux
maxim n complexitate O((M+N)3). Apoi, dac avem flux 1 pe o muchie (l(i), c(j)), atunci
elementul (i,j) din matrice va avea valoarea 1 (altfel, (i,j) va avea valoarea 0).
Dac Slinmin(i)=Slinmax(i) i Scolmin(j)=Scolmax(j) pentru orice linie i i orice coloan
j, atunci putem calcula direct doar un flux maxim. Vom construi aceeasi reea de flux, n care
toate capacitile inferioare vor fi 0. Dac fluxul maxim n acea reea (considernd doar
capaciti superioare) este egal cu suma valorilor Slinmax(i) (1iM) (aceast sum trebuind
s fie egal i cu suma valorilor Scolmax(j), 1jN), atunci exist o soluie. Din nou,
elementele (i,j) cu valoarea 1 din matrice sunt acelea pentru care fluxul de pe muchia (l(i),
c(j)) este 1 (celelalte elemente nefixate n prealabil vor avea valoarea 0).
Pentru cazul n care Slinmin(i)=Slinmax(i) i Scolmin(j)=Scolmax(j) pentru orice linie i i
orice coloan j, precum i dac nu este fixat niciun element n prealabil, putem obine un
algoritm cu complexitatea O(MN). Vom nota Slin(i)=Slinmax(i) i Scol(j)=Scolmax(j). Vom
sorta liniile descresctor dup Slin(*) i coloanele descresctor dup Scol(*). Astfel, vom
avea Slin(i)Slin(i+1) (1iM-1) i Scol(j)Scol(j+1) (1jN-1). Vom parcurge liniile n
ordinea sortat, de la prima ctre ultima. Pentru a amplasa cele Slin(i) elemente egale cu 1 pe
linia i, vom alege primele Slin(i) coloane (n ordinea sortat a coloanelor). Apoi vom
decrementa cu 1 valorile Scol(*) ale primelor Slin(i) coloane. Dup aceasta, vom resorta
valorile Scol(*) corespunztoare coloanelor. Resortarea se poate realiza n timp O(N),
deoarece const n interclasarea primelor Slin(i) valori (a cror ordine relativ se menine) cu
celelalte N-Slin(i) valori (care nu au fost decrementate cu 1). Astfel, obinem complexitatea
dorit.
Bineneles, atunci cnd sortm liniile i (re)sortm coloanele, vom menine, pentru
fiecare valoare Slin(i), respectiv Scol(j), coloana creia i corespunde. Astfel, pentru fiecare
linie i, cele Slin(i) elemente egale cu 1 vor fi amplasate pe coloanele corespunztoare
primelor (celor mai mari) Slin(i) valori Scol(*).

118

Capitolul 10. Probabiliti


Problema 10-1. Bile ntr-o urn (Olimpiada Online 2001, Romnia)
ntr-o urn se afl W (1W100) bile albe i B (1B100) bile negre. Doi juctori extrag,
pe rnd, cte o bil i se uit la ea. Daca e alb o pstreaz, altfel (dac e neagr) o pune la
loc. Ctig cel care extrage ultima bil alb. n total, pot avea loc maxim K extrageri. Dac
nimeni nu a ctigat dup K (1K100) extrageri, atunci jocul se consider remiz.
Determinai probabilitatea ca primul juctor (cel care efectueaz prima extragere) s ctige
jocul.
Soluie: Vom calcula dou matrici: PA(q,a)=probabilitatea ca primul juctor s ctige jocul
dac el se afl la mutare, au mai rmas a bile albe i mai sunt posibile, n total, q extrageri, i
PB(q,a)=probabilitatea ca primul juctor s ctige jocul dac la mutare se afl al doilea
juctor, au mai rmas a bile albe i mai sunt posibile, n total, q extrageri.
Avem PA(0,*)=PB(0,*)=0. Pentru 1qK avem urmtoarele relaii:
(1) PA(q,0)=PB(q,0)=0;
(2) PA(q,1)=(1/(B+1))+(B/(B+1))PB(q-1,1);
(3) PB(q,1)=(1/(B+1))PA(q-1,0)+(B/(B+1))PA(q-1,1);
(4) PA(q,2aW)=(a/(a+B))PB(q-1,a-1)+(b/(a+b))PB(q-1,a);
(5) PB(q,2aW)=(a/(a+B))PA(q-1,a-1)+(b/(a+b))PB(q-1,a).
Relaiile se bazeaz pe urmtoarele fapte. Atunci cnd exist a bile albe i b bile negre n
urn, exist o probabilitate de a/(a+b) s fie extras o bil alb i una de b/(a+b) s fie
extras o bil neagr. Dac se extrage o bil alb, numrul de bile albe scade cu 1; altfel
rmne constant. Indiferent de ce juctor se afl la mutare, la mutarea urmtoarea va efectua
o extragere cellalt juctor. Rezultatul problemei este PA(K,W), iar complexitatea
algoritmului este evident: O(WK).
Problema 10-2. Joc de cri (Olimpiada Judeean de Informatic, Bucureti, Romnia,
2001)
ntr-un pachet de cri se afl N cri nerge i R cri roii (1N,R50.000), aezate ntr-o
ordine oarecare n pachet, cu faa n jos (orice ordine este la fel de probabil). Un juctor
joac urmtorul joc. El ncearc s ghiceasc culoarea crii aflate n vful pachetului.
Pentru aceasta, el alege o culoare (rou sau negru) i ntoarce cartea din vrful pachetului.
Dac a ghicit culoarea, el elimin cartea din pachet i continu cu ncercarea de a ghici
culoarea urmtoarei cri. Dac nu a ghicit culoarea, jocul se termin. Jocul se termin i
dac a ghicit culorile tuturor crilor din pachet. Juctorul nu ghicete culorile crilor, ns,
la ntmplare. El tie, la orice moment de timp, numrul de cri nerge (Ncur) i roii (Rcur)
care au mai rms n pachet. Dac RcurNcur, el alege culoarea roie; altfel, alege culoarea
neagr. Determinai numrul mediu de cri ale cror culori juctorul le ghicete pn la
sfritul unui joc.
Exemplu: N=1, R=1 => Rspunsul este 1.0.
Soluie: Rspunsul este egal cu suma valorilor (LProb(L)) (0LN+R), unde Prob(L) este
probabilitatea ca juctorul s ghiceasc exact L cri la un joc. Prob(L) poate fi definit ca
Nconfig(L)/Ntotal(N+R), unde Ntotal(N+R) este numrul total de configuraii coninnd N

119

cri nerge i R cri roii (care este egal cu C(N+R,N)=combinri de N+R luate cte N), iar
Nconfig(L)=numrul de configuraii n care se ghicesc exact L cri. Observm c dac s-au
ghicit exact L cri, tim exact ordinea primelor L cri. S definim Ncur(L) (Rcur(L)) =
numrul de cri nerge (roii) care rmn n pachet dup ghicirea primelor L cri.
Ncur(0)=N i Rcur(0)=R. Pentru L1, dac Rcur(L-1)Ncur(L-1), atunci Rcur(L)=Rcur(L1)-1 i Ncur(L)=Ncur(L-1); altfel, Rcur(L)=Rcur(L-1) i Ncur(L)=Ncur(L-1)-1.
Dac L=N+R, atunci Nconfig(N+R)=1. Altfel, juctorul trebuie s nu ghiceasc a (L+1)a carte. Dac Rcur(L)Ncur(L), a (L+1)-a carte trebuie s fie neagr, deci setm
Rcur2(L)=Rcur(L) i Ncur2(L)=Ncur(L)-1; altfel, setm Rcur2(L)=Rcur(L)-1 i
Ncur2(L)=Ncur(L). Nconfig(L) este egal cu Ntotal(Ncur2(L)+Rcur2(L)). Algoritmul este
liniar, dar presupune folosirea operaiilor pe numere mari, ceea ce nu este convenabil.
O soluie mai simpl este urmtoarea. Vom calcula, pe rnd, valorile Prob(L), ncepnd
de la 0 i pn la N+R. Vom menine, pe parcurs, valorile Pcur, Ncur, Rcur i Lcur. Iniial,
Pcur=1.0, Ncur=N, Rcur=R i Lcur=0. Dac RcurNcur, juctorul va alege, la momentul
curent, culoarea roie; altfel, alege culoarea neagr. Probabilitatea de a ghici la momentul
curent este P=max{Rcur,Ncur}/(Rcur+Ncur). Dac nu ghicete, atunci jocul se termin i el
rmne cu Lcur cri ghicite. Pcur este probabilitatea de a ghici primele Lcur cri.
Prob(Lcur) va fi egal cu Pcur(1-P) (probabilitatea de a ghici Lcur cri i de a nu o ghici pe
a (Lcur+1)-a).
Dup considerarea cazului n care nu a ghicit cartea, vom trece la pasul urmtor. Dac
RcurNcur, setm Rcur=Rcur-1; altfel, Ncur=Ncur-1 (deoarece cartea ghicit este scoas
din pachet). Apoi setm Pcur=PcurP i Lcur=Lcur+1. Cnd ajungem n starea
Ncur=Rcur=0, setm Prob(Lcur=N+R)=Pcur. n felul acesta, am determinat probabilitile
Prob(L) pentru fiecare numr de cri 0LN+R. Putem s nici nu meninem aceste
probabiliti separat, ci s calculm suma ce reprezint rspunsul pe msur ce calculm
probabilitile. Complexitatea algoritmului este O(N+R).
Problema 10-3. Vaci i Maini (UVA)
Participi la o emisiune televizat i n faa ta sunt X+Y (1X,Y10.000) ui. n spatele a X
ui se afl cte o vac, iar n spatele celorlalte Y se afl cte o main. n prima etap, tu alegi
una din ui. Apoi, prezentatorul emisiunii deschide Z (0ZX-1) ui n spatele crora se afl
(sigur) o vac (ua pe care ai ales-o tu nu se afl n mod cert printre cele Z deschise). Dup
deschiderea celor Z ui, prezentatorul i ofer posibilitatea s i schimbi alegerea (adic s
alegi alt u). Tu accepi oferta i alegi o u diferit de cea aleas iniial (i de cele Z
deschise de prezentator). Care este probabilitatea ca n spatele uii alese la final s gseti o
main ? (n mod clar, o main este ceea ce i doreti, i nu o vac).
Exemplu: X=2, Y=1, Z=1 => Rspunsul este 0.666666.
Soluie: Rspunsul este suma a doua probabiliti, P1 i P2. P1 corespunde cazului n care n
spatele uii alese iniial se afla o main, iar P2 corespunde cazului n care n spatele uii
alese iniial se afl o vac. P1=(Y/(X+Y))((Y-1)/(X-Z+Y-1)). P2=(X/(X+Y))(Y/(X-Z-1+Y)).
Problema 10-4. Zi de Natere (UVA)
Stai la o coad la cinematograf pentru a cumpara bilete la cel mai nou film cu actorul
(actria) preferat(). De fiecare dat cnd cineva cumpr un bilet, vnztorul i noteaz ziua
de natere a persoanei i o compar cu zilele de natere ale persoanelor care au cumprat
bilet naintea ei (la care se adaug ziua de natere a vnztorului, pentru a oferi o ans i

120

primei persoane aflate la coad). Dac ziua de natere coincide cu a unei persoane care a
cumprat deja bilet (sau cu a vnztorului), persoana care tomai a cumprat biletul ctig o
invitaie la cin din partea actorului preferat (actriei preferate). Pe ce poziie i-ai dori s te
afli n coad, pentru ca probabilitatea ca tu s ctigi invitaia s fie maxim ? Determinai
att poziia cu virgul, ct i poziia ntreag. Poziiile se numeroteaz de la 1, iar un an are Z
(1Z100.000) zile.
Exemplu: Z=365 => Rspunsul este 18.61 (iar poziia cu numr ntreg este 19).
Soluie: Poziia optim (ca numr real) este poz=(1+(4Z+1)1/2)/2-1. Poziia ca numr ntreg
se obine prin rotunjirea valorii reale (n jos, dac partea fracionar este mai mic dect 0.5;
sau n sus, pentru 0.5). ncercai s demonstrai formula. Observai c probabilitatea
Prob(p) de a ctiga invitaia dac v aflai pe poziia p este egal cu: (1-Prob(1)-...-Prob(p1))p/N (cu Prob(1)=1/N). O alt expresie a lui Prob(p) este p/NC(N,p)/pN= C(N,p)/(NpN-1).
(unde C(a,b) reprezint combinri de a luate cte b).
Problema 10-5. Extragerea bilelor colorate
ntr-o urn se afl bile din N culori (1N10); cte b(i) bile din culoarea i (0b(i)10).
Dumneavoastr extragei K bile din urn (0Kb(1)++b(N)). Care este probabilitatea s fi
extras a(1) bile de culoarea 1, ..., a(i) bile de culoarea i, ... (1iN; a(1)++a(N)=K;
0a(i)b(i)) ?
Soluie: Vom calcula P(c(1), ..., c(N))=probabilitatea de a fi extras exact c(i) bile de culoarea
i (1iN) ntre primele c(1)+...+c(N) bile extrase. Avem P(0, ..., 0)=1. Vom calcula aceste
valori n ordine lexicografic a irurilor (c(1), ..., c(N)). Pentru a calcula P(c(1), ..., c(N)),
iniializm aceast valoare cu 0. Calculm apoi numrul de bile rmase n urn dup
extragerea celor c(i) bile din fiecare culoare i (1iN): NB=(b(1)-c(1))+...+(b(N)-c(N)).
Apoi considerm, pe rnd, toate culorile i (1iN) cu c(i)>0 i adunm la P(c(1), ..., c(N))
valoarea (b(i)-c(i)+1)/(NB+1)P(c(1), ..., c(i-1), c(i)-1, c(i+1), ..., c(N)); valoarea adunat
reprezint probabilitatea de a ajunge n starea (c(1), ..., c(N)), dac la ultima extragere am
extras o bil de culoarea i.

121

Capitolul 11. Probleme Ad-Hoc


Problema 11-1. Detecia repetiiilor n iruri recurente
S considerm un ir infinit, n care al N-lea element al irului, x(N) este dat ca o funcie a
ultimilor K1 termeni: x(N)=f(x(N-1), ..., x(N-K)). Primii K termeni, x(1), ..., x(K) sunt dai.
Se pot defini multe probleme pe baza acestor iruri, care, n general, se bazeaz pe detecia
repetiiilor. De exemplu, dac valorile elementelor irului sunt numere ntregi i se tie c
sunt ntr-un interval [A,B], atunci putem menine o matrice K-dimensional T(v(1), v(2), ...,
v(K)), cu Av(i)B. Dimensiunea matricii T este (B-A+1)K. Aceast matrice este iniializat
cu 0. Setm apoi T(x(1), ..., x(K))=K, apoi ncepem s generm, n ordine, elementele x(i)
(iK+1). Dup ce am generat un element x(i), verificm dac T(x(i-K+1), ..., x(i)) este nenul.
Dac nu este, atunci am gsit un ciclu de lungime i-T(x(i-K+1), ..., x(i)) n generarea
valorilor irului. Dac este zero, atunci setm T(x(i-K+1), ..., x(i))=i. S presupunem c am
detectat un ciclu de lungime L, care ncepe de la o poziie P ncolo. Atunci putem genera
foarte simplu al N-lea element, unde N este foarte mare. Dac NP, atunci l vom genera
normal (n timp O(P)). Altfel, x(N)=x(P+((N-P) mod L)) (pe care l generm n timp
O(P+L)).
O alt metod pentru detecia ciclurilor, folosete doi pointeri, p1 i p2. p1 este iniializat
la primul element, iar p2 la al doilea. La fiecare iteraie, p1 avanseaz cu un pas (trece la
elementul urmtor) i p2 avanseaz doi pai. Pentru fiecare pointer se menin, n ordine,
ultimele K valori din ir peste care a trecut (inclusiv cea curent). Dac, la un moment dat,
cele K valori corespunztoare lui p1 i p2 sunt identice, atunci am identificat un ciclu. Pentru
a determina o poziie de nceput a ciclului, vom porni cu un pointer p3 de la nceputul irului
i vom avansa pas cu pas, pn cnd ultimele K valori generate sunt cele corespunztoare lui
p1 i p2. Totui, este posibil ca poziia pe care o indic p3 s nu fie chiar prima poziie din
ciclu, el putnd s nceap mai devreme. Dac am putea merge napoi cu cte un pas, att cu
p3, ct i cu p1, atunci, atta vreme ct ultimele K valori corespunztoare celor doi pointeri ar
fi identice, am merge napoi cu un pas cu fiecare pointer. n felul acesta, am ajunge chiar la
prima poziie din ciclu.
Dac dorim s gsim poziia exact de nceput a ciclului i nu putem merge cu pointer-ii
napoi, putem proceda dup cum urmeaz. Dup ce am gsit poziia p3 unde ultimele K
elemente sigur aparin ciclului, putem cuta binar poziia p4 (1p4p3), pentru a gsi poziia
exact de nceput a ciclului (prima poziie poz pentru care ultimele K-1 elemente, plus
elementul de pe poziia poz, fac parte din ciclu). S presupunem c am ales o poziie poz.
Vom genera, pornind de la nceputul irului, toate elementele, pn ajungem la poziia poz.
Aici vom pstra ultimele K elemente. Vom parcurge irul cu un pointer p5, ncepnd de unde
a ajuns pointer-ul p3. tim sigur c pointer-ul p5 parcurge elemente de pe ciclu. Dac, n
timpul parcurgerii cu p5, ntlnim, n ordine, ultimele K elemente indicate de poziia poz,
atunci poziia poz face parte din ciclu i, n cadrul cutrii binare, vom ncerca s gsim
(dac exist) o poziie mai mic. Dac, ns, parcurgnd irul cu pointer-ul p5, ajungem
napoi la elementele corespunztoare pointer-ului p3, fr a ntlni cele K elemente indicate
de poziia poz, atunci poziia poz nu face parte din ciclu i va trebui s testm (n cadrul
cutrii binare) o poziie mai mare.

122

Problema 11-2. Program Introspectiv (TIMUS)


Se consider limbajul de programare PIBAS, descris n continuare. Un program PIBAS
const dintr-unul sau mai muli operatori separai prin ;. Exist dou tipuri de operatori:
operatorul de atribuire de iruri i operatorul de afiare. Operatorul de atribuire = este
folosit n felul urmtor: <Variabila String>=<Expresie String>. O <Variabila String> este
o liter latin mare (A-Z). O <Expresie String> este ori o <Variabil String>, o <Constant
String>, o <Funcie String> sau o concatenare de <Expresii String>. Concatenarea a dou
<Expresii String> are forma: <Expresie String 1>+<Expresie String 2>. O <Constant
String> este o secven de caractere tipribile, incluse ntre dou ghilimele () sau dou
apostroafe (). Aceast secven nu poate conine sau n interiorul ei, dac este inclus
ntre acestea. De exemplu, repede, Olala! i "I don't know the solution." sunt
<Constante String> corecte.
O <Funcie String> este folosit n felul urmtor: $(<Variabila string>,<ntreg fr
semn>,<ntreg fr semn>). Funcia ntoarce un subir (de caractere consecutive) al
<Variabilei String>, incepnd de la poziia p (al doilea parameteru) i avnd lungime l (al
treilea parameteru). Primul caracter dintr-un ir se afl pe poziia 1.
Operatorul de afiare este folosit astfel: ?<Expresie String>.
Exemple:
Program PIBAS
Ce afiaz
?"Hello, "+'World!'
Hello, World!
A='World, Hello!';?$(A,8,5);?", ";B=$(A,1,5)+'!';?B
Hello, World!
Scriei un program PIBAS introspectiv. Un program este introspectiv dac i afiaz
propriul cod surs.
Soluie: Aproape n orice limbaj de programare se pot scrie programe introspective.
Limbajul PIBAS din cadrul problemei este unul simplu i, n plus, fa de un limbaj
standard, are avantajul ca este un limbaj nou pentru toi cei care ncearc s rezolve
problema. Nu exist o reet pe care s o putei folosi pentru a scrie un program introspectiv,
de aceea, n continuare, este prezentat programul gsit de autor:
A=;B=;C==ABC;?$(C,2,1);?$(C,1,1);?B;?A;?B;?$(C,5,1);?$(
C,3,1);?$(C,1,1);?A;?B;?A;?$(C,5,1);?$(C,4,1);?$(C,1,1);?A;?C;
?A;?$(C,5,1);?$(C,6,128);?$(C,2,1);?$(C,1,1);?B;?A;?B;?$(C,5,
1);?$(C,3,1);?$(C,1,1);?A;?B;?A;?$(C,5,1);?$(C,4,1);?$(C,1,1);
?A;?C;?A;?$(C,5,1);?$(C,6,128)
Un program introspectiv n C (gsit la [Quine]) este urmtorul (se presupune ca header-ul
stdio.h este inclus n mod implicit):
char*f="char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c";main(){printf(f,34,f,34,10);}.
Problema 11-3. Caraibe (Lot 2004, Romnia)
N (1N65.000) pirai au obinut o sum S foarte mare (S>N(N-1)/2). Pentru
mprire, piraii se aeaz n linie. Primul pirat va propune o schem de mprire a banilor.
Dac un anumit numr de pirai nu sunt de acord cu aceast schem, piratul va fi aruncat
peste bord, i apoi urmtorul pirat va propune o schem de mprire, i tot aa. Piraii sunt
foarte inteligeni: un pirat este de acord cu o schem de mprire doar dac aceasta i aduce
un avantaj strict (cel puin un bnu) fa de ce ar obine votnd mpotriva schemei. Pentru c
acioneaz numai pe baze raionale, piraii sunt i foarte predictibili. Cu alte cuvinte, un pirat
poate anticipa decizia altor pirai pentru a lua o decizie proprie (aceasta nseamn i c dac

123

un pirat are mai multe posibiliti de a alege o schem de mprire, ceilali pirai tiu ce
variant ar alege).
Depinznd de caracteristicile fiecrui pirat, numrul de pirai care trebuie s fie de acord
cu schema lui pentru a nu fi aruncat peste bord variaz: pentru piratul i (1i<N) acest numr
este A[i]. Dac piratul i propune o schem, tim c toi piratii pn la i-1 au fost aruncai deja
peste bord. n afar de piratul i, mai exist N-i pirai. Dac cel puin A[i] dintre acetia sunt
de acord cu schema piratului i, comoara va fi mprit dup aceast schem. Altfel, piratul i
va fi aruncat peste bord, i piratul i+1 va propune o schem. Pentru orice i, avem 0A[i]<Ni. Datorit acestei condiii A[N-1]=0, iar A[N] nu este definit (pentru c piratul N este
ultimul).
Primul pirat din linie dorete s propun o schem de mprire a banilor astfel nct s nu
fie aruncat peste bord, i el s primeasc ct mai muli bnui. Determinai suma maxim pe
care o poate primi. Se garanteaz c exist o schem pe care o poate propune primul pirat,
astfel nct el s nu fie aruncat peste bord.
Soluie: Ideea este s raionm pornind de la ultimul pirat spre primul. Dac N-2 pirai sunt
aruncai peste bord, piratul N-1 i va acorda ntreaga comoar lui. Piratul N nu poate s l
mpiedice, pentru c A[N-1]=0. Deci piratul N-3 tie ce se va ntmpla dac el va fi aruncat
peste bord (N-1 primete tot, i N primete zero). Bazat pe asta, el poate propune o schem
care i maximizeaz profitul i este acceptat. Deci acum piratul N-4 tie precis ce se va
ntmpla dac el este aruncat peste bord. Similar, prin inducie, piratul N-i-1 tie ce se va
ntmpla dac el este aruncat peste bord (va fi adoptat schema piratului N-i), i poate lua o
decizie bazat pe aceast certitudine.
Cnd propune o schem, un pirat J vrea s i maximizeze profitul, dar este necesar ca
schema lui s fie acceptat (altfel va fi aruncat peste bord). Pentru asta, el trebuie ca la A[J]
pirai s dea mai muli bnui dect acetia ar primii n schema piratului J+1. Pentru a-i
maximiza profitul, el alege s conving n acest mod pe piraii care primesc cele mai mici
sume n schema lui J+1. La aceste sume, el adaug cte un bnu. La ceilali pirai, el le d
zero pentru c are deja suficieni susintori. Algoritmul va fi n esen acesta: considerm
toi J de la N-2 pn la 1; la pasul J tim deja schema pe care ar propune-o J+1; pentru a afla
schema piratului J, alegem A[J] pirai cu cele mai mici sume n schema precedent,
incrementm ctigul acestor pirai, i facem ctigul celorlali egal cu zero.
Se observ c mcar suma unui pirat va fi facut zero (pentru c A[J] < N-J). Deci suma
pe care o ctig J este cel puin suma maxim din suma lui J+1 minus A[J] (fiindc trebuie
incrementate A[J] sume). Pentru c numrul de bnui este foarte mare, reiese uor c suma
maxim din schema lui J este ce i acord J lui nsui. Mai precis, n schema proprie, J
ctig cel puin SA[N-2] A[N-1] ... A[J+1]. Asta nseamn c orice J poate propune o
schem n care s nu fie aruncat peste bord, i mai mult poate ctiga mai mult dect orice
pirat rmas.
Implementarea algoritmului este destul de uoar i are un timp de rulare O(N). inem o
coad cu piraii n ordinea cresctoare a sumelor ctigate. Dac mai muli pirai ctig
aceai sum, inem n coad un singur element (numrul de pirai care ctig acea sum). La
pasul J, extragem din vrful cozii toi piraii care vor primii zero, pn rmn doar A[J] pirai.
Toi aceti pirai vor fi introdui la baza cozii ca un singur element (toi primesc zero). Nu e
nevoie s incrementm explicit sumele pentru ceilali, ci putem s observm c toi din
grupul I (unde primul grup din coad are I=0) primesc I bnui, deci suma e dat de poziia
n coad (care se schimb n timp). Este uor de vzut ca algoritmul ruleaz n timp O(N): la

124

fiecare pas, n coad se bag doar un element (un grup de pirai cu suma zero), deci numrul
total de elemente scoase din coad pe parcursul rulrii este cel mult N.
Problema 11-4. Cutii (ACM ICPC NEERC Southern Subregion, 2003)
Se dau dou cutii, coninnd A, respectiv B bile (0A,B2.000.000.000). O mutare const
n a transfera dintr-o cuitie n alta un numr de bile egal cu numrul de bile care se aflau n
cutia destinaie naintea efecturii mutrii. De exemplu, presupunnd c AB, dup
efectuarea mutrii vom rmne cu A-B, respectiv 2B bile n cele dou cutii. Determinai dac
este posibil s se transfere toate bilele dintr-o cutie n cealalt i, dac da, dup cte mutri.
Soluie: Observm c, la fiecare pas, exist o singur mutare pe care o putem efectua i
anume, s transferm bile din cutia cu mai multe bile n cea cu mai puine bile. Aadar, vom
aplica acest algoritm i vom numr mutrile. Singura problem ar fi s detectm dac nu se
poate ajunge n configuraia final dorit. S presupunem c, la un moment dat n cadrul
algoritmului, am ajuns cu A bile ntr-o cutie i B n cealalt (AB). Vom calcula Q, ctul
mpririi lui A la B. Dac Q nu este un numr impar, atunci problema nu admite soluie.
Acest fapt se poate demonstra dac pornim de la configuraia final (de fapt, cea aproape
final, n care se gasete un numr egal de bile n fiecare cutie) i efectum mutrile invers,
considernd, de fiecare dat, cele dou cazuri posibile. Dac avem AB bile n cele dou
cutii, atunci nainte de efectuarea mutrii puteam avea A+B/2 i B/2 bile (dac i B este
par), sau A/2 i B+A/2 (dac i A este par). Observm c n ambele cazuri, ctul mpririi
numrului mai mare la cel mai mic rmne impar (am realizat, astfel, o demonstraie prin
inducie dup numrul de mutri efectuate n sens invers).
Problema 11-5. Expresie cu mpriri (Olimpiada Baltic de informatic, 2000)
Se d urmtoarea expresie, ce conine N (2N100.000) numere naturale: a1 / a2 / ... / aN.
Determinai dac exist vreo posibilitate de a insera 0 sau mai multe perechi de paranteze,
astfel nct rezultatul expresiei s fie un numr natural.
Exemple:
N=4
Rspuns: Da. O posibilitate de parantezare este
1/2/1/2
urmtoarea: (1/2)/(1/2).
N=3
Rspuns: Nu.
1/2/3
Soluie: Observm empiric c, n fracia final, ne-ar plcea s nu aveam prea multe numere
la numitor (i cele mai multe s fie la numrtirul fraciei). Observm, de asemenea, c,
indiferent de mmodul n care introducem paranteze, a1 se va afla de fiecare dat la numrtor,
iar a2 se va afla la numitor. Aadar, o parantezare n care a2 este singurul numr aflat la
numitor ar fi cea mai convenabil. Observm c urmtoarea parantezare are aceast
proprietate: a1/(a2/a3/.../aN). Tot ce mai rmne de fcut este s verificm c produsul
numerelor a1, a3, a4, ..., aN este divizibil cu a2. Bineneles, nu vom calcula produsl efectiv,
deoarece ar putea avea foarte multe cifre. Vom parcurge numerele n ordinea a1, a3, a4, ... ;
pentru fiecare numr ai (i=1 sau i=3,...,N) vom calcula cel mai mare divizor comun di dintre
ai i a2, dup care mprim pe a2 la di (modificm, astfel, valoarea lui a2). Dac, la final, a2
are valoarea 1, atunci rspunsul este Da. n caz contrar, rspunsul este Nu.

125

Problema 11-6. Identificarea numrului lips


Se dau N-1 numere distincte din mulimea {1,2,...,N}. Determinai numrul lips (adic
numrul din {1,2,...,N} care nu apare printre cele N-1 numere date.
Soluie: Dac am avea suficient memorie la dispoziie, am putea scrie un program care s
sorteze cele N-1 numere. Am parcurge apoi numerele n ordinea sortat i am verifica c
fiecare numr este egal cu numrul anterior, plus 1. Dac nu este aa, atunci numrul lips
este chiar numrul anterior plus 1 (sau N, dac am terminat de parcurs toate cele N-1 numere).
Aceast soluie are complexitatea O(Nlog(N)). O alt variant de rezolvare ar consta n
introducerea celor N-1 numere ntr-o tabel hash. Vom parcurge apoi toate numerele de la 1
la N i, folosind tabela hash, vom verifica dac un numr exist sau nu printre cele N-1
numere date. Aceast soluie are complexitatea O(N). Totui, dac nu avem suficient
memorie la dispoziie (dar chiar i n cazul n care avem), urmtoarea abordare este cea mai
eficient. Calculm suma S a celor N-1 numere. Numrul lips va fi N(N+1)/2-S (altfel spus,
din suma 1+2+...+N scdem suma S).
Problema 11-7. Identificarea numrului care apare de un numr impar de ori
Se dau N numere naturale a(1), ..., a(N), avnd valori cuprinse ntre 0 i 2.000.000.000.
S considerm mulimea M a numerelor distincte dintre cele N date. Se tie c fiecare numr
din M apare de un numr par de ori printre cele N numere date, cu excepia unuia singur, care
apare de un numr impar de ori. Identificai numrul care apare de un numr impar de ori.
Soluie: Evident, am putea sorta numerele i apoi am parcurge irul sortat. n felul acesta, am
identfica uor numrul care apare de un numr impar de ori. Aceast soluie are
complexitatea O(Nlog(N)). O alt variant ar consta n a menine o tabel hash, n care
cheile sunt reprezentate de numere, iar valorile de numrul de apariii al fiecui numr.
Parcurgem irul i dac nu gsim un element a(i) n hash, introducem un element cu cheia
a(i) i valoarea 1; dac gsim un element a(i) cu valoarea j, tergem acest element din hash i
introducem un element cu cheia a(i) valoarea (j+1). Aceast soluie are complexitatea
O(N). Ambele soluii prezentate anterior folosesc memorie O(N).
Putem rezolva problema i folosind mai puin memorie. Practic, vom calcula x = a(1)
xor a(2) xor ... xor a(N). l putem calcula pe x pe msur ce citim numerele a(1), ..., a(N)
(dintr-un fiier, de exemplu). x este numrul care apare de un numr impar de ori.
Problema 11-8. Identificarea numrului minoritar (Olimpiada Baltic de Informatic,
2004, enun modificat)
Se dau N numere naturale a(1), ..., a(N), avnd valori cuprinse ntre 0 i 2.000.000.000.
S considerm mulimea M a numerelor distincte dintre cele N date. Se tie c fiecare numr
din M apare de exact K2 ori, cu excepia unuia singur, care apare de 1QK-1 ori. Vom
numi acest numr minoritar. Identificai numrul minoritar, n condiiile n care K i Q nu
sunt cunoscute.
Soluie: Evident, soluiile bazate pe sortare i tabele hash pot fi folosite i n acest caz, ns
folosesc O(N) memorie. O soluie cu memorie O(1) este urmtoarea. Vom parcurge fiierul
de intrare i vom gsi 2 numere distincte: x i y. Dac nu exist 2 astfel de numere, atunci
toate numerele a(i) sunt identice => a(1) este rspunsul. Apoi mai parcurgem fiierul o dat
i calculm nx i ny, numerele de apariii n fiier ale lui x i y; dac nx>ny, rspunsul este y,

126

iar dac ny>nx, rspunsul este x. Dac nx=ny, atunci K=nx i am gsit valoarea lui K. Vom
determina acum numrul minoritar bit cu bit (are cel mult 32 de bii). Parcurgem fiierul de
intrare nc o dat i pentru fiecare bit b de la 0 la 31, calculm num(b,q)=numrul de numere
din fiier pentru care bitul b are valoarea q (q=0 sau 1). Pentru fiecare bit b, unul dintre
numerele num(b,0) i num(b,1) va fi multiplu de K, iar cellalt nu va fi. Dac num(b,q) este
multiplu de K, atunci numrul minoritar are bitul b egal cu (1-q). n felul acesta, putem
determina fiecare bit al numrului cutat.
Problema 11-9. Dreptunghiuri Disjuncte (TIMUS)
Se d o matrice de pixeli binari (0 sau 1) de dimeniuni NxN (1N5000). S se determine
dac componentele maximale (pe direciile Nord, Sud, Est sau Vest) de pixeli 1 (negri) sunt
toate dreptunghiuri.
Soluie: Este necesar ca orice sub-ptrat de dimensiuni 2x2 al matricii s conin un numr X
de pixeli de negri, unde X3 (X poate fi 0, 1, 2 sau 4). Astfel, verificarea se poate realiza n
timp O(N2) (timp proporional cu dimensiunea matricii).
Problema 11-10. Depozit (TIMUS)
ntr-un depozit exist K (1K50.000) seturi de produse. Un produs este identificat prin
tipul acestuia, un numr de la 1 la N (1N100). Spunem c dou seturi S1 i S2 sunt similare,
dac:
S1 este obinut din S2 prin eliminarea unui produs
S1 este obinut din S2 prin adugarea unui produs
S1 (S2) este obinut din S2 (S1) prin nlocuirea unui produs cu un alt produs
De exemplu, setul (1,2,3,4) (conine cte un produs din tipurile 1, 2, 3 i 4) este similar cu
seturile (1,2,3), (1,2,3,4,5), (1,2,2,3,4), (1,3,4,5), etc. Am considerat produsele dintr-un set
sortate n ordine cresctoare a tipurilor lor (deoarece ordinea acestor ntr-un set nu conteaz).
Observai i c un set poate conine mai multe produse de acelai tip practic, un set este
definit prin numrul de produse din fiecare tip.
mprii seturile de produse date la cele M (N<M) magazine cu care depozitul are
contract (fiecare set ajunge la un magazin), n aa fel nct dou seturi similare s nu ajung
la acelai magazin.
Soluie: Vom calcula suma tipurilor produselor fiecrui set i, S(i) (1iK). Observm c dac
dou seturi i i j sunt similare, atunci 1|S(i)-S(j)|N. De asemenea, observm c un set nu
este similar cu el nsui, conform definiiei (astfel, dac exist mai multe seturi care conin
acelai numr de produse din fiecare tip, ele pot fi distribuite la acelai magazin). ntruct
MN+1, putem distribui fiecare set i la magazinul ((S(i) mod (N+1))+1). Complexitatea
algoritmului este liniar n dimensiunea datelor de intrare.
Problema 11-11. Reconstrucia unui ir din sumele a oricare 2 elemente
Se tie c avem un ir ce const din N valori (3N200), pe care nu le cunoatem.
Cunoatem, n schimb, cele N(N-1)/2 sume a oricare dou elemente din ir. Determinai
elementele irului pe baza sumelor date.
Soluie: Vom sorta irul sumelor astfel nct s avem S(1)S(2)...S(N(N-1)/2). S notm
elementele irului prin v(1), ..., v(N), astfel nct v(1)v(2)...v(N). n mod cert,

127

S(1)=v(1)+v(2) i S(2)=v(1)+v(3). Mai trebuie s determinm care dintre celelalte sume este
suma v(2)+v(3). S observm care ar putea fi valorile candidate: S(3) ar putea fi v(2)+v(3)
sau v(1)+v(4); dac S(3) nu este v(2)+v(3), atunci S(4) ar putea fi v(2)+v(3) sau
v(1)+v(5); ... ; n general, S(3iN-1) ar putea fi egal cu v(2)+v(3) sau v(1)+v(i+1). Aadar,
avem N-3 sume candidate pentru a fi egale cu v(2)+v(3). Vom considera fiecare din cele
O(N) posibiliti. S presupunem c am considerat c v(2)+v(3)=X. Vom construi un ir S
ce conine elementele irului S, din care eliminm primele dou elemente (S(1) i S(2)) i pe
X (dac X apare de mai multe ori, se elimin o singur apariie a sa). O dat ce am stabilit
valoare X a lui v(2)+v(3) avem un sistem de 3 ecuaii cu 3 ncunoscute:
(1) v(1)+v(2)=S(1);
(2) v(1)+v(3)=S(2);
(3) v(2)+v(3)=X)
i 3 necunoscute (v(1), v(2), v(3)). De aici putem obine valorile lui v(1), v(2) i v(3). O
dat ce valorile acestor elemente au fost determinate, tim c primul element din irul S este
v(1)+v(4), obinnd, astfel, valoarea lui v(4). Dup determinarea lui v(4), vom elimina
valorile (v(1)+v(4)), (v(2)+v(4)) i (v(3)+v(4)) din irul S. Acum primul element (cel mai
mic) din S este egal cu v(1)+v(5); .a.m.d. Atunci cnd tim c cel mai mic element din S
este egal cu v(1)+v(i) (4iN), calculm valoarea lui v(i) (deoarece cunoatem valoarea v(1)),
apoi eliminm din S valorile (v(j)+v(i)) (1ji-1); n continuare, dac i<N, cel mai mic
element din S va fi egal cu (v(1)+v(i+1)). Dac, la un moment dat, atunci cnd vrem s
eliminm o valoare Y din S aceasta nu (mai) exist n S, nseamn c presupunerea iniial
(c v(2)+v(3)=X) este greit i va trebui s ncercm o alt valoare pentru v(2)+v(3). Din
punct de vedere al implementrii, S poate fi implementat ca un arbore echilibrat. n felul
acesta complexitatea soluiei este O(N3log(N)). Dac diferena dintre suma minim i cea
maxim nu este prea mare, atunci putem folosi un vector de frecvene (f(y)=numrul de
apariii n S a valorii S(1)+y, 0yS(N(N-1)/2)-S(1)) i complexitatea algoritmului se reduce
la O(N3+VMAX), unde VMAX este diferena dintre valoarea maxim i minim a unei sume
dintre cele N(N-1)/2 date.
Problema 11-12. ir circular
Se d un ir circular ce const din N elemente: 1, 2, ..., N. Iniial ne aflm poziionai pe
elementul e(1). De fiecare dat cnd ajungem pe o poziie i, trebuie s naintm de x(i)0 ori
n sens cresctor (dac s(i)=1) sau descresctor dac (s(i)=-1). Urmtoarele y(i)>0 poziii
(ncepnd de la cea pe care am ajuns dup cele x(i) naintri) trebuie eliminat, dup care
trecem pe elementul urmtor (n sensul n care am efectuat parcurgere pn atunci). Afiai
elementele n ordinea n care acestea sunt eliminate.
Soluie: O prim soluie const n meninerea unor valori next i prev pentru fiecare poziie i.
next(i) este poziia care urmeaz dup i n sens cresctor, iar prev(i) este poziia care urmeaz
dup i n sens descresctor. Vom menine valoarea curent poz, iniial 1, precum i numrul
de elemente rmase M (iniial M=N). Ct timp M>0 vom efectua urmtoarele aciuni. Vom
iniializa dou contoare k=(x(poz) mod M) i l=y(poz), i un sens sk=s(poz). Apoi vom
efectua atribuirea poz=next(poz) (poz=prev(poz)) de k ori dac sk=1 (sk=-1). Dup aceea,
ct timp l>0, salvm poziia urmtoare poz (poz=next(poz), dac sk=1, sau prev(poz), dac
sk=-1) i tergem poziia poz din ir (o tergere se realizeaz astfel:
next(prev(poz))=next(poz); prev(next(poz))=prev(poz)). Dup tergere decrementm M cu 1,
decrementm l cu 1, i setm poz=poz. Dac valorile x(*) sunt mari, aceast soluie are

128

complexitatea O(N2). Pentru acest caz, putem folosi un arbore de intervale pentru a gsi mai
rapid urmtoarea poziie ce trebuie tears. De exemplu, s presupunem c naintm n sens
cresctor de k ori de la poziia poz. Vom calcula (folosind arborele de intervale) cte poziii q
mai sunt active n intervalul [poz+1,N]. Dac sunt mai puin de k, setm k=k-q i mutm poz
la prima poziie existent mai mare sau egal cu 1 (o putem gsi n timp logaritmic, dac
meninem n fiecare nod al arborelui de intervale cte poziii active (neeliminate) exist n
subarborele asociat acestuia). Pentru a determina a k-a poziie activ din intervalul [poz,N],
parcurgem arborele de intervale de la rdcin spre frunze. Dac fiul stnga al nodului la
care am ajuns conine qleftk poziii active, mergem n fiul stnga; altfel mergem n fiul
dreapta, dar nu naintea de a seta k=k-qleft. Cazul parcurgerii n sens descresctor se trateaz
n mod similar. O tergere a unei poziii poz se realizeaz prin decrementarea cu 1 a
numrului de poziii active din toate nodurile de pe drumul de la frunza corespunztoare
intervalului de poziii [poz,poz] pn la rdcina arborelui de intervale. Astfel, obinem o
complexitate O(Nlog(N)). Putem folosi i o mprire n O(sqrt(N)) grupuri de cte
O(sqrt(N)) poziii, caz n care meninem, pentru fiecare grup, cte poziii active exist n
grupul respectiv. n felul acesta, putem gsi n timp O(sqrt(N)) a k-a poziie la care trebuie s
ajungem (cutm liniar n grupul ce conine poziia poz; apoi, atta timp ct k0, srim peste
cte un grup ntreg, decrementnd k cu numrul de poziii active din grup; dac k devine 0
anulm ultima modificare a lui k i cutm liniar poziia dorit n cadrul grupului la care am
ajuns).
Exist i alte variante ale problemei prezentate, ns, n afara unor cazuri particulare, cele
dou tehnici prezentate (cea bazat pe next/prev i cea bazat pe arbori de intervale sau pe
mprirea n O(sqrt(N)) grupuri de cte O(sqrt(N)) poziii, pot fi folosite pentru a rezolva
orice astfel de problem.
Problema 11-13. Lume liniar (ACM ICPC SEERC 2005)
Se d o lume sub forma unui segment de dreapt orizontal de lungime L (captul stng
este la x=0 i captul drept la x=L). n aceast lume se afl N persoane care se deplaseaz cu
aceeai vitez V. La momentul t=0, fiecare persoan i se afl la coordonata x(i) (0x(i)L) i
i ncepe deplasarea n sensul s(i) (s(i)=+1, pentru sensul cresctor al coordonatelor x i -1
pentru sensul descresctor), 1iN. Cnd 2 persoane se ntlnesc, una venind din sensul
cresctor iar cealalt din sensul descresctor, acestea i schimb instantaneu sensul. Cnd o
persoan ajunge la marginea segmentului (din stnga sau din dreapta), aceasta cade de pe
segment i dispare. Determinai care persoan cade ultima i dup ct timp. Se garanteaz c
nu exist dou persoane care s cad de pe segment simultan i c oricare dou persoane au
coordonatele x(i) distincte.
Soluie: Observm c atunci cnd 2 persoane se ntlnesc este ca i cum acestea ar trece una
pe lng cealalt, deoarece fiecare continu traiectoria celeilalte. Pentru a determina dup ct
timp cade ultima persoan, vom calcula pentru fiecare persoan i, valoarea T(i)=momentul
de timp la care aceast persoan ar cdea de pe segment, n condiiile n care trece pe lng
persoanele pe care le ntlnete (adic nu i schimb sensul la fiecare ntlnire). Dac s(i)=1,
atunci T(i)=(L-x(i))/V; dac s(i)=-1, atunci T(i)=x(i)/V. Durata de timp Tmax dup care cade
ultima persoan este max{T(i)}. n mod similar, durata de timp dup care cade prima
persoan este min{T(i)}.
Pentru a determina care este persoana care cade ultima, vom proceda n felul urmtor.
Vom sorta coordonatele x(i), astfel nct s avem x(o(1))<x(o(2))<...<x(o(N)). S definim

129

po(i)=poziia pe care apare persoana i n aceast ordonare (o(po(i))=i). Pentru 0tTmax,


putem determina poziiile xp(i,t)= x(i)+s(i)Vt. La momentul t, va exista cte o persoan la
fiecare din poziiile xp(i,t) (1iN) (presupunnd c segmentul ar avea lungime inifinit i nu
ar cdea nimeni). Observm c, ntruct atunci cnd doi oameni se ntlnesc acetia i
schimb sensul, ordinea relativ a celor N persoane (considernd coordonatele lor x) rmne
mereu aceeai. Aadar, dac sortm poziiile xp(i,t) astfel nct s avem
xp(q(1),t)xp(q(2),t)....xp(q(N),t), atunci persoana o(i) se va afla la momentul t la
coordonata xp(q(i),t) (1iN). S considerm persoana px pentru care Tmax=T(px). Fie
pq(px) poziia lui xp(px, Tmax) n ordonarea xp(q(1),Tmax)...xp(q(N),Tmax), adic
q(pq(px))=px. La momentul Tmax, la coordonata xp(px,Tmax)=0 sau L (unul din capetele
segmentului) se va afla persoana o(pq(px)). Se observ uor c algoritmul descris are
complexitatea O(Nlog(N)).
Problema 11-14. Regele Alb-Negru (SGU)
Pe o tabl de ah de dimensiuni NxN (2N106) se afl amplasai (n poziii distincte) 3
regi: regele alb, regele negru i regele alb-negru. Regele alb-negru este invizibil i reprezint
o ameninare pentru regele alb i regele negru. Regele alb i regele negru vor s se
ntlneasc pentru a stabili o alian mpotriva regelui alb-negru. Pentru aceasta, cei 2 regi
(alb i negru) trebuie s ajung n dou poziii alturate (pe orizontal, vertical sau
diagonal). Mutrile ncep la momentul de timp 0 i alterneaz n felul urmtor. nti mut
regele alb, apoi regele negru, apoi regele alb-negru, iar apoi ciclul de mutri se reia (fiecare
rege se poate muta ntr-o poziie alturat pe orizontal, vertical sau diagonal, cu condiia
s nu prseasc tabla de ah). Regele alb i regele negru se deplaseaz unul spre altul pe
unul din drumurile de lungime minim de pe tabl. Regele alb-negru se deplaseaz ctre unul
din cei doi regi. Dac n urma unei mutri efectuate de regele alb-negru, acesta ajunge pe o
poziia ocupat de regele alb sau de cel negru, atunci regele respectiv este omort (i aliana
este, astfel, mpiedicat). Dac regele alb sau regele negru, n urma mutrilor lor, ajung pe
poziia ocupat de regele alb-negru, atunci nu se ntmpl nimic. Regii nu au voie s stea pe
loc atunci cnd le vine rndul s mute. n plus, regele alb-negru se deplaseaz conform
urmtoarei proprieti: dac, la un moment dat, se afl n poziia (L,C), atunci el a urmat unul
din drumurile de lungime minim din poziia sa iniial pn la poziia (L,C).
Considernd c regele alb-negru i-ar putea influena pe regele alb i pe cel negru s
aleag unul din drumurile de lungime minim alese de regele alb-negru, determinai numrul
minim de mutri efectuate de regele alb-negru dup care unul din cei doi regi (alb sau negru)
moare (dac acest lucru este posibil).
Soluie: Fie (LA,CA), (LB,CB) i (LAB,CAB) coordonatele (linie,coloan) ale regelui alb,
regelui negru i regelui alb-negru. Vom roti i/sau oglindi tabla de ah i/sau vom
interschimba liniile cu coloanele, dup cum este necesar, pentru a ajunge n situaia: CA<CB,
LALB i CB-CALB-LA. Astfel, la fiecare mutare a regelui alb, coloana pe care se afl
acesta va crete, iar la fiecare mutare a regelui negru, coloana pe care se afl acesta va scdea.
Numrul de poziii intermediare dintre poziia regelui alb i cea a regelui negru este D=CBCA-1. Numrul maxim de mutri pe care le poate efectua regele alb-negru este Dmax=(D-1)
div 2.
Vom ncerca, pe rnd, fiecare numr de mutri x (1xDmax), n ordine cresctoare, i
vom verifica dac este posibil ca regele alb-negru s omoare pe regele alb sau pe regele
negru exact la a x-a mutare a regelui alb-negru. Pe drumurile pe care le urmeaz, regele alb i

130

regele negru se afl mereu n interiorul unui paralelogram avnd dou laturi paralele cu
liniile tablei de ah i dou laturi paralele cu diagonalele secundare. Fie Dif=(CB-CA)-(LBLA). Latura de sus (de pe linia cu indice mai mic) conine segmentul orizontal dintre poziiile
(LA, CA) i (LA, CA+Dif). Latura de jos (de pe linia cu indice mai mare) conine segmentul
orizontal dintre poziiile (LB, CB-Dif) i (LB, CB). Paralelogramul conine toate poziiile de
pe conturul i din interiorul su. Acest paralelogram poate fi i degenerat: un segment
orizontal (dac LA=LB) sau un segment de pe o diagonal secundar, dac Dif=0.
Dup x mutri efectuate, regele alb se afl pe coloana CA+x, undeva n interiorul
paralelogramului, iar regele B pe coloana CB-x, tot undeva n interiorul paralelogramului.
Vom calcula segmentele verticale VA i VB ce corespund interseciei unei coloane C (CA+x
sau CB-x) cu interiorul (i conturul) paralelogramului (aceste segmente reprezint intervale
de linii de pe coloanele respective). Dup x mutri, regele alb-negru se afl pe conturul unui
ptrat de latur 2x+1, avnd centrul n poziia sa iniial. Trebuie doar s verificm dac
vreunul din segmentele VA i VB (calculate anterior) intersecteaz conturul ptratului (l
ating cu unul din capete, l intersecteaz efectiv sau se suprapun parial sau total pe una din
laturile verticale ale sale). Dac intersecia dintre VA sau VB cu conturul ptratului regelui
alb-negru este nevid, atunci exist o posibilitate ca la a x-a mutare, regele alb-negru s
omoare unul din ceilali doi regi. Dac intersecia este vid, atunci vom trece la urmtoarea
valoare a lui x (x+1).
Dac nu am gsit o intersecie nevid pentru nicio valoare a lui x, atunci regele alb-negru
nu poate mpiedica ntlnirea regilor alb i negru.
Problema 11-15. Butura otrvit (SGU)
Pe masa unui rege se afl N (1N100.000) pahare cu vin, dintre care se tie c unul a
fost otrvit (cu o otrav letal). Regele dorete s identifice paharul cu vin otrvit. Pentru
aceasta, el are la dispoziie un numr foarte mare de servitori. El poate alege o parte dintre
servitori (fie M numrul lor) i poate asigna fiecruia o submulime de pahare de vin. Apoi,
fiecare servitor gust din fiecare pahar din submulimea asignat. Otrava nu omoar imediat,
ci dup o perioad suficient de lung de timp, astfel c orice servitor, chiar dac bea la un
moment dat din paharul cu vin otrvit, va tri suficient de mult pentru a bea din toate
paharele din submulimea asignat. Determinai numrul M minim de servitori, precum i
submulimile asignate acestora, astfel nct regele s poat identifica paharul cu vin otrvit.
Identificarea se face dup un timp suficient de lung (mai lung dect timpul n care i-ar face
efectul otrava), dup care se va ti, pentru fiecare servitor ales i (1iM), dac a murit sau
dac a supravieuit.
Soluie: n mod clar, o soluie posibil este ca regele s aleag M=N servitori i fiecare s
guste din cte un pahar (servitorul i din paharul i). n felul acesta, va muri un singur servitor,
care va identifica n mod unic paharul cu otrav. Totui, problema poate fi rezolvat i cu
M=ceil(log2(N)) servitori. Servitorului i (1iM) i se va asigna submulimea de pahare cu
numere de ordine j care au proprietatea c j are al i-lea bit egal cu 1 (vom numerota biii de la
1 la M). Astfel, dac un servitor i moare, vom ti sigur c paharul otrvit are al i-lea bit egal
cu 1; dac servitorul i supravieuiete, atunci al i-lea bit al numrului de ordine al paharului
otrvit este 0. n felul acesta, putem identifica fiecare bit al numrului de ordine al paharului
otrvit (i, deci, putem calcula acest numr).

131

Problema 11-16. Numere idempotente (TIMUS)


Determinai toate numerele x (0xN), astfel nct xx=x (mod N), unde N
(6N1.000.000.000) este produsul a dou numere prime distincte.
Soluie: Este clar c x=0 i x=1 sunt soluii pentru orice N. n afar de 0 i 1, mai exist
exact alte 2 soluii. nti vom determina cele 2 numere prime P i Q, astfel nct N=PQ.
Pentru aceasta, vom considera toate numerele P de la 2 la sqrt(N). Dac N mod P=0, atunci
numrul Q este N div P. Dup ce am determinat numerele prime P i Q, vom folosi
algoritmul lui Euclid extins, pentru a determina coeficienii a i b, astfel nct aP+bQ=1.
Unul din coeficieni este pozitiv, iar cellalt negativ. Dac a>0, atunci setm x1=aP i
x2=(b+P)Q. Dac b>0, atunci setm x1=bQ i x2=(a+Q)P. x1 i x2 sunt celelalte 2 soluii
ale ecuaiei date. Vom justifica acest lucru pentru a>0 (cazul b>0 este simetric, prin
nlocuirea lui a cu b i a lui P cu Q). Avem aP=(1-bQ). (aP)2=aP(1-bQ)=aPabPQ=aP (mod (PQ)). Aadar, ecuaia este verificat. Egalitatea aP+bQ=1 poate fi
scris sub forma aP-PQ +bQ+PQ=1 => (a-Q)P+(b+P)Q=1. ntruct |b|<P, avem c
b+P>0. Acum putem scrie a=b+P i b=a-Q, obinnd aQ+bP=1. Putem folosi aceeai
justificare ca mai sus (pentru aP), pentru aQ.

132

Capitolul 12. Probleme Interactive


Problema 12-1. Master Mind (Olimpiada Balcanic de Informatic 2001, enun
modificat)
Se consider un ir secret S de N (1N5) cifre, fiecare cifr lund valori de la 0 la M-1
(0M10). Pentru a ghici irul secret, putei pune ntrebri n care s dai ca parametru un ir
SA de N cifre ales de dumneavoastr. Modulul cu care interacionai v rspunde cu
urmtoarele informaii:
cazul 1: NC=n cte poziii coincid irul secret S i irul SA
cazul 2: NC=n cte poziii coincid irul secret S i irul SA; n plus, fie NCW=numrul
maxim de poziii din SA care pot coincide cu poziiile din S, considernd cea mai
favorabil permutare a cifrelor lui SA => se rspunde i cu valoarea NCE=NCW-NC.
Determinai irul secret folosind un numr ct mai mic de ntrebri.
Soluie: S considerm mulimea SC a tuturor celor MN iruri candidate pentru a fi irul
secret. Ct timp |SC|>1 vom alege un ir candidat SA. Pe baza rspunsului primit, vom
parcurge toate irurile din S i le vom elimina pe acele iruri S pentru care rspunsul nu s-ar
potrivi cu irul SA (n cazul 1: S este eliminat dac nu are NC poziii comune cu SA; n cazul
2, S este eliminat dac nu are NC poziii comune cu SA sau dac numrul maxim de poziii
n care coincide cu SA, considernd orice permutare posibil a cifrelor lui S, nu este
NC+NCE).
Este de dorit s ajungem ct mai repede ca mulimea SC s conin un singur ir (irul
secret). Pentru aceasta, este important modalitatea n care alegem la fiecare pas irul
candidat SA. Avem mai multe variante. Una din ele const n a alege un ir oarecare din SC.
A doua variant const n a considera fiecare ir S din SC (sau chiar dintre toate irurile
posibile) i a considera toate rspunsurile posibile dac S ar fi ales drept irul candidat SA
(aceste rspunsuri se obin ca reuniune a rspunsurilor obinute dac am considera fiecare ir
S din SC ca fiind irul secret ; bineneles, se elimin rspunsurile duplicate din reuniune).
Pentru fiecare rspuns calculm care ar fi cardinalul lui SC dup eliminarea irurilor care nu
ar corespunde cu acel rspuns; i atam lui S o pondere egal cu cardinalul maxim al lui
SC obinut n fiecare din rspunsurile posibile. Vom alege drept ir candidat SA acel ir S
pentru care ponderea este minim.
Dac se cunosc informaii suplimentare despre irul secret S (de ex., conine cel puin l(i)
i cel mult h(i) cifre cu valoarea i, 0iM-1), atunci vom porni cu o mulime SC redus, ce va
conine doar acele iruri care satisfac restriciile suplimentare.
Problema 12-2. Platou (Lotul Naional de Informatic, Romnia, 2006)
Se consider un ir de 2N elemente care sunt numere ntregi. Se definesc noiunile: (1)
platou=o secven de elemente egale aflate n vector n poziii consecutive; (2) lungimea
unui platou ca fiind numrul de elemente care alctuiesc un platoul.
Se tie c n irul considerat, lungimea maxim a unui platou este 2K (0KN) i c exist
cel puin un platou care are aceast lungime. Amplasarea unui platou este determinat de
poziia cea mai mic i de poziia cea mai mare dintre poziiile elementelor care alctuiesc
platoul. irul nu este cunoscut. Tot ceea ce putei face este s punei ntrebri de forma: care

133

este lungimea cea mai mare a unui platou din ir aflat ntre poziiile p1 i p2 ? (1p1p22N).
Avei voie s punei maxim N-K+3 ntrebri.
Soluie: O soluie foarte simpl este urmtoarea. Vom cuta binar cel mai mic indice pmin,
astfel nct lungimea maxim a unui platou din intervalul de poziii [1,pmin] este 2K. pmin se
poate afla n intervalul [2K,2N]. Dac n cadrul cutrii binare vrem s testm o valoare pcand,
ntrebm care este lungimea L a unui platou coninut n intervalul [1,pcand]. Dac L2K,
atunci pcandpmin; altfel, pcand<pmin. Dup gsirea lui pmin, platoul se afl ntre poziiile
pmin-2K+1 i pmin. Aceast soluie pune log2(2N-2K+1) ntrebri. O soluie mai bun este
urmtoarea, care const din 2 etape:
1) Localizarea unui interval de poziii [p1,p2] de lungime cel mult 22K=2K+1, n care se afl
un platou de lungime 2K.
2) Localizarea platoului de lungime 2K n interiorul intervalului.
Pentru etapa 1), putem folosi urmtorul algoritm, bazat pe cutare binar. Alegem un
indice pd, care va avea semnificaia c n stanga lui (inclusiv pd) se termin un platou de
lungime 2K i un indice ps cu semnificaia c n stanga lui (exclusiv ps) nu se termin nici un
platou de lungime 2K. Iniial ps=1, pd=2N. ntr-o bucl while facem urmatoarea cutare :
ct timp (pd-ps>2K)
pmid=(ps+pd)/2;
ntrebm de intervalul [p1=1,p2=pmid] i primim rspunsul R
dac R=2K atunci pd=pmid altfel ps=pmid+1
Numrul de pai pentru aceast bucl e log2(2N/2K)=N-K. Intervalul [p1=max{pd-22K+1,
1}, p2=pd] are proprietatea c sigur conine un platou de lungime 2K. Dac [p1,p2]=[1,2K],
atunci am gsit platoul pe primele 2K poziii. Altfel, mai avem de pus 3 ntrebri
suplimentare. Notm cu pmid=(p1+p2)/2 i efectum 2 interogri: ls=ntrebare(p1, pmid) i
ld=ntrebare(pmid+1,p2). Avem urmtoarele cazuri:
dac ls=2K, atunci platoul se afl ntre poziiile p1 i pmid
dac ld=2K, atunci platoul se afl ntre poziiile pmid+1 i p2
dac ls+ld=2K, atunci paltoul se afl ntre poziiile pmid-ls+1 i pmid+ld
dac ls+ld>2K, atunci ntre poziiile p1 si p2 se mai afl (pe lng platoul de lungime 2K),
o bucat dintr-un platou de lungime2K; platoul de lungime 2K se afl :
o cazul 1: ntre poziia din stnga=pmid-ls+1 i poziia din drepata=pmidls+2K
(intervalul I1); sau
o cazul 2: ntre pozitia din dreapta=pmid+ld i poziia din stnga=pmid+ld-(2K-1)
(intervalul I2)
Pentru a stabili care din aceste situaii are loc, mai este necesar o ntrebare (de ex.,
ntrebm pentru intervalul I1 i dac obinem ca rspuns chiar lungimea intervalului I1, atunci
suntem n cazul 1; altfel, suntem n cazul 2). Aadar, pentru a rezolva etapa 2) mai sunt
necesare 3 ntrebri. n total sunt necesare cel mult N-K+3 ntrebri. Pentru N=20 i K=13,
aceast soluie pune cel mult 10 ntrebri, n timp ce prima soluie descris pune 20 ntrebri.
Problema 12-3. Maxim (Lotul Naional de Informatic, Romnia, 2006)
Se consider un ir x cu N (3N1.000.000) componente numere ntregi. Se tie c
oricare dou componente din ir sunt diferite. Elementul din poziia p (2pN-1) este maxim
local dac este strict mai mare dect elementele din poziiile p-1 i p+1. Ultimul element din
ir este maxim local dac este strict mai mare dect elementele din poziiile 1 i N-1 iar
primul element din ir este maxim local dac el este strict mai mare dect elementele din

134

poziiile 2 i N. Dumneavoastr nu cunoatei irul. Determinarea poziiei unui element care


este maxim local se face adresnd ntrebri comisiei. O ntrebare const n a preciza trei
poziii din ir, fie acestea p1, p2 i p3. La o ntrebare Q(p1,p2,p3) putei primi unul din
urmtoarele 4 rspunsuri:
1, dac ntre cele trei elemente din x avem relaiile x[p1]<x[p2] i x[p2]<x[p3]
2, dac ntre cele trei elemente din x avem relaiile x[p1]<x[p2] i x[p3]<x[p2]
3, dac ntre cele trei elemente din x avem relaiile x[p1]>x[p2] i x[p2]>x[p3]
4, dac ntre cele trei elemente din x avem relaiile x[p1]>x[p2] i x[p2]<x[p3]
Putei folosi cel mult 25 de ntrebri.
Soluie: S presupunem c am gsit trei poziii p1, p2 i p3, reprezentnd intervalul de poziii
[p1,p3] (cu p2 ntre p1 i p3 n sensul de pe interval), astfel nct x[p1]<x[p2] i x[p2]>x[p3].
Vom efectua o interogare pentru poziiile p1, p2 i p2, calculate astfel: p1=(p1+p2) div 2 ;
p2=(p2+p3)/2 i n funcie de rspunsul primit avem urmtoarele cazuri:
2 : aplicm acelai raionament pentru poziiile p1, p2, p2, deci pentru intervalul
[p1,p2]
1 : aplicm acelai raionament pentru intervalul p2, p2, p3, deci pentru intervalul [p2,p3]
3 : aplicm acelai raionament pentru intervalul p1, p1, p2, deci pentru intervalul [p1,p2]
4 : aplicm acelai raionament pentru oricare din intervalele [p1,p2] (cu p1 n interval)
sau [p2,p3] (cu p2 n interval)
Se observ c pentru oricare din cele patru cazuri intervalul de poziii a fost redus la
jumtate. Astfel, n log2(N) pai putem gsi 3 poziii consecutive p1, p2 i p3, unde p2 este
maxim local. Pentru a gsi un prim interval de poziii care respect condiia x[p1]<x[p2] i
x[p3]<x[p2], facem o prim interogare pentru poziiile 1, n/3 i 2n/3 i n funcie de rspuns,
avem urmtoarele cazuri:
1 : poziiile iniiale (p1,p2,p3) sunt n/3, 2n/3 i 1
2 : poziiile iniiale (p1,p2,p3) sunt 1, n/3, 2n/3
3 : poziiile iniiale (p1,p2,p3) sunt 2n/3, 1, n/3
4 : este necesar nc o interogare care s decid care din numerele de pe poziiile 1 sau
2n/3 este mai mare (de ex., Q(n/3,2n/3,1) => dac rspunsul este 1 sau 4, vom avea
(p1,p2,p3)=(2n/3, 1, n/3); altfel, (p1,p2,p3)=(n/3, 2n/3, 1))
Problema 12-4. Dreptunghi
S considerm o reea de NN (1N31.000) celule, n care colul din stnga-sus are
coordonatele carteziene (1,1). n interiorul acestei reele se afl un dreptunghi (pe care l vom
nota n continuare cu D1) cu laturi paralele cu axele de coordonate, compus din celule ale
reelei. Determinai amplasarea dreptunghiului D1, punnd ntrebri de tipul urmtor: dai ca
argument al ntrebrii un dreptunghi D2 (prin liniile i coloanele celulelor ce reprezint
colurile stnga-sus i dreapta-jos), iar rspunsul la ntrebare este numrul de celule din
intersecia dreptunghiului cutat D1 cu dreptunghiul D2 dat ca argument. Avei voie s
punei maxim 31 de ntrebri.
Soluie: Se ncepe cu o ntrebare cu toat suprafaa, aflnd astfel numrul np de celule din
D1. Cutm apoi binar linia de sus a unuia dintre coluri, ntrebnd cu dreptunghiuri ce
conin toate coloanele i numr de linii variabil (intervalul ce corespunde valorilor candidate
pentru linia de sus se njumtete la fiecare pas). Iniial, acest interval este [1,N]. Cnd

135

ntrebm cu primele x linii ale dreptunghiului. Fie nr numarul de puncte pe care le primim ca
rspuns:
dac nr=0, atunci linia de sus a lui D1 este x i pstrm jumtatea de interval ce
conine valorile mai mari dect x;
dac nr>0, atunci linia de sus a dreptunghiului D1 este x;
Ne oprim cnd intervalul nostru conine o singur linie (adi e de forma [lin,lin]). Vom
reine numrul de puncte ncol de la ultima ntrebare cu rspuns strict pozitiv (iar linia de sus
este linia lin). Dac toate rspunsurile au fost 0, atunci linia de sus este linia lin, ea coninnd
ncol=np puncte.
Dup aceste prime log2(N) ntrebri, putem deduce i numrul de linii nlin=np/ncol. Dac
ncol>1, vom pune ntrebri cu un dreptunghi D2 avnd o singur linie (linia de sus a lui D1),
coloana din stnga egal cu 1 i coloana din dreapta variabil. Cutm, astfel, binar coloana
din stnga a lui D1. Cutarea este similar primei etape. Dac rspunsul este 0 pentru o
coloan dreapta y, va trebui s cutm valori mai mari ale lui y; dac rspunsul este >0,
coloana cutat este y. n acest moment, dup 2log2(N)+1 ntrebri, am gsit un col al
dreptunghiului i dimensiunile acestuia, identificnd, astfel, complet dreptunghiul.
O alt soluie este urmtoarea. Dup ntrebarea iniial din care aflm numrul de puncte
np din dreptunghi, vom pune ntrebri cu dreptunghiuri avnd N coloane. Vom menine un
interval [A,B] (ncepem cu A=1 i B=N). Pentru un interval [A,B], vom pune o ntrebare cu
liniile cuprinse ntre A i (A+B) div 2. Dac rspunsul nr este np, atunci setm B=(A+B) div
2; dac nr=0, atunci A=((A+B) div 2) + 1. Ne oprim cnd A=B sau rspunsul nr este ntre 1
i np-1 (inclusiv). n acest moment, suntem siguri c linia ((A+B) div 2) taie dreptunghiul.
Fie ultimul rspuns primit nq (i A<B) i linia care taie dreptunghiul o notm prin C. Vom
cuta binar linia de sus a dreptunghiului, n intervalul [A=A, C=C]. Vom pune ntrebri cu
dreptunghiuri avnd N coloane i linii cuprinse ntre (A+C) div 2 i C. Dac rspunsul nr
este <nq, atunci setm C=((A+C) div 2)-1; dac nr=nq, atunci setm A=((A+C) div
2)+1. Vom reine indicele ultimei linii Lsus=(A+C) div 2 (pentru intervalul [A,C]
considerat la momentul respectiv) pentru care rspunsul a fost egal cu nq. Astfel, am
identificat linia de sus a dreptunghiului n log2(N) ntrebri n total. Putem identifica i
numrul de coloane ncol=nq/(C-Lsus+1) i, apoi, numrul de linii nlin=np/ncol. Apoi vom
cuta coloana cea mai din stnga, punnd alte log2(N) ntrebri cu dreptunghiuri ce conin N
linii (n mod similar celui n care cutm coloana stnga n soluia anterioar). i aceast
soluie pune tot 2log2(N)+1 ntrebri.
Problema 12-5. Meandian (Olimpiada de Informatic a Europei Centrale, 2006)
Se consider un ir ce conine N (4N1000) elemente distincte: a(1), ..., a(N). Avem la
dispoziie urmtoarea operaie: Meandian(i1, i2, i3, i4). Aceast operaie sorteaz cresctor
elementele a(i1), a(i2), a(i3), a(i4) (s presupunem c ordinea lor este
a(j1)<a(j2)<a(j3)<a(j4), unde {j1, j2, j3, j4}={i1, i2, i3, i4}) i ntoarce media celor 2
elemente din mijloc ((a(j2)+a(j3))/2). Cei 4 indici i1, ..., i4, trebuie s fie diferii unul de
altul. Folosind aceast operaie de cel mult 10.000 de ori, determinai toate valorile a(1), ...,
a(N) ce pot fi determinate (mai exact, pentru fiecare indice i, determinai valoarea a(i), dac
aceasta poate fi determinat).
Soluie: Dac am considera valorile a(i) sortate cresctor, atunci fie i1 i i2 indicii celor mai
mici 2 valori (a(i1) i a(i2)), i i3 i i4 indicii celor mai mari 2 valori. Chiar dac am
cunoate indicii i1 i i2 (respectiv i3 i i4), nu am putea determina exact care sunt valorile

136

a(i1) i a(i2) (respectiv a(i3) i a(i4)). Astfel, vom putea determina exact doar N-4 valori din
irul a(1), ..., a(N).
S considerm c am ales 5 indici: i1, i2, i3, i4, i5 (i s presupunem c avem
a(j1)<a(j2)<a(j3)<a(j4)<a(j5), unde {j1, ..., j5}={i1, ..., i5}; ordinea j1, .., j5 nu este
cunoscut). Vom pune ntrebrile urmtoare:
b1=Meandian(i1, i2, i3, i4)
b2=Meandian(i1, i2, i3, i5)
b3=Meandian(i1, i2, i4, i5)
b4=Meandian(i1, i3, i4, i5)
b5=Meandian(i2, i3, i4, i5)
Vom sorta valorile b1, ..., b5, astfel nct s avem c1c2c3c4c5 (unde c1, ..., c5, sunt
o permutare a valorilor b1, .., b5; iar ci corespunde valorii bp(i)). Referindu-ne la valorile
j1, ..., j5 menionate anterior, sunt evidente urmtoarele lucruri:
c1=Meandian(j1, j2, j3, j4)=(a(j2)+a(j3))/2
c2=Meandian(j1, j2, j3, j5)=(a(j2)+a(j3))/2=c1
c3=Meandian(j1, j2, j4, j5)=(a(j2)+a(j4))/2
c4=Meandian(j1, j3, j4, j5)=(a(j3)+a(j4))/2
c5=Meandian(j2, j3, j4, j5)=(a(j3)+a(j4))/2=c4
Vom considera acum urmtorul sistem cu 3 ecuaii i 3 necunoscute:
2c1=a(j2)+a(j3)
2c3=a(j2)+a(j4)
2c5=(a(j3)+a(j4))
Rezult a(j2)=2c1-a(j3); a(j4)=2c5-a(j3). nlocuind n a 2-a ecuaie, obinem
2(c1+c5)-2a(j3)=2c3 => a(j3)=c1+c5-c3. Pentru a determina efectiv i indicele j3 (din
mulimea {i1, ..., i5}), alegem rezultatul bp(3)=c3. tim c bp(3) este rezultatul acelei
ntrebari Meandian care a implicat toi ceilali indici n afar de j3. Astfel, j3 este acel indice
care nu a fost folosit n ntrebarea n urma creia s-a obinut rezultatul bp(3)=c3.
Astfel, dup 5 ntrebri, am reuit s determinm o valoare dintre oricare 5 indici i1, ..., i5.
Vom folosi aceast metod pentru a determina toate cele N-4 valori ce pot fi determinate,
punnd 5(N-4) ntrebri. Vom menine o mulime S, pe care o iniializm la S={1,...,5}.
Punem cele 5 ntrebri pentru cei 5 indici din S i determinm indicele j3 (i a(j3)). Apoi,
pentru i=6,...,N efectum urmtoarele aciuni:
(1) S=S\{j3}+{i} (j3 este indicele determinat la pasul anterior);
(2) determinm indicele j3 (i valoarea a(j3)) considernd cei 5 indici din S.
Deci, n mod repetat, excludem din S indicele pentru care am determinat valoarea anterior
i adugm un nou indice.
Problema 12-6. Gsete punctul (Olimpiada Naional de Informatic, Croaia, 2005)
Se consider un spaiu d-dimensional n care se afl un punct special la coordonate ntregi
necunoscute. tim doar c el se afl n interiorul paralelipipedului [0,XMAX=109] d. Se
dorete identificarea locaiei punctului special n felul urmtor. Avei la dispoziie un punct
al dumneavoastr, care se afl iniial la coordonatele ntregi (x(1), ..., x(d)). Putei efectua
mutri conform cror punctul dumneavoastr se deplaseaz la orice alte coordonate ntregi
(x(1), x(2), ..., x(d)). Dup fiecare mutare vei afla dac noua poziie a punctului
dumneavoastr este mai aproape de poziia punctului special fa de poziia anterioar a
punctului dumneavoastr, sau mai deprtat (n caz de distan egal se poate rspunde

137

oricum). Distana folosit este cea eculidian. Gsii locaia punctului special folosind cel
mult 60d mutri.
Soluie: Vom determina fiecare coordonat a punctului special independent de celelalte. S
presupunem c vrem s determinm coordonata j (1jd). Vom efectua o cutare binar
dup coordonata j, dup cum urmeaz. Vom menine un interval [a,b] n care se poate afla
coordonata j a punctului special. Iniial, a=0, b=XMAX. Ct timp b>a vom efectua
urmtoarele aciuni. Modificm coordonata j punctului nostru astfel nct x(j)=a, apoi mutm
punctul nostru astfel nct x(j)=b (coordonatele jj rmn nemodificate). Dac la mutarea n
care am setat x(j)=b, punctul nostru este mai departe de punctul special, atunci vom seta
b=inf((a+b)/2); altfel, dac pentru x(j)=b punctul nostru este mai aproape de punctul special,
atunci setm a=sup((a+b)/2). Am notat prin inf(q)=parte ntreag inferioar din q i prin
sup(q)=parte ntreag superioar din q. Astfel, vom efectua 2log(XMAX)=60 mutri pentru
fiecare coordonat j (1jd).
Problema 12-7. Monede (Lotul Naional de Informatic, Romnia, 2003)
Avei la dispoziie N (2N32768; N par) monede, fiecare avnd unul din urmtoarele 3
tipuri: moned de aur (1), moned de argint (2) sau moned de bronz (3). Se tie c unul din
cele 3 tipuri este majoritar (exist cel puin N/2+1 monede din tipul respectiv). Se dorete
gsirea unei monede din tipul majoritar prin efectuarea de un numr minim de ori a
urmtoarei operaii: se formeaz N/2 perechi de monezi (fiecare moned face parte dintr-o
pereche) i se compar cele 2 monezi din cadrul fiecrei perechi. Rezultatul unei comparaii
poate fi 1 (cele 2 monezi sunt de acelai tip) sau 0 (cele 2 monezi sunt de tipuri diferite).
Rezultatul unei operaii este irul rezultatelor celor N/2 comparaii efectuate.
Soluie: n prima rund comparm monedele 2k-1 cu 2k (1kN/2). Fie S mulimea
monedelor 2k-1 cu proprietatea c 2k-1 i 2k sunt identice. Organizm S ca o list circular
dublu-nlnuit (elementele sunt aezate n list ntr-o ordine arbitrar). La runda 2,
comparm pe x cu prev(x) i next(x) unde prev i next se refer la relaia n lista dublunlnuit. Deoarece lista e circular, fiecare element din S apare n exact dou comparaii.
Cum facem asta ntr-o singur rund? Pi, tim c pentru orice x din S, x+1 este egal cu x.
Deci putem folosi x ntr-o comparaie i x+1 n cealalt. Folosind rezultatele de la comparaii,
grupm elementele din list n grupuri de elemente consecutive care sunt egale; primul
element din fiecare grup va fi reprezentantul grupului.
Organizm reprezentanii grupurilor ntr-o list circular dublu-nlnuit. La a treia
rund comparm x cu prev(prev(x)) i next(next(x)) unde prev i next se refer acum la lista
reprezentanilor. Folosind rezultatele acestor comparaii, putem afla tipul fiecrui
reprezentant. Deci tim tipul monedelor din fiecare grup, deci putem determina tipul
majoritar n mod trivial (prin numrare). Dar cum tim tipul reprezentanilor ? Primelor dou
elemente le atribuim arbitrar tipurile 1 i 2. n continuare examinm elementele pe rnd.
Dac x este egal cu prev(prev(x)), tim tipul lui x pentru c deja tim tipul lui prev(prev(x)).
Dac x este diferit de prev(prev(x)), mai tim i c el este diferit de prev(x) (din modul cum
am construit grupurile i reprezentanii), aa c tipul lui x este unic determinat ca fiind
singurul tip rmas (elementul din mulimea {1,2,3} din care eliminm tipul lui prev(x) i pe
cel al lui prev(prev(x))).
Putem demonstra c problema nu se poate rezolva n mai puin de 3 runde n cazul cel
mai defavorabil, construind un adversar care ne oblig s efectum 3 runde. Orice comparaii

138

ar efectua algoritmul n prima rund, adversarul rspunde egal la toate. Astfel se creeaz
perechi de elemente care sunt egale pe care le imaginm unite ntr-un singur element. La a
doua rund, algoritmul poate face maxim 2 comparaii cu fiecare element unit (pentru c un
astfel de element nseamn o pereche de elemente). Interpretate ca un graf, comparaiile
cerute formeaz o reuniune de cicluri i lanuri disjuncte. Dac graful nu e conex (exist cel
puin dou cicluri/lanuri), adversarul are o strategie destul de simpl. Pentru orice
component care conine mai puin de jumtate din noduri, adversarul rspunde egal la
toate comparaiile. Dac exist o component cu mai mult de jumate din noduri (evident
aceasta este unic), adversarul rspunde c jumate minus 1 dintre monede sunt de acelai tip,
i celelalte sunt de alt tip. Dac algoritmul ncerc s dea rspunsul la problem, se poate
construi uor un aranjament al monedelor care reprezint un contraexemplu i este consistent
cu rspunsurile date de adversar. Deci algoritmul trebuie s mai efectueze cel puin o rund.
Dac graful este conex, adversarul rspunde diferit la toate comparaiile. Din nou, dac
algoritmul ncearc s dea rspunsul la problem, se poate construi uor un contraexemplu
care arat c rspunsul nu e adevrat. Deci algoritmul mai trebuie s efectueze o rund. n
consecin, este nevoie de minim 3 runde n cel mai defavorabil caz.

139

Capitolul 13. Transformri, Evaluri, Ecuaii i


Sisteme de Ecuaii
Problema 13-1. Ecu (Lotul Naional de Informatic, Romnia, 2003)
Gigel are de rezolvat un sistem complicat de ecuaii neliniare i pentru aceasta
intenioneaz s foloseasc o metod iterativ care, sper el, va converge ctre soluie dup
un numr rezonabil de iteraii. Mai nti, el alege nite valori iniiale pentru cele N
necunoscute ale sistemului. Aceste valori se noteaz cu x ( 0) x(0) ... x( 0) . n continuare, dup
1

fiecare iteraie, el va modifica valorile necunoscutelor, conform urmtoarelor relaii:

x(ki ) = p k x(ik1 ) + 1 p k +1 x(ki+1)1+ y k , pentru 1k<N

x(Ni ) = p N x(iN1 ) + 1 p1 x1(i1) + y N

unde prin

(i )

xk

s-a notat valoarea necunoscutei k dup i iteraii. pk reprezint ponderea

asociat necunoscutei k, iar y k reprezint corecia aplicat necunoscutei k, dup fiecare


iteraie.
Dndu-se valorile iniiale ale celor N (2N30) necunoscute, ponderile asociate i
coreciile aplicate, s se determine valorile necunoscutelor dup M (0M109) iteraii.
Soluie: S notm cu x(i,j) valoarea necunoscutei i dup j iteraii. x(i,0) sunt date.
x(i,1) = p(i)x(i,0) + (1-p(i+1))x(i+1,0) + y(i)
x(i,2) = p(i)x(i,1) + (1-p(i+1))x(i+1,1) + y(i) =
p(i)( p(i)x(i,0) + (1-p(i+1))x(i+1,0) + y(i) ) +
p(i+1)( p(i+1)x(i+1,0) + (1-p(i+2))x(i+2,0) + y(i+1)).
x(i,j) se poate scrie ca o funcie liniar de valorile iniiale. Astfel,
x(i,j) = c(i,j,1)x(1,0) + c(i,j,2)x(2,0) + .. + c(i,j,N)x(N,0) + c(i,j,0) ,
unde c(i,j,k) cu k de la 0 la N sunt nite constante reale. Evident, dac am determina c(i,M,k)
cu k de la 0 la N am putea afla valorea lui x(i,M) (exact ceea ce ne intereseaz).
Observm c nu ne intereseaz toate valorile c(i,j,k), ci numai valorile de tipul c(i,2p,k)
(adic numai dupa un numr de iteratii egal cu o putere a lui 2). S considerm c am
calculat aceste valori. Atunci putem determina c(i,M,k), parcurgnd reprezentarea binar a lui
M. S considerm c primul bit de 1 al lui M se afl pe poziia p. Atunci, c(i,M,k)=Suma de
la j=0 la N din c(i,2p,j)c(j,M-2p,k) (este similar cu nmulirea de matrici; de fapt, problema se
poate rezolva i considernd relaii ntre matrici i vectori). Rmne de determinat c(i,M2p,k), care se determin ca i pentru M (M-2p este M fr cel mai semnificativ bit de 1).
Valorile c(i,2p,k) sunt egale cu:
c(i,2p,k)=Suma de la j=0 la N din c(i,2p-1,j)c(j,2p-1,k).
Valorile c(i,1,k) sunt usor de determinat, din relatiile date n enun, cci x(i,1) =
c(i,1,i)x(i,0)+c(i,1,i+1)x(i+1,0)+c(i,1,0). Pentru a nu lucra efectiv cu termeni constani, se
poate considera c exist o necunoscut n plus, cu numrul 0, a crei valoare este egal cu 1
i nu se modific n cursul unei iteraii. In schimb, relaiile de calcul devin:
x(i,j) = p(i)x(i,j-1)+(1-p(i+1))x(i+1,j-1)+y(i)x(0,j-1), unde x(0,k)=1 (k 0).

140

Astfel, complexitatea algoritmului este O(N3log(M)) i memoria folosit este


O(N2log(M)).
Problema 13-2. Expresii min-max (Happy Coding 2006, infoarena)
Considerai o expresie care conine numere naturale, paranteze, i operatorii binari m i M.
m este operatorul de minim i M este operatorul de maxim. Astfel, rezultatul operaiei A m B
este valoarea minim dintre A i B, iar rezultatul operaiei A M B este valoarea maxim dintre
A i B. De exemplu, rezultatul 2m7 este 2, iar rezultatul 9M8 este 9. Cei doi operatori au
aceeai prioritate, ceea ce nseamn c dac nu sunt paranteze, vor fi evaluai, n ordine, de la
stnga la dreapta. De exemplu, rezultatul expresiei 1M22m13m789 este 13.
Dndu-se o expresie care conine numere naturale, paranteze i aceti doi operatori, aflai
rezultatul expresiei. Expresia va conine cel mult 100.000 de caractere, iar numerele din
cadrul ei sunt ntre 0 i 1.000.000.
Soluie: Expresia dat poate fi evaluat folosind o metod de complexitate liniar (O(N),
unde N este lungimea expresiei). Pentru simplificarea explicaiilor, vom considera c
ntreaga expresie este ncadrat ntr-o pereche de paranteze. Se parcurge expresia de la
stnga la dreapta i se va menine o stiv cu operatorii neevaluai nc, cu rezultate pariale i
cu paranteze deschise. Cnd se intlnete un operator, acesta se adaug n stiv. Cnd se
ntlnete un operand (numr) i n vrful stivei este un operator, se efectueaz operaia
respectiv (cci n stiv se va gsi i cel de-al doilea operand, pe nivelul de sub vrf): adic
se elimin din stiv operatorul i cel de-al doilea operand i se pune n vrful stivei rezultatul
operaiei; dac n vrful stivei nu se afl un operator, operandul se adaug n vrful stivei.
Cnd se ntlnete un operand i n stiv se afl o parantez deschis, operandul se pune n
vrful stivei. La ntlnirea unei paranteze nchise vom evalua toate operaiile pn la prima
parantez deschis din stiv. Apoi vom nlocui paranteza deschis cu rezultatul evalurii i,
dac pe nivelul urmtor din stiv se gasete un operator, atunci efectum operaia. La final,
n vrful stivei vom avea rezultatul expresiei.
Problema 13-3. Matrice (Bursele Agora, 2000-2001)
Se consider o matrice cu M linii i N coloane (1M,N100.000). Fiecare element al
matricii este 1. Dorim s obinem K (0KMN) elemente egale cu -1, folosind o secven de
mutri de tipul urmtor: putem schimba semnul tuturor elementelor de pe o linie sau de pe o
coloan.
Soluie: Se observ c pe orice linie i orice coloan, semnul elementelor se schimb maxim
o dat. De asemenea, nu conteaz care sunt liniile sau coloanele asupra cror aplicm
operaia menionat, astfel c, dac aplicm operaia asupra a P linii (Q coloane), putem
presupune c acestea sunt primele P linii (primele Q coloane). n plus, nu contaz nici
ordinea n care efectum operaiile. S presupunem c vrem s aplicm operaia asupra a P
linii. Dup aplicarea celor P operaii avem PN elemente egale cu -1 i (M-P)N elemente
egale cu 1. Dac aplicm apoi operaia asupra a Q coloane, vom obine PN-PQ+(M-P)Q.
Aadar, trebuie s gsim 2 valori ntregi P i Q (0PM i 0QN), astfel nct PN+MQ2PQ=K.
Vom ncerca toate valorile posibile ale lui P. Pentru fiecare valoare, vom determina n
timp O(1) dac exist o valoare potrivit a lui Q. Pentru un P fixat, avem Q=(K-PN)/(M-

141

2P). Dac (K-PN)/(M-2P) este un numr ntreg din intervalul [0,N], atunci am gsit o
valoare potrivit pentru Q.
Problema 13-4. Resturi 1 (Happy Coding 2005, infoarena)
Se dau N (1N30) numere (nu neaprat prime) distincte p(1), p(2), ..., p(N)
(2p(i)1.000, 1iN) i N resturi distincte r(1), r(2), ..., r(N) (0r(i)p(i)-1; 1iN). Aflai
cel mai mic numr nenegativ X cu proprietatea: X mod p(k) = r(k), pentru orice k ntre 1 i N.
Exemplu:
N=3
X=179.
p(1)=5 ; r(1)=4
p(2)=11 ; r(2)=3
p(3)=19 ; r(3)=8
Soluie: Aceast problem este cunoscut sub numele de Teorema Chinez a Restului. Vom
calcula numrul X cerut n mod incremental. La pasul i (1iN) vom avea calculat numrul
Q, reprezentnd cel mai mic numr care respect primele i relaii (deci Q mod p(j)=r(j)
pentru orice 1ji). La pasul 1, Q este egal chiar cu r(1). Avnd calculat numarul Q la pasul i,
va trebui s determinm numrul Q la pasul i+1 care respect primele i+1 relaii. Acest
numr Q este de forma Q+xM, cu x0, unde M este cel mai mic multiplu comun al
numerelor p(1), ..., p(i) (M este egal cu produsul p(1)...p(i), mprit la cel mai mare divizor
comun al numerelor p(1), ..., p(i); cmmdc(p(1), ..., p(i))=cmmdc(cmmdc(p(1), ..., p(i-1)), p(i)).
Ideea din spatele acestei formule este c la numrul Q trebuie adunat un multiplu al
numrului M, pentru ca numrul obinut Q s pstreze aceleai resturi la mpririle la
primele i numere prime date. Avem acum urmtoarea ecuaie: Q+xM=r(i+1) (mod p(i+1)).
Trecnd pe Q n partea dreapt, obinem o ecuaie de forma Ax=B (mod P), care se poate
rezolva direct, folosind algoritmul lui Euclid extins, pentru a calcula inversul multiplicativ al
lui A, relativ la numrul prim P. O metod mai simpl de rezolvare a ecuaiei (i utilizabil
chiar i atunci cnd nu exist inverse modulare la fiecare pas, deoarece numerele A i P din
forma generic a ecuaiei nu sunt prime ntre ele) se bazeaz pe a ncerca toate valorile
posibile pentru x, ntre 0 i p(i+1)-1, care funcioneaz deoarece valorile numerelor p(*) sunt
relativ mici.
Problema 13-5. Resturi 2 (Lotul Naional de Informatic, Romnia, 2004)
Se d un numr natural N (1N10) i numerele naturale p(1), p(2), , p(N), r(1), r(2),
, r(N), unde p(1), , p(N) sunt numere prime diferite dou cte dou i 0r(i)p(i)-1,
pentru orice i=1,...,N. Spunem c un numr X este liber de resturi, dac restul mpririi lui X
la p(i) este diferit de r(i), pentru orice i=1,...,N. Considerm irul sortat al numerelor naturale
libere de resturi. S se determine al K-lea (1K2.000.000.000) element al irului. Se
garanteaz c rezultatul va fi mai mic dect 1010.
Soluie: Vom cuta binar cel mai mic numr X cu proprietatea c exist exact K numere
libere de resturi n intervalul de numere naturale [0,...,X]. Numrul gsit este rspunsul
problemei. Mai trebuie doar s determinm un algoritm eficient pentru a numra cte numere
libere de resturi NLR(X) exist ntr-un interval [0,...,X]. Vom folosi principiul includerii i
excluderii. Vom nota prin NR(S,X)=numrul de numere din intervalul [0,...,X] care, mprite
la fiecare numr p(i) din submulimea S dau restul r(i). Vom nota prin NTR(h,X) suma
valorilor NR(S,X), cu |S|=h. Avem NLR(X)=(X+1)-NTR(1,X)+NTR(2,X)-NTR(3,X)+...+(-

142

1)iNTR(i,X)+...+ (-1)NNTR(N,X). Vom considera toate cele 2N submulimi S ale mulimii


{p(1), ..., p(N)} i vom calcula NR(S,X) pentru fiecare. Vom folosi rezolvarea de la problema
anterioar pentru a calcula cel mai mic numr Q care mprit la fiecare numr p(i) din S d
restul r(i). Dac Q>X, atunci NR(S,X)=0. Altfel, vom calcula M=cel mai mic multiplu comun
al numerelor p(i) din S i vom avea NR(S,X)=1+((X-Q) div M) (prin A div B am notat ctul
mpririi ntregi a lui A la B). Un caz particular apare cnd r(i)=0 pentru toate numerele p(i)
dintr-o submulime S. n acest caz, NR(S,X)=1+(X div M).
Algoritmul descris are complexitatea O(2NNlog(X)). Putem reduce complexitatea la
O(2Nlog(X)) dac nu recalculm de la nceput numrul Q corespunztor unei submulimi S.
Mai exact, s presupunem c am calculat numrul Q corespunztor unei submulimi
S=S\{p(i)} i numrul M=cel mai mic multiplu comun al elementelor din S, unde p(i) este
un element din S. Atunci Q se obine imediat din Q i M, considernd i perechea (p(i), r(i))
(avem ecuaia Q+yM=r(i) (mod p(i)); dup ce determinm cea mai mic valoare y care
verific ecuaia, avem Q= Q+yM).
Dac ne-ar interesa irul sortat al numerelor care dau restul r(i) la cel puin unul din
numerele p(i) i am dori s determinm al K-lea numr din acest ir, am folosi o procedur
asemntoare. Vom cuta binar cel mai mic numr X pentru care exist n intervalul [0,X] K
numere care mprite la cel puin un numr p(i) dau resul r(i). Avem nevoie i de aceast
dat de un algoritm eficient pentru a calcula NN(X)=numrul de numere din intervalul [0,X]
care mprite la cel puin un numr p(i) dau resul r(i). Observm uor c NN(X)=(X+1)NLR(X).
Problema 13-6. Transformri geometrice (SGU/.campion 2008)
Se dau N (1N50.000) puncte n spaiul 3D. Asupra fiecrui punct vrem s efectum
aceeai secven de operaii. Secvena const din M (1M50.000) operaii. Operaia i
(1iM) este de tipul op(i) (Translaie, Rotaie n jurul unei drepte date din spaiu i
Scalare) i se execut de x(i) ori consecutiv (1x(i)1.000.000.000). Determinai
coordonatele finale ale celor N puncte.
Soluie: Vom reprezenta fiecare operaie sub forma unei matrici de transformare 4x4. Fiecare
punct va fi considerat ca avnd 4 coordonate, cea de-a 4-a fiind mereu egal cu 1. Matricile
pentru translaie i scalare au forme standard. Matricea pentru o rotaie n jurul unei drepte
arbitrare se obine dup cum urmeaz:
(1) se translateaz dreapta pentru a trece prin originea sistemului;
(2) se rotete dreapta n jurul axei OZ pn ajunge n planul OXZ;
(3) se rotete dreapta n jurul axei OY, pn se suprapune cu OX;
(4) se realizeaz rotaia n jurul axei OX;
(5) se efectueaz transformrile (3), (2) i (1) (n aceast ordine) n sens invers.
O dat ce avem calculat matricea de transfromare T(i) pentru operaia i, o vom ridica la
puterea x(i). Pentru aceasta, vom folosi ridicare la putere logaritmic. Vom calcula T(i)x(i) n
O(log(x(i))) pai, obinnd o matrice T2(i). Se calculeaz apoi matricea produs
TM=T2(M)T2(M-1)...T2(1). Pentru a determina coordonatele finale ale fiecrui punct k
(1kN), nmulim matricea TM cu vectorul coloan al coordonatelor punctului k (a 4-a
coordonat este 1, dup cum am menionat deja). Vectorul coloan rezultat reprezint
coordonatele finale ale punctului k.
Complexitatea algoritmului este O(Mlog(max(x(*)))+M+N).

143

Capitolul 14. Backtracking


Problema 14-1. Regine2 (Happy Coding 2007, infoarena)
Se d o tabl de ah de dimensiune NxN. Pe aceast tabl, unele ptrele sunt libere, iar
altele sunt blocate. Determinai care este numrul maxim de regine care pot fi plasate pe
tabla de ah, astfel nct oricare dou regine s nu se atace una pe alta. O regin poate fi
plasat numai pe un ptrel liber. Dou regine se atac una pe alta dac sunt pe aceeai linie,
coloan sau diagonal i toate ptrelele dintre cele 2 regine (de pe linia, coloana sau
diagonala respectiv) sunt libere. Fie Q numrul maxim de regine care pot fi aezate pe tabl.
n plus, trebuie s determinai i numrul de posibiliti de a aeza cele Q regine pe tabl.
Exemplu:
Se pot amplasa maxim 4 regine, n 6 feluri.
N=4 (.=liber ; #=ocupat)
.#..
##..
.#.#
.#.#
Soluie: Pentru fiecare poziie (n ordinea liniilor i, pentru fiecare linie, n ordinea
coloanelor), se ncearc amplasarea sau neamplasarea unei regine n poziia respectiv, iar
apoi se marcheaz toate poziiile atacate de regina respectiv, pentru a nu se mai ncerca
amplasarea unei regine viitoare pe o poziie deja atacat. La ntoarcerea din backtracking,
poziiile marcate se demarcheaz (vom folosi, de fapt, un contor pentru fiecare poziie, n
care vom reine de cte regine deja amplasate este atacat poziia respectiv). Singura
optimizare necesar este c, atunci cnd marcm poziiile atacate de o regin nou-amplasat,
vom marca doar poziiile pe care vom ncerca s amplasm o regin n viitor (adic doar
nspre direciile: est, sud-est, sud, sud-vest, i nu n toate cele 8 directii).
Problema 14-2. Promo (Olimpiada Naional de Informatic, Romnia 2007)
Compania ONIx comercializeaz N produse. Pentru a crete vnzrile, compania a pus la
dispoziia clienilor M oferte promoionale. Fiecare ofert const din exact 2 produse diferite,
care sunt vndute mpreun la un pre mai sczut dect dac ar fi vndute separat (de
exemplu, suc i ap mineral). Produsele sunt identificate prin numere de la 1 la N, iar
ofertele promoionale prin numere de la 1 la M. Deoarece i-au schimbat de curnd aplicaia
software ce gestioneaz baza de date a companiei, angajaii nu s-au obinuit cu noul sistem i,
din neatenie, unul dintre acetia a ters toate informaiile despre produsele i ofertele
existente. Singurele informaii rmase sunt cele ale departamentului de statistic, care
folosete o baz de date proprie. Aceste informaii sunt reprezentate prin numrul M de
oferte i de toate cele K perechi de oferte ce au un produs n comun (n mod evident, oricare
2 oferte pot avea cel mult un produs n comun). Folosind informaiile departamentului de
statistic, determinai numrul de produse i cele 2 produse din cadrul fiecrei oferte.
Soluie: Problema cere determinarea unui graf pe baza grafului muchiilor acestuia (unde 2
muchii sunt adiacente dac au unul din cele 2 capete n comun). Vom mpri graful celor M
muchii n componente conexe. Pentru fiecare component conex vom ordona muchiile ce
fac parte din ea (noduri n graful muchiilor) astfel nct orice muchie n afara de prima s

144

aib cel puin o muchie adiacent cu aceasta undeva naintea ei (folosind o parcurgere DF, de
exemplu). Vom determina, pe rnd, nodurile ce reprezint capetele fiecrei muchii din
componenta conex curent. Primei muchii i atribuim 2 noduri noi. n continuare, fiecare
muchie are cel puin o alt muchie adiacent deja poziionat, astfel c unul din cele 2 capete
ale muchiei curente este unul din cele 2 capete ale vecinului ce se afl naintea acesteia n
ordonarea pe care am realizat-o. Vom ncerca fiecare din aceste 2 capete ca prim capt al
muchiei curente. Drept al doilea capt vom testa ori un nod nou, neatribuit niciunei alte
muchii, ori unul din cele 2 noduri ale unei alte muchii care are capetele deja fixate i care
este vecin cu muchia curent. O analiz atent ne va conduce la concluzia c exist o
singur modalitate de a atribui cele 2 capete muchiei curente n condiiile n care muchiile
dinaintea acesteia au capatele deja fixate. Exist doar 2 excepii posibile :
cnd am ajuns la a treia muchie i aceasta este adiacent att cu prima muchie, ct i
cu a doua: cele 3 muchii pot fi aezate n "stea" sau n "triunghi"
cnd aezm a 4-a muchie (sau a 5-a, dup caz) poate exista situaia n care
muchiile fixate anterior sunt muchiile unui subgraf bipartit 2x2: n acest caz, muchia
curent poate uni ori cele 2 muchii din partea stng a subgrafului bipartit, ori cele
dou noduri din partea dreapt
Cele 2 excepii nu pot aprea simultan. n concluzie, pentru fiecare component conex
vom avea de ncercat cel mult dou variante. Complexitatea algoritmului este O(M2), chiar
dac putem s l implementm folosind backtracking.

145

Bibliografie
[Andreica-COMM2008] M. I. Andreica, Optimal Scheduling of File Transfers with
Divisible Sizes on Multiple Disjoint Paths, Proceedings of the 7th IEEE Romania
International Conference "Communications", pp. 155-158, 2008.
[Andreica-CTRQ2008] M. I. Andreica, N. Tapus, Optimal Offline TCP Sender Buffer
Management Strategy, Proceedings of the 1st International Conference on Communication
Theory, Reliability, and Quality of Service, pp. 41-46, 2008.
[Andreica-ISPDC2008] M. I. Andreica, N. Tapus, Efficient Data Structures for Online
QoS-Constrained Data Transfer Scheduling, Proceedings of the 7th IEEE International
Symposium on Parallel and Distributed Computing (ISPDC), pp. 285-292, 2008.
[Andreica-MCBE2008] M. I. Andreica, E.-D. Tirsa, C. T. Andreica, R. Andreica, M. A.
Ungureanu, Optimal Geometric Partitions, Covers and K-Centers, Proceedings of the 9th
WSEAS International Conference on Mathematics and Computers in Business and
Economics (MCBE), pp. 173-178, 2008.
[Bender-RMQLCA2000] M. A. Bender, M. Farach-Colton, The LCA Problem Revisited,
Lecture Notes in Computer Science, vol. 1776, pp. 88-94, 2000.
[CLRS] T. H. Cormen, C. E. Leiserson, L. Rivest, C. Stein, Introduction to Algorithms,
3rd edition, MIT Press, 2009.
[Eppstein1992] D. Eppstein, M. Overmars, G. Rote, G. Woeginger, Finding Minimum
Area k-gons, Discrete & Computational Geometry, vol. 7, pp. 45-58, 1992.
[PA3DCG] S. Ferguson, Practical Algorithms for 3D Computer Graphics, CRC Press,
2001.
[campion] http://campion.edu.ro/
[Codechef] http://www.codechef.com/
[Codeforces] http://codeforces.com/
[infoarena] http://www.infoarena.ro/
[Quine] http://www.nyx.net/~gthompso/quine.htm
[SGU] http://acm.sgu.ru/
[TIMUS] http://acm.timus.ru/
[TopCoder] http://www.topcoder.com/
[UVA] http://uva.onlinejudge.org/

146