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.).
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.
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
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
12
13
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
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
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
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
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
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).
34
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
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
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
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
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
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
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
53
54
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
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.
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
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
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
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
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
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
78
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.
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
83
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
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
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
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:
94
95
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
97
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.
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
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
nct
C NK*M *H
planul
UX
1 i N
(de
UY
tip
1i M
3)
UZ
fie
gol,
numrul
cutat
va
fi
1i H
(1)
a +b+c
a =1 b =1 c =1
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
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
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
117
118
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
122
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
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
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
132
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
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
unde prin
(i )
xk
140
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
143
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