Sunteți pe pagina 1din 342

PROBLEME DE INFORMATIC€

date la olimpiade

în

2020
2019 2018 2017 2016 2015
2014 2013 2012 2011 2010

la clasa a 5-a

... draft (ciorn ) ...


*** Nobody is perfect ***

Ph.D. Adrian R bâea

9 decembrie 2020
Dedicaµie

I would like to dedicate this book ...

1
to myself ...
in a time when ...
I will not be able ...
2
to be.

That is because ...

3
When I Die Nobody Will Remember Me

1
I Dedicate This Book to Myself  By Carol Lynne
2
To be, or not to be ..., Hamlet, Act III, Scene I, William Shakespeare, 1564-1616
3
https://www.youtube.com/watch?v=eMtcDkSh7fU

ii
Prefaµ 
Stilul acestor c rµi este ... ca ³i cum a³ vorbi cu nepoµii mei (³i chiar cu mine însumi!) ... încercând
împreun  s  g sim o rezolvare cât mai bun  pentru o problem  dat  la olimpiad .

Ideea, de a scrie aceste culegeri de probleme date la olimpiadele de informatic , a ap rut acum
câµiva ani când am întrebat un student (care nu reu³ea s  rezolve ni³te probleme foarte simple):
Ce te faci dac  un elev, care ³tie c  e³ti student ³i c  studiezi ³i informatic , te roag , din când în
când, s -l ajuµi s  rezolve câte o problem  de informatic  dat  la gimnaziu la olimpiad , sau pur
³i simplu ca tem  de cas , ³i tu, aproape de ecare dat , nu îl poµi ajuta? Eu cred c  nu este prea
bine ³i poate c  ... te faci ... de râs! Pe vremea mea (!), când eram elev de gimnaziu, un student
era ca un fel de ... zeu! Cu trecerea anilor am înµeles c  nu este chiar a³a! “i înc  ceva: nu am
reu³it s  înµeleg de ce, atunci când cineva nu poate s  rezolve corect o problem  de informatic 
de clasa a 6-a, dat  la olimpiada de informatic  sau ca tem  de cas , folose³te aceast  scuz : eu
nu am f cut informatic  în liceu! ³i acest cineva este zeul sau zeiµa despre care vorbeam!.
4
Sunt convins c  este important s  studiem cu atenµie cât mai multe probleme rezolvate! Cred
cred c  sunt utile ³i primele versiuni în care sunt prezentate chiar ³i numai enunµurile ³i indicaµiile
"ociale" de rezolvare. Acestea se g sesc în multe locuri; aici încerc s  le pun pe toate la un loc !

Limbajul de programare se alege în funcµie de problema pe care o avem de rezolvat. Cu ni³te


ani în urm  alegerea era mai simpl : dac  era o problem  de calcul se alegea Fortran iar dac  era
o problem  de prelucrarea masiv  a datelor atunci se alegea Cobol. Acum alegerea este ceva mai
5 6
dicil ! :-) Vezi, de exemplu, IOI2020 ³i IOI2019 , IOI2015 .

Cred c , de cele mai multe ori, este foarte greu s  gândim "simplu" ³i s  nu "ne complic m"
atunci când caut m o rezolvare pentru o problem  dat  la olimpiad . Acesta este motivul pentru
care vom analiza cu foarte mare atenµie atât exemplele date în enunµurile problemelor cât ³i
"restricµiile" care apar acolo (ele sigur "ascund" ceva interesant din punct de vedere al algoritmului
7
de rezolvare!) .

Am început câteva c rµi (pentru clasele de liceu) cu mai mulµi ani în urm , pentru perioada
2000-2007 ([29] - [33]), cu anii în ordine cresc toare!). A urmat o pauz  de câµiva ani (destul de
mulµi!). Am observat c  acele cursuri s-au împr ³tiat un pic pe net ([48] - [56])! Încerc acum
s  ajung acolo unde am r mas ... plecând mereu din prezent ... pân  când nu va mai  posibil ...
a³a c , de aceast  dat , anii sunt în ordine ... descresc toare! :-)

Codurile surs  sunt cele ociale (publicate pe site-urile olimpiadelor) sau publicate pe alte
site-uri (dac  mi s-a p rut c  sunt utile ³i se poate înv µa câte ceva din ele).

Pentru liceu perioada acoperit  este de azi (pân  când va exista acest azi pentru mine!)
pân  în anul 2000 (aveam deja perioada 2000-2007!).

Pentru gimnaziu perioada acoperit  este de azi pân  în anul 2010 (nu am prea mult timp
disponibil ³i, oricum, calculatoarele folosite la olimpiade înainte de 2010 erau ceva mai 'slabe' ³i
8
... restricµiile de memorie, din enunµurile problemelor, par 'ciudate' acum!). “i indc  a venit
vorba despre calculatoare mai  slabe sau mai  puternice: laptopul meu¯t u este puµin mai  slab
decât cel mai puternic calculator din lume în 1985 dar ³i ... un pic mai  puternic decât cel mai

9
puternic calculator din lume în 1983. (armaµia este valabil  acum, în 2020).

4
Se poate observa din Coduri surs  c  orice problem  are numeroase soluµii, atât ca algoritmi de rezolvare
cât ³i ca stil de programare! Studiind aceste coduri ... avem ce înv µa ... de³i uneori pare c  'se trage cu tunul' ...
5
IOI2019 ³i IOI2020 au a permis utilizarea limbajelor de programare C++ ³i Java
6
IOI2015 a permis utilizarea limbajelor de programare C++, Java, Pascal, Python ³i Rubi (...)
7
8
Vezi cele 5 secunde pentru Timp maxim de executare/test din problema avârcolaci - ONI2014 clasa a 11-a
Când eram eu elev/student un calculator obi³nuit executa în jur de 1.000.000 de operaµii pe secund , acum
execut  1.000.000.000 de operaµii pe secund , iar mai târziu ... cine stie ce va mai ?!
9
https://en.wikipedia.org/wiki/List_of_fastest_computers

iii
În perioada 2017-2020 cele mai puternice calculatoare din lume au fost: în noiembrie 2017 în
China, în noiembrie 2019 în SUA ³i ... în iunie 2020 în Japonia (Fugaku: 415 petaops, adic 
15 10
415 ˜ 10 operaµii pe secund , adic  ... 415 milioane de ... miliarde de ... operaµii pe secund ).

O mic  observaµie: în 2017 a fost prima ediµie a olimpiadei EJOI11 în Bulgaria ³i ... tot în
12
Bulgaria a fost ³i prima ediµie a olimpiadei IOI în 1989.
Dar ... prima ediµie a olimpiadei IMO (International Mathematical Olympiad) a fost în
13
România în 1959. Tot în România s-au µinut ediµiile din anii 1960, 1969, 1978, 1999 ³i 2018.

Revenind la ...  culegerile noastre ... mai departe, probabil, va urma completarea unor
informaµii în Rezolv ri detaliate ... pentru unele probleme numai (tot din cauza lipsei timpului
necesar pentru toate!). Prioritate vor avea problemele de gimnaziu (nu pentru c  sunt mai 'u³oare'
ci pentru c  ... elevii de liceu se descurc  ³i singuri!). Totu³i, vor  prezentate ³i Rezolv ri
detaliate ale problemelor de liceu (pe care le-am considerat în mod subiectiv!) utile.

Îmi aduc aminte c  exista o interesant  vorb  de duh printre programatorii din generaµia mea:

nu se trage cu tunul într-o musc  . Sensul este: nu se scrie un cod complicat dac  se poate
scrie un cod simplu ³i clar! Asta încerc eu în Rezolv ri detaliate .

Vom încerca, împreun , ³i câteva probleme de ... IOI ... dar asta este o treab  ... nu prea
u³oar ! Cred totu³i c  este mai bine s  prezint numai enunµuri ale problemelor date la IOI în
ultimii câµiva ani! (asta a³a, ca s  vedem cum sunt problemele la acest nivel!). Cei care ajung
acolo sau vor s  ajung  acolo (la IOI) nu au nevoie de ajutorul meu! Se descurc  singuri! La
Indicaµii de rezolvare voi prezenta numai ... numele algoritmilor clasici folosiµi în rezolvare.

ALGORITMI utili la olimpiadele de informatic  , separat pentru gimnaziu ³i liceu, sper s 


e de folos, a³a cum cred c  sunt [1] - [28], [34] - [47], [57] - [82], ... ³i multe alte c rµi ³i site-uri!.

O alt  mic  observaµie: ce am strâns ³i am scris în aceste c rµi se adreseaz  celor interesaµi de
aceste teme! Nu cârcota³ilor! Sunt evidente sursele de pe net (³i locurile în care au fost folosite).
Nu sunt necesare preciz ri suplimentare!

“i un ultim gând: criticile ³i sfaturile sunt utile dac  au valoare! Dac  sunt numai a³a ...
cum critic  lumea la un meci de fotbal ... sau cum, pe banc  în parc, î³i d  cu p rerea despre
rezolvarea problemelor economice ale µ rii ... atunci ... !!!

"I'm only responsible for what I say,


14
not for what you understand."

Adrese interesante (rezultatele elevilor români):

https://stats.ioinformatics.org/halloffame/
https://stats.ioinformatics.org/tasks/
http://stats.ioinformatics.org/results/ROU

Adresele acestor cursuri:

http://adrianrabaea.scienceontheweb.net/
https://www.scribd.com/user/243528817/Adrian-Rabaea
https://drive.google.com/drive/folders/1hC5PZuslCdS95sl37SW46H-qy59GRDGZ

Adrese utile (programe ³colare):

http://www.ise.ro/wp-content/uploads/2017/01/Informatica-si-TIC.pdf
http://programe.ise.ro/Portals/1/Curriculum/Progr_Lic/TH/Informatica_teoretic_vocatio
nal_intensiv_clasa%20a%20IX-a.pdf
http://programe.ise.ro/Portals/1/Curriculum/Progr_Lic/TH/Informatica_teoretic_vocatio
nal_intensiv_clasa%20a%20X_a.pdf
http://programe.ise.ro/Portals/1/Curriculum/Progr_Lic/TH/Informatica_teoretic_vocatio
nal_intensiv_clasa%20a%20XI-a.pdf

Bistriµa, Ph.D. Adrian R bâea


9 decembrie 2020

10
https://www.top500.org/lists/top500/
11
https://ejoi.org/about/
12
https://stats.ioinformatics.org/olympiads/
13
https://en.wikipedia.org/wiki/International_Mathematical_Olympiad
14
https://www.etsy.com/listing/604809336/john-wayne-quotes-i-am-only-responsible
"Acknowledgements"
15
"I want to thank God most of all because without God I wouldn't be able to do any of this."

Bistriµa, 9 decembrie 2020

Adrian R.

15
I.d.k.: "I don't know who the author is."

v
Despre autor16
nume: R bâea Aurel-Adrian, 18.03.1953 - ...
adresa: Str. Valea Ghinzii nr. 21 B, Bistriµa, România
telefon: +40 728 18 03 53 +40 363 10 25 10
email: adrian1803@gmail.com

Lector universitar - Universitatea Tehnic  din Cluj Napoca - Centrul


Universitar Nord din Baia Mare, Facultatea de “tiinµe, Str. Victoriei,
nr. 76, Baia Mare, România, (pensionat: 01.10.2018)
http://www.stiinte.utcluj.ro/
Discipline predate (1992-2018):
Algoritmi ³i structuri de date, Algoritmi în teoria opµiunilor nanciare, Bazele matematice
ale calculatoarelor, Bazele tehnologiei informaµiei, Birotic , Capitole speciale de inteligenµ 
articial , Capitole speciale de teoria algoritmilor, Calcul paralel, Informatic  economic ,
Instruire asistat  de calculator, Limbaje de programare; Programare orientat  pe obiecte,
Programare procedural , Structuri de date,

Studii doctorale în informatic  economic  - Diplom  de doctor (1997-2002):


Institutµia: Academia de Studii Economice, Bucure³ti;
17
Titlul tezei: Algoritmi paraleli ³i aplicaµii pe ma³ini virtual paralele
18
Conduc tor ³tiinµic: Prof. dr. ing. Gheorghe Dodescu
Teme studiate: utilizarea algoritmilor paraleli în teoria opµiunilor nanciare

Studii de specializare în informatic  - Certicat anul V - 'master' (1978-1979):


Instituµia: Facultatea de matematic  ³i informatic , Bucure³ti;
Titlul tezei: Probleme la limit  pentru procese cu cre³teri independente ³i aplicaµii în teoria
a³tept rii
19
Conduc tor ³tiinµic: Prof. dr. Constantin Tudor

Studii universitare de licenµ  în informatic  - Diplom  de licenµ  (1974-1978):


Instituµia: Facultatea de matematic  ³i informatic , Bucure³ti;
Titlul tezei: Metode de comparaµie multipl  în analiza dispersional 
20
Conduc tor ³tiinµic: Prof. dr. Ion V duva

Locuri de munc : (1979-2018):


- (2018-2009) Universitatea Tehnic  din Cluj-Napoca, Centrul Universitar Nord din Baia-
Mare, Facultatea de “tiinµe, Departamentul de Matematic -Informatic 
- (2009-1992) Universitatea "Ovidius" din Constanµa, Facultatea de Matematic  ³i Informa-
tic , Departamentul de Informatic 
- (1992-1979) Centrul de Informatic  ³i organizare CINOR, Bucure³ti

https://scholar.google.com/citations?user=-sSE_1wAAAAJ&hl=en
https://www.scopus.com/authid/detail.uri?origin=resultslist&authorId=56122389200&zone=
http://www.facebook.com/adrian.rabaea

16
https://stiinte.utcluj.ro/files/cv/CV%20Rabaea_Adrian.pdf
17
http://opac.biblioteca.ase.ro/opac/bibliographic_view/149021
18
http://www.ionivan.ro/2015-PERSONALITATI/Dodescu.htm
19
https://sites.google.com/site/ciprianatudor/Home/professor-constantin-tudor
20
https://ro.wikipedia.org/wiki/Ion_V%C4%83duva

vi
Cuprins

Prefaµ  iii
Cuprins vii
Lista gurilor xiii
Lista tabelelor xv
Lista programelor xvi

I OJI - Olimpiada judeµean  de informatic  1


1 OJI 2020 2
1.1 cartonase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2 tai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

2 OJI 2019 18
2.1 Aur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.1.3 Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.2 Cartele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.2.3 Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

3 OJI 2018 41
3.1 Patrate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.2 forus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

4 OJI 2017 52
4.1 numere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.2 robot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

vii
4.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

5 OJI 2016 65
5.1 colier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
5.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
5.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
5.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.2 Palindrom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
5.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

6 OJI 2015 75
6.1 Cuart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
6.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
6.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
6.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
6.2 speciale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
6.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
6.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
6.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

7 OJI 2014 91
7.1 martisoare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
7.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
7.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
7.2 piramide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
7.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
7.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
7.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104

8 OJI 2013 105


8.1 bete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
8.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
8.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
8.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
8.2 chibrituri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
8.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
8.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
8.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

9 OJI 2012 113


9.1 alice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
9.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
9.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
9.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
9.2 porumb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
9.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
9.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
9.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124

10 OJI 2011 125


10.1 magic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
10.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
10.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
10.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
10.2 numerus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
10.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
10.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
10.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

11 OJI 2010 136


11.1 sir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
11.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
11.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
11.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
11.2 tren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
11.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
11.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
11.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

II ONI - Olimpiada naµional  de informatic  150


12 ONI 2020 151
12.1 *** . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
12.1.1 *Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
12.1.2 *Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
12.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
12.2 *** . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
12.2.1 *Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
12.2.2 *Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
12.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
12.3 *** . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
12.3.1 *Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
12.3.2 *Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
12.3.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

13 ONI 2019 154


13.1 Copii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
13.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
13.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
13.1.3 Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
13.2 Numere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
13.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
13.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
13.2.3 Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
13.3 Trio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
13.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
13.3.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
13.3.3 Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180

14 ONI 2018 183


14.1 desen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
14.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
14.1.2 *Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
14.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
14.2 mostenire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
14.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
14.2.2 *Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
14.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
14.3 pyk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
14.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
14.3.2 *Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
14.3.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
15 ONI 2017 189
15.1 prime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
15.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
15.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
15.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
15.2 robot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
15.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
15.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
15.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
15.3 roua . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
15.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
15.3.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
15.3.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210

16 ONI 2016 211


16.1 Norocos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
16.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
16.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
16.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
16.2 Oglinda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
16.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
16.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
16.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
16.3 Perechi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
16.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
16.3.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
16.3.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218

17 ONI 2015 219


17.1 iepuras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
17.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
17.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
17.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
17.2 inventie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
17.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
17.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
17.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
17.3 mesaj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
17.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
17.3.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
17.3.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252

18 ONI 2014 253


18.1 2048 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
18.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
18.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
18.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
18.2 babilon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
18.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
18.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
18.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
18.3 iepurasi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
18.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
18.3.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
18.3.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
19 ONI 2013 274
19.1 greieri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
19.1.1 *Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
19.1.2 *Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
19.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
19.2 Onigim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
19.2.1 *Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
19.2.2 *Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
19.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
19.3 Extraprime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
19.3.1 *Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
19.3.2 *Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
19.3.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277

20 ONI 2012 278


20.1 culegere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
20.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
20.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
20.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
20.2 culori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
20.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
20.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
20.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
20.3 stele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
20.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
20.3.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
20.3.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287

21 ONI 2011 288


21.1 Fagure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
21.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
21.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
21.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
21.2 Goe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
21.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
21.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
21.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
21.3 P pu³a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
21.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
21.3.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
21.3.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297

22 ONI 2010 298


22.1 cluburi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
22.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
22.1.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
22.1.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
22.2 domino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
22.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
22.2.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
22.2.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
22.3 max . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
22.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
22.3.2 Cod surs  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
22.3.3 *Rezolvare detaliat  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313

Anexa A Un pic de matematic ! 315


A.1 ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
A.1.1 Prezentare general  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
A.1.2 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Anexa B Un pic de programare! 316
B.1 ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
B.1.1 Prezentare general  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
B.1.2 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316

Glosar 317
Bibliograe 319
Lista autorilor 322
Lista gurilor
3.1 Patrate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.2 forus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

4.1 Numere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.2 Robot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

6.1 Cuart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
6.2 speciale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

7.1 marti³oare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7.2 Piramide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

8.1 chibrituri1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108


8.2 chibrituri2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

9.1 alice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113


9.2 AliceIR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
9.3 AliceIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
9.4 AliceIR3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
9.5 AliceIR4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
9.6 porumbi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
9.7 porumbIR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
9.8 P orumbIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

10.1 Numerus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131


10.2 Numerus - exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

11.1 sirir1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137


11.2 sirir2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
11.3 sirir3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
11.4 sirir4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
11.5 sirir5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

13.1 Numere cu 3 cifre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164


13.2 Numere cu 4 cifre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
13.3 Numere cu 5 cifre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165

14.1 desen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

17.1 mesaj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239

18.1 2048 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253


18.2 iepurasi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265

19.1 greieri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274

20.1 culegere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278


20.2 culegereIR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
20.3 culegereIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
20.4 culegereIR3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
20.5 culegereIR4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
20.6 culori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282

xiii
20.7 culoriIR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
20.8 culoriIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
20.9 culoriIR3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
20.10stele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
20.11steleIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286

21.1 fagure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288


21.2 Goe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
21.3 papusa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294

22.1 cluburiIR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299


22.2 cluburiIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
22.3 cluburiIR3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
22.4 domino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
22.5 dominoIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
22.6 maxIR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
22.7 maxIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
Lista tabelelor
13.1 copii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

xv
Lista programelor
1.1.1 cartonase.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.2 cartonase.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.3 cartonase1.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.4 cartonase2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.1 tai.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2.2 tai.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.3 tai1.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2.4 tai2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.2.5 tai3.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.2.6 tai4.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.1.1 aur_LC.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.1.2 aur_sol.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.1.3 aur_td.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.1.4 Aur - Etapa nr. 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.1.5 Aur - Etapa nr. 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.1.6 Aur - Etapa nr. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.1.7 Aur - Etapa nr. 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.1.8 Aur - Etapa nr. 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.1.9 Aur - Etapa nr. 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.2.1 cartele_LC.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.2.2 cartele_td.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.2.3 Cartele - Etapa nr. 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.2.4 Cartele - Etapa nr. 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.2.5 Cartele - Etapa nr. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.2.6 Cartele - Etapa nr. 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.1.1 patrate_AS.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.1.2 patrate_cpp_CM.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.1.3 patrate_FB.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.1.4 patrate_VG.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.2.1 forus_CM_100.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.2.2 forus_nvl_100.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.2.3 forus_VG_100.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.2.4 ocial_FB_100.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
4.1.1 numere_cardas.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.1.2 numere_cerchez.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.1.3 numere_jakab.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
4.1.4 numere_sandor.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
4.1.5 numere_vladescu.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
4.2.1 robot_cerchez.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.2.2 robot_cerchez_ok.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.2.3 robot_jakab.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5.1.1 colier_gina.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
5.1.2 colier_Marius.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
5.1.3 colier_Miana.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5.1.4 colier_sanda.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
5.2.1 palindrom_Marius.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.2.2 palindrom_Sanda.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
6.1.1 cuart_dl.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
6.1.2 cuart_dt.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

xvi
6.1.3 cuart_la.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
6.1.4 cuartAI.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
6.1.5 cuartAI_ecuatie.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.2.1 speciale_dc.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
6.2.2 speciale_n_dt.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
6.2.3 speciale_SJ.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
6.2.4 specialedl.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
7.1.1 mAna.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
7.1.2 mCarmen.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
7.1.3 mCristina.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
7.1.4 mMarilena.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
7.1.5 mRaluca.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
7.2.1 p_s_CM.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
7.2.2 p_v_CM.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
7.2.3 pAna.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
7.2.4 pCristina.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
7.2.5 pGina.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
7.2.6 pMarilena.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
7.2.7 pRaluca.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8.1.1 bete_OFICIAL.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
8.1.2 bete_vectori.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
8.2.1 chibrituri_OFICIAL.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
8.2.2 chibrituri_v.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
9.1.1 alice_CM2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
9.1.2 alice_CS.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
9.1.3 alice_SJ.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
9.2.1 p100_AS.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
9.2.2 p100_CL.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
9.2.3 p100_CM1.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
9.2.4 p100_CM2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
9.2.5 p100_CS.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
9.2.6 p100_DT.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
9.2.7 p100_JIT.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
10.1.1 CARACTER.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
10.1.2 magic_DM.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
10.1.3 MAGIC_S.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
10.1.4 magicAna.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
10.1.5 MAGICDT3.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
10.2.1 A1_Numer.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
10.2.2 D_NUMERU.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
10.2.3 S_Numeru.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
11.1.1 sir.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
11.1.2 sirana.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
11.1.3 SIRcris.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
11.1.4 SIRcris2.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
11.1.5 SIRcris2.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
11.1.6 SIRVECT.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
11.2.1 Ana.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
11.2.2 Carmen.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
11.2.3 Cris1.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
11.2.4 Cris2.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
11.2.5 Cris3.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
11.2.6 Dana.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
13.1.1 copii_cpp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
13.1.2 Copii - Etapa nr. 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
13.1.3 Copii - Etapa nr. 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
13.1.4 Copii - Etapa nr. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
13.2.1 numere_cpp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
13.2.2 Numere - Etapa nr. 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
13.2.3 Numere - Etapa nr. 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
13.2.4 Numere - Etapa nr. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
13.2.5 Numere - Etapa nr. 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
13.2.6 Numere - Etapa nr. 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
13.2.7 Numere - Etapa nr. 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
13.3.1 trio_cpp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
13.3.2 Trio - Etapa nr. 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
13.3.3 Trio - Etapa nr. 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
13.3.4 Trio - Etapa nr. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
13.3.5 Trio - Etapa nr. 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
15.1.1 prime_cp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
15.1.2 prime_em.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
15.1.3 prime_fara_ciur_sn.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
15.2.1 robot_adriana.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
15.2.2 robot_cp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
15.2.3 robot_ema.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
15.2.4 robot-JT.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
15.3.1 roua_cardas.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
15.3.2 roua_cp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
15.3.3 roua_jt.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
16.1.1 norocos.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
16.2.1 oglinda.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
16.3.1 perechi.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
17.1.1 iepuras_1.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
17.1.2 iepuras_2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
17.1.3 iepuras_3.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
17.1.4 iepuras_4.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
17.1.5 iepuras_5.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
17.1.6 iepuras_6.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
17.2.1 inventie_1.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
17.2.2 inventie_2cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
17.2.3 inventie_3.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
17.2.4 inventie_4_20p.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
17.2.5 inventie_5_45p.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
17.2.6 inventie_6.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
17.2.7 inventie_7.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
17.2.8 inventie_8_35p.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
17.3.1 mesaj_1.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
17.3.2 mesaj_2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
17.3.3 mesaj_3.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
17.3.4 mesaj_4.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
17.3.5 mesaj_5.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
17.3.6 mesaj_6.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
17.3.7 mesaj_7.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
18.1.1 2048.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
18.1.2 2048A.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
18.1.3 2048F.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
18.1.4 2048G.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
18.1.5 2048L.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
18.1.6 2048R.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
18.2.1 babilon.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
18.2.2 babilonA.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
18.2.3 babilonC.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
18.2.4 babilonL.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
18.3.1 iepurasi_AI.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
18.3.2 iepurasi_CS.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
18.3.3 iepurasi_gina.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
18.3.4 iepurasi_lucia.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
18.3.5 iepurasiM.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
20.1.1 culegere_2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
20.1.2 culegere_3.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
20.2.1 culori_1.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
20.2.2 culori_2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
20.3.1 stele_1.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
20.3.2 stele_2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
20.3.3 stele_3.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
21.1.1 fagure.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
21.2.1 GOE.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
21.3.1 papusa.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
22.1.1 cluburi_CS.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
22.1.2 cluburi_fara_vectori.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
22.1.3 cluburi_SG.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
22.2.1 domino_AS_1.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
22.2.2 domino_AS_2.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
22.2.3 domino_CM.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
22.2.4 domino_CS.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
22.2.5 domino_SG.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
22.3.1 MAX_CM.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
22.3.2 MAX_CS.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
22.3.3 MAX_SG.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
Partea I

OJI - Olimpiada judeµean  de


informatic 

1
Capitolul 1

OJI 2020

1.1 cartonase
Problema 1 - cartonase 100 de puncte
Ionel are N cartona³e. Fiecare cartona³ are înscrise dou  numere (un num r, s, în partea
stâng , ³i cel lalt num r, d, în partea dreapt ).
El a a³ezat cartona³ele într-un ³ir, lipite unul de cel lalt, astfel încât num rul din partea
dreapt  a primului cartona³ este lipit de num rul din partea stâng  a celui de-al doilea cartona³,
num rul din partea dreapt  a celui de al doilea cartona³ este lipit de num rul din partea stâng 
a celui de-al treilea cartona³ etc.
Spunem c  dou  cartona³e al turate se potrivesc dac  num rul din dreapta al primului
cartona³ este egal cu num rul din stânga al celui de al doilea cartona³.
Ionel observ  c  sunt perechi de cartona³e al turate care se potrivesc ³i chiar secvenµe de
mai multe cartona³e al turate, în care primul se potrive³te cu al doilea, al doilea se potrive³te
cu al treilea etc.

Cerinµe
Scrieµi un program care s  citeasc  num rul N de cartona³e, numerele înscrise pe ecare
cartona³ ³i determin :

1) Num rul de perechi de cartona³e care se potrivesc.

2) Num rul de cartona³e din cea mai lung  secvenµ  în care ecare dou  cartona³e al turate
se potrivesc.

3) Num rul de secvenµe cu num r maxim de cartona³e care se potrivesc.

Date de intrare
Fi³ierul de intrare cartonase.in conµine doar numere naturale nenule:
- pe prima linie se g se³te num rul C care poate avea doar valorile 1, 2 sau 3 ³i reprezint 
cerinµa care urmeaz  a  rezolvat . Pe a doua linie a ³ierului se g se³te num rul natural
N, cu semnicaµia din enunµ.

- pe ecare dintre urm toarele N linii se a , în acest  ordine, câte dou  numere naturale s
³i d, separate printr-un spaµiu, cu semnicaµia din enunµ pentru un cartona³. Perechile de
numere sunt date în ordinea în care cartona³ele corespunz toare lor apar în ³irul lui Ionel.

Date de ie³ire
Fi³ierul de ie³ire cartonase.out va conµine pe prima linie un num r natural reprezentând
r spunsul la cerinµa specicat .

Restricµii ³i preciz ri
a 1 & N & 500; 1 & s & 10 000; 1 & d & 10 000

a Pentru rezolvarea ec rei cerinµe se obµin câte 30 de puncte.

Exemple:

2
CAPITOLUL 1. OJI 2020 3

cartonase.in cartonase.out Explicaµii


1 2 Sunt 2 perechi de cartona³e al turate care se potrivesc:
5 - primul cu al doilea (2 10 ³i 10 5)
2 10 - al treilea cu al patrulea (10 2 ³i 2 10)
10 5
10 2
2 10
37 5
2 4 Primele patru cartonase formeaz  o secvenµ  în care ecare
5 dou  cartona³e al turate se potrivesc:
2 10 - primul cartona³ cu al doilea (2 10 ³i 10 5)
10 5 - al doilea cartona³ cu al treilea (10 5 ³i 5 2)
5 2 - al treilea cartona³ cu al patrulea (5 2 ³i 2 10)
2 10
37 5
3 2 Sunt maximum doua cartona³e al turate care se potrivesc.
6 În sier exist  dou  secvenµe de câte dou  cartona³e care se
2 10 potrivesc:
10 5 primele dou  cartona³e ³i al patrulea cu al cincilea cartona³
2 8
6 2
2 10
37 5

Timp maxim de executare/test: 0.5 secunde


Memorie: total 32 MB din care pentru stiv  32 MB
Dimensiune maxim  a sursei: 15 KB

1.1.1 Indicaµii de rezolvare


Descriere a unei soluµii posibile

Se citesc numerele de pe cartona³e, reµinând la un moment dat numerele de pe dou  cartona³e


al turate (citite consecutiv):

- în s1, d1 reµinem numerele de pe cartona³ul anterior citit

- în s2, d2 citim numerele de pe cartona³ul curent

Cerinµa 1

- utiliz m o variabil  de tip contor pentru a num ra perechile

- pentru ecare pereche de cartona³e al turate (s1, d1, s2, d2), veric m dac  se potrivesc
(dac  d1 s2)

Cerinµa 2

- utiliz m o variabil  de tip contor pentru a num ra cartona³ele

- dac  d1 s2 adun m 1 la contorul care num r  cartona³ele dintr-o secvenµ . Compar m


acest contor cu maximul(L) ³i reµinem în L valoarea mai mare.

- dac  d1 j s2, iniµializ m contorul cu 1.

Cerinµa 3

- utiliz m o variabil  de tip contor pentru a num ra cartona³ele

- dac  d1 s2 adun m 1 la contorul care num r  cartona³ele dintr-o secvenµ . Compar m


acest contor cu maximul(L) ³i reµinem în L valoarea mai mare.
CAPITOLUL 1. OJI 2020 4

- dac  d1 j s2, iniµializ m contorul cu 1.

- Num r m secvenµele de lungime egal  cu L într-un alt contor care se reseteaz  atunci când
se modic  L.

1.1.2 Cod surs 

Listing 1.1.1: cartonase.c

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4
5 int N, R, X, Y, K, P, i, Max, Lc, Nr, Nrs, x, y;
6
7 int main()
8 {
9 freopen("cartonase.in", "r",stdin);
10 freopen("cartonase.out","w",stdout);
11
12 scanf("%d\n",&P);
13 assert(P>0 && P<4);
14
15 scanf("%d\n",&N);
16 assert(N>0 && N<501);
17
18 Nr = Max = 0;
19 Lc = 1;
20 Nrs = 0;
21
22 scanf("%d %d", &X, &Y);
23 assert(X>0 && X<10001);
24 assert(Y>0 && Y<10001);
25
26 for(i = 2; i <= N ; i++)
27 {
28 scanf("%d %d", &x, &y);
29 assert(x>0 && x<10001);
30 assert(y>0 && y<10001);
31
32 if (Y == x)
33 {
34 Nr++;
35 Lc++;
36 }
37 else Lc = 1;
38
39 if(Lc > Max) {Max = Lc; Nrs = 1;}
40 else if (Lc == Max) Nrs++;
41
42 Y = y;
43 }
44
45 if(P==1) printf("%d\n", Nr);
46 else if (P==2 ) printf("%d\n", Max);
47 else printf("%d\n", Nrs);
48
49 return 0;
50 }

Listing 1.1.2: cartonase.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 int main()
6 {
7 ifstream in ("cartonase.in");
8 ofstream out ("cartonase.out");
9
10 int n,L=1,P=0,C,s1,d1,s2,d2,i,nr=0,i1,i2,cate;
CAPITOLUL 1. OJI 2020 5

11
12 in>>C>>n;
13
14 if(C==1)
15 {
16 in>>s1>>d1;
17 for(i=2;i<=n;++i)
18 {
19 in>>s2>>d2;
20 if(d1==s2)
21 P++;
22 s1=s2;
23 d1=d2;
24 }
25
26 out<<P<<endl;
27 }
28
29 if(C==2)
30 {
31 in>>s1>>d1;
32 nr=1;
33 i1=1;
34 i2=1;
35 for(i=2;i<=n;++i)
36 {
37 in>>s2>>d2;
38 if(d1==s2)
39 {
40 nr++;
41 if(nr>L){L=nr;}
42 }
43 else {nr=1;}
44
45 s1=s2;
46 d1=d2;
47 }
48
49 out<<L<<endl;
50 }
51
52 if(C==3)
53 {
54 in>>s1>>d1;
55 nr=1;
56 cate=1;
57 for(i=2;i<=n;++i)
58 {
59 in>>s2>>d2;
60 if(d1==s2)
61 {
62 nr++;
63 if(nr>L){L=nr; cate=1;}
64 else if(nr==L) cate++;
65 }
66 else {nr=1;}
67
68 s1=s2;
69 d1=d2;
70 }
71
72 out<<cate<<endl;
73 }
74
75 return 0;
76 }

Listing 1.1.3: cartonase1.cpp

1 /*
2 Implementare Dan Pracsiu
3 */
4 #include <fstream>
5
6 using namespace std;
CAPITOLUL 1. OJI 2020 6

7
8 int main()
9 {
10 int i, n;
11 int task; /// cerinta
12 int a1, b1; /// a1,b1= valorile de pe cartonasul precedent
13 int a2, b2; /// a2, b2 = valorile de pe cartonasul curent
14 int nrPerechi; /// pentru cerinta 1
15 int maxLen, L, cnt;
16
17 /// maxLen = lungimea maxima a unei secvente de cartonase
18 /// cnt = numarul secventelor maximale
19
20 ifstream fin("cartonase.in");
21 ofstream fout("cartonase.out");
22
23 fin >> task >> n;
24
25 if (task == 1) /// cerinta 1
26 {
27 nrPerechi = 0;
28 fin >> a1 >> b1;
29 for (i = 2; i <= n; i++)
30 {
31 fin >> a2 >> b2;
32 if (a2 == b1) nrPerechi++;
33 a1 = a2;
34 b1 = b2;
35 }
36 fout << nrPerechi << "\n";
37 }
38 else /// cerintele 2 si 3
39 {
40 fin >> a1 >> b1;
41 maxLen = 1;
42 cnt = 1;
43 L = 1;
44 for (i = 2; i <= n; i++)
45 {
46 fin >> a2 >> b2;
47 if (a2 == b1) L++;
48 else L = 1;
49
50 if (maxLen < L)
51 {
52 maxLen = L;
53 cnt = 1;
54 }
55 else if (maxLen == L) cnt++;
56
57 a1 = a2;
58 b1 = b2;
59 }
60
61 if (task == 2) fout << maxLen << "\n";
62 else fout << cnt << "\n";
63 }
64
65 fin.close();
66 fout.close();
67
68 return 0;
69 }

Listing 1.1.4: cartonase2.cpp

1 #include<fstream>
2
3 using namespace std;
4
5 int n,s,d,nr,c,S,D,lc,lmax;
6
7 ifstream f("cartonase.in");
8 ofstream g("cartonase.out");
9
CAPITOLUL 1. OJI 2020 7

10 int main()
11 {
12 f>>c>>n;
13 ///cerinta 1
14 if(c==1)
15 { f>>s>>d;
16 for(int i=2;i<=n;i++)
17 {
18 f>>S>>D;
19 if(d==S) nr++;
20 s=S;d=D;
21 }
22 g<<nr<<endl;
23 }
24 else
25 { ///cerintele 2 si 3
26 f>>s>>d;lmax=1;nr=1;lc=1;
27 for(int i=2;i<=n;i++)
28 {
29 f>>S>>D;
30 if(d==S) lc++;
31 else
32 lc=1;
33 if(lc>lmax)
34 {lmax=lc;nr=1;}
35 else
36 if(lc==lmax) nr++;
37 s=S;d=D;
38 }
39 ///afisare cerinta 2
40 if(c==2)
41 g<<lmax<<endl;
42 else g<<nr<<endl; ///afisare cerinta 3
43 }
44
45 f.close();
46 g.close();
47
48 return 0;
49 }

1.1.3 *Rezolvare detaliat 

1.2 tai
Problema 2 - tai 100 de puncte
Un num r este prim dac  are exact doi divizori naturali. Prin t ierea unui num r în p p rµi
înµelegem împ rµirea acestuia în p numere, ecare de cel puµin o cifr , astfel încât prin alipirea
numerelor obµinute de la stânga la dreapta obµinem num rul iniµial.
De exemplu, dac  împ rµim num rul 12045 în dou  p rµi avem patru variante de t iere
obµinându-se numerele: 1 ³i 2045; 12 ³i 045; 120 ³i 45; 1204 ³i 5. Dac  îl împ rµim în trei
p rµi avem ³ase variante de t iere obµinându-se numerele 1, 2 ³i 045; 1, 20 ³i 45; 1, 204 ³i 5; 12, 0
³i 45; 12, 04 ³i 5; 120, 4 ³i 5.

Cerinµe
Se consider  un ³ir format din N numere naturale.

1) Determinaµi cel mai mare num r prim din ³irul celor N numere.

2) Determinaµi cel mai mare num r prim dintre cele obµinute prin t ierea în dou  p rµi a
ec rui num r din ³irul celor N.
3) Determinaµi cel mai mare num r prim dintre cele obµinute prin t ierea în trei p rµi a ec rui
num r din ³irul celor N.

Date de intrare
CAPITOLUL 1. OJI 2020 8

Pe prima linie a ³ierului tai.in se g se³te num rul C care poate avea doar valorile 1, 2 sau 3
³i reprezint  cerinµa care urmeaz  a  rezolvat . Pe a doua linie se g se³te N, cu semnicaµia din
enunµ, iar pe a treia linie se g se³te ³irul celor N numere naturale desp rµite prin câte un spaµiu.

Date de ie³ire
În ³ierul de ie³ire tai.out pe prima linie se va a³a un num r natural reprezentând r spunsul
la cerinµa specicat .

Restricµii ³i preciz ri
a 1&N & 100
a 0& orice num r din ³ir & 1 000 000 000
a Pentru cerinµele 2 ³i 3 se garanteaz  c  pentru toate numerele din ³ir se poate efectua t ierea

a Pentru cerinµa 1 dac  ³irul nu conµine numere prime se va a³a 0

a Pentru cerinµele 2 ³i 3 dac  în urma t ierilor nu se obµine niciun num r prim, se va a³a 0

a Pentru rezolvarea ec rei cerinµe se obµin 30 de puncte.

Exemple:

tai.in tai.out Explicaµii


1 17 Numere prime din ³ir sunt 2, 13 ³i 17, iar maximul este 17
5
2 13 21 17 1
2 19 Din 23 se obµin dou  numere 2 ³i 3, din 196 se pot obµine nu-
3 merele 1 ³i 96 sau 19 ³i 6, iar din 27 se obµin numerele 2 ³i 7.
23 196 27 Cel mai mare num r prim care se poate obµine este 19.
3 71 Din num rul 1234 se pot obµine numerele: 1, 2, 34 sau 1, 23, 4
3 sau 12, 3, 4.
1234 17119 5678 Din num rul 17119 se pot obµine numerele: 1, 7 ³i 119 sau 1, 71
³i 19 sau 1, 711 ³i 9 sau 17, 1 ³i 19 sau 17, 11 ³i 9.
Din num rul 5678 se pot obµine numerele: 5, 6 ³i 78 sau 5, 67
³i 8 sau 56, 7 ³i 8.
Cel mai mare num r prim care se poate obµine este 71.

Timp maxim de executare/test: 0.5 secunde


Memorie: total 32 MB din care pentru stiv  32 MB
Dimensiune maxim  a sursei: 15 KB

1.2.1 Indicaµii de rezolvare


Descriere a unei soluµii posibile

Pentru ca un num r s  e prim folosim algoritm de num rare de divizori sau de determinare


a primului divizor propriu.
În funcµie de algoritmul folosit se obµin punctaje parµiale. Optim pentru problema dat  este
s  caut un divizor propriu ³i s  m  opresc la primul divizor propriu.

Folosim propietatea:

Dac  un num r x are cel puµin un divizor propriu, not m cu d cel mai mic divizor propriu al
s u. “tim c  d ³i x©d sunt divizorii lui x. Atunci d ˜ d $ x.
Cerinµa 1
- Calcul m maximul numerelor

Cerinµa 2
- Vom împ rµi numerele date în exact dou  numere ³i vom calcula maximul celor prime
CAPITOLUL 1. OJI 2020 9

Cerinµa 3
- Vom împ rµi numerele date în exact 3 numere ca în enunµ ³i vom calcula maximul celor
prime. Se pot împ rµi direct în 3 p rµi numerele cu dou  strucuturi repetitive ³i folosind puterile
lui 10 sau se poate împ rµi o dat  în 2 p rµi ³i o parte iar în 2 p rµi.

1.2.2 Cod surs 

Listing 1.2.1: tai.c

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4
5 #define inf 1000000000
6
7 int N, R, X, K, P, j, i, ok, cif, x, d, pz, p, a, b, c, Max,cm, nc, Nr, p1, k;
8
9 int main()
10 {
11 freopen("tai.in", "r",stdin);
12 freopen("tai.out","w",stdout);
13
14 scanf("%d\n",&P);
15 assert(P>0 && P<4);
16
17 scanf("%d\n",&N);
18 assert(N>0 && N<101);
19
20 if(P==1)
21 {
22 Max = 0;
23 for( i = 1; i <= N ; i++)
24 {
25 scanf("%d", &X);
26 assert(X>=0 && X<=inf);
27 if(X<2)
28 ok = 0;
29 else
30 ok = 1;
31
32 for(d = 2; d * d <= X && ok; d++)
33 if(X%d == 0)
34 ok = 0;
35
36 if(ok && X > Max)
37 Max = X;
38 }
39 printf("%d\n", Max);
40 }
41
42 if(P==2)
43 {
44 Max = 0;
45 for( i = 1; i <= N ; i++)
46 {
47 scanf("%d", &x);
48 assert(x>=0 && x<=inf);
49 pz = 1;
50 ok = 1;
51 while (x/pz > 0)
52 pz*=10;
53 p = pz/10;
54 while (p>9)
55 {
56 a = x % p;
57 b = x / p;
58
59 ok = 1;
60 for(d = 2; d * d <= a && ok; d++)
61 if(a % d == 0)
62 ok = 0;
63
CAPITOLUL 1. OJI 2020 10

64 if(a>1 && ok && a > Max)


65 Max = a;
66
67 ok = 1;
68 for(d = 2; d * d <= b && ok; d++)
69 if(b % d == 0)
70 ok = 0;
71
72 if(b>1 && ok && b > Max)
73 Max = b;
74 p/=10;
75 }
76 }
77 printf("%d\n", Max);
78 }
79
80 if(P==3)
81 {
82 Max = 0;
83 for( k = 1; k <= N ; k++)
84 {
85 scanf("%d", &X);
86 assert(X>=0 && X<=inf);
87 nc = 0;
88 pz = 1;
89 while (X/pz > 0)
90 {
91 pz*=10;
92 nc++;
93 }
94 pz = pz/10;
95 p1 = p = pz;
96 for(i = 1; i< nc -1; i++)
97 {
98 c = X / p1;
99 x = X % p1;
100 p = p1 / 10;
101
102 ok = 1;
103 for(d = 2; d * d <= c && ok; d++)
104 if(c % d == 0)
105 ok = 0;
106
107 if(c>1 && ok && c > Max)
108 Max = c;
109 while (p>9)
110 {
111 a = x % p;
112 b = x / p;
113
114 ok = 1;
115 for(d = 2; d * d <= a && ok; d++)
116 if(a % d == 0)
117 ok = 0;
118
119 if(a>1 && ok && a > Max)
120 Max = a;
121
122 ok = 1;
123 for(d = 2; d * d <= b && ok; d++)
124 if(b % d == 0)
125 ok = 0;
126
127 if(b>1 && ok && b > Max)
128 Max = b;
129 p/=10;
130 }
131 p1 /=10;
132 }
133 }
134
135 printf("%d\n", Max);
136 }
137
138 return 0;
139 }
CAPITOLUL 1. OJI 2020 11

Listing 1.2.2: tai.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("tai.in");
6 ofstream g("tai.out");
7
8 int N,i,x,nd,d,C,aux,y1,y2,y3,z,t,w,p,max1,x1,x2,q;
9
10 int main()
11 {
12 f>>C;
13 if (C==1)
14 {
15 f>>N;
16 max1=0;
17 for (i=1;i<=N;i++)
18 {
19 f>>x;
20 for (d=2;d*d<=x;d++)
21 if (x%d==0) break;
22 if (x>1&&d*d>x&& x>max1)
23 max1=x;
24 }
25 g<<max1<<"\n";
26 }
27 else
28 if (C==2)
29 {
30 max1=0;
31 f>>N;
32 for (i=1;i<=N;i++)
33 {
34 f>>x;
35 aux=x;
36 p=10;
37 while (aux>=p)
38 {
39 x1=aux%p;
40 x2=aux/p;
41 //g<<x<<"="<<x2<<" "<<x1<<endl;
42 p=p*10;
43 for (d=2;d*d<=x1;d++)
44 if (x1%d==0) break;
45 if (x1>1&&d*d>x1&& x1>max1)
46 max1=x1;
47 for (d=2;d*d<=x2;d++)
48 if (x2%d==0) break;
49 if (x2>1&&d*d>x2&& x2>max1)
50 max1=x2;
51 }
52 }
53 g<<max1<<"\n";
54 }
55 else
56 {
57 f>>N;
58 max1=0;
59 for (i=1;i<=N;i++)
60 {
61 f>>x;
62 aux=x;
63 p=10;
64 while (aux>p*10)
65 p=p*10;
66 for (t=10;t*10<=p;t=t*10)
67 for (q=10;q*t<=p;q=q*10)
68 {
69 y1=x%t;
70 z=x/t;
71 y2=z%q;
72 y3=z/q;
73 for (d=2;d*d<=y1;d++)
74 if (y1%d==0) break;
CAPITOLUL 1. OJI 2020 12

75 if (y1>1&&d*d>y1&& y1>max1)
76 max1=y1;
77 for (d=2;d*d<=y2;d++)
78 if (y2%d==0) break;
79 if (y2>1&&d*d>y2&& y2>max1)
80 max1=y2;
81 for (d=2;d*d<=y3;d++)
82 if (y3%d==0) break;
83 if (y3>1&&d*d>y3&& y3>max1)
84 max1=y3;
85 }
86 }
87 g<<max1<<"\n";
88 }
89
90 return 0;
91 }

Listing 1.2.3: tai1.cpp

1 #include <iostream>
2 #include <fstream>
3
4 using namespace std;
5
6 ifstream in("tai.in");
7 ofstream out("tai.out");
8
9 int prim(int x)
10 {
11 int ok,d;
12 ok=1;
13 if(x<=1)ok=0;
14 for(d=2;d*d<=x&&ok;++d)
15 if(x%d==0) ok=0;
16 return ok;
17 }
18
19 int main()
20 {
21 int N,i,x,ok,xmax=0,C,d,y,x1,x2,p,p2,x21,x22;
22
23 in>>C>>N;
24
25 if(C==1)
26 {
27 for(i=1;i<=N;++i)
28 {
29 in>>x;
30
31 if(prim(x))if(x>xmax)xmax=x;
32 }
33 out<<xmax;
34 }
35
36 if(C==2)
37 {
38 for(i=1;i<=N;++i)
39 {
40 in>>y;
41 p=10;
42 while(p<y)
43 {
44 x1=y/p;
45 x2=y%p;
46 if(prim(x1))
47 if(x1>xmax) xmax=x1;
48
49 if(prim(x2))if(x2>xmax)xmax=x2;
50 p=p*10;
51 }
52 }
53 out<<xmax;
54 }
55
CAPITOLUL 1. OJI 2020 13

56 if(C==3)
57 {
58 for(i=1;i<=N;++i)
59 {
60 in>>y;
61 p=100;
62 while(p<y)
63 {
64 x1=y/p;
65 x2=y%p;
66 if(prim(x1))
67 if(x1>xmax) xmax=x1;
68
69 p2=10;
70 while(p2<x2)
71 {
72 x21=x2/p2;
73 x22=x2%p2;
74 if(prim(x21))
75 if(x21>xmax) xmax=x21;
76 if(prim(x22))
77 if(x22>xmax) xmax=x22;
78 p2=p2*10;
79 }
80 p=p*10;
81 }
82 }
83
84 out<<xmax;
85 }
86
87 return 0;
88 }

Listing 1.2.4: tai2.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 int Prim(int n)
6 {
7 if (n <= 1) return 0;
8 if (n == 2) return 1;
9 if (n % 2 == 0) return 0;
10 for (int i = 3; i * i <= n; i += 2)
11 if (n % i == 0) return 0;
12 return 1;
13 }
14
15 int main()
16 {
17 int x, n, task, p, q, M = 0;
18
19 ifstream fin("tai.in");
20 ofstream fout("tai.out");
21
22 fin >> task >> n;
23
24 if (task == 1)
25 {
26 while (n--)
27 {
28 fin >> x;
29 if (Prim(x) && x > M) M = x;
30 }
31 }
32 else if (task == 2)
33 {
34 while (n--)
35 {
36 fin >> x;
37 p = 10;
38 while (x / p > 0)
39 {
CAPITOLUL 1. OJI 2020 14

40 if (Prim(x / p) && M < x / p) M = x / p;


41 if (Prim(x % p) && M < x % p) M = x % p;
42 p *= 10;
43 }
44 }
45 }
46 else /// task = 3
47 {
48 while (n--)
49 {
50 fin >> x;
51 for (p = 100; x / p > 0; p *= 10)
52 for (q = 10; q < p; q *= 10)
53 {
54 if (Prim(x / p) && M < x / p) M = x / p;
55 if (Prim(x % p / q) && M < x % p / q) M = x % p / q;
56 if (Prim(x % q) && M < x % q) M = x % q;
57 }
58 }
59 }
60
61 fout << M << "\n";
62 fin.close();
63 fout.close();
64 return 0;
65 }

Listing 1.2.5: tai3.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("tai.in");
6 ofstream g("tai.out");
7
8 int c,n,a;
9 bool eprim(int);
10 int nr_cifre(int);
11 int putere(int);
12
13 int main()
14 {
15 f>>c>>n;
16 if(c==1)
17 {
18 int sol=0;
19 for(int i=1; i<=n; i++)
20 {
21 f>>a;
22 if(eprim(a))
23 sol=max(sol,a);
24 }
25 g<<sol;
26 }
27
28 if(c==2)
29 {
30 int sol=0;
31 for(int i=1; i<=n; i++)
32 {
33 f>>a;
34 int cnt=nr_cifre(a)-1;
35 for(int j=1; j<=cnt; j++)
36 {
37 int aux=putere(j);
38 int b=a%aux,c=a/aux;
39 if(eprim(b))
40 sol=max(sol,b);
41 if(eprim(c))
42 sol=max(sol,c);
43 }
44 }
45 g<<sol;
46 }
CAPITOLUL 1. OJI 2020 15

47
48 if(c==3)
49 {
50 int sol=0;
51 for(int i=1; i<=n; i++)
52 {
53 f>>a;
54 int cnt=nr_cifre(a)-1;
55 for(int j=1; j<=cnt; j++)
56 {
57 int aux=putere(j);
58 int b=a%aux;
59 int c=a/aux;
60 if(b>=10)
61 {
62 int cntt=nr_cifre(b)-1;
63 for(int jj=1; jj<=cntt; jj++)
64 {
65 int auxx=putere(jj);
66 int bb=b%auxx;
67 int cc=b/auxx;
68 if(eprim(bb))
69 sol=max(sol,bb);
70 if(eprim(cc))
71 sol=max(sol,cc);
72 }
73 if(eprim(c)) sol=max(sol,c);
74 }
75 else
76 {
77 int cntt=nr_cifre(c)-1;
78 for(int jj=1; jj<=cntt; jj++)
79 {
80 int auxx=putere(jj);
81 int bb=c%auxx;
82 int cc=c/auxx;
83 if(eprim(bb))
84 sol=max(sol,bb);
85 if(eprim(cc))
86 sol=max(sol,cc);
87 }
88 if(eprim(b)) sol=max(sol,b);
89
90 }
91 }
92 }
93 g<<sol;
94 }
95
96 return 0;
97 }
98
99 bool eprim(int x)
100 {
101 if(x==1||x==0)
102 return false;
103 if(x==2)
104 return true;
105 if(x%2==0)
106 return false;
107 for(int i=3; i*i<=x; i+=2)
108 if(x%i==0)
109 return false;
110 return true;
111 }
112
113 int nr_cifre(int x)
114 {
115 int cnt=0;
116 while(x)
117 {
118 x/=10;
119 cnt++;
120 }
121 return cnt;
122 }
CAPITOLUL 1. OJI 2020 16

123
124 int putere(int x)
125 {
126 int p=1;
127 while(x)
128 {
129 p*=10;
130 x--;
131 }
132 return p;
133 }

Listing 1.2.6: tai4.cpp

1 #include<fstream>
2
3 using namespace std;
4
5 ifstream f("tai.in");
6 ofstream g("tai.out");
7
8 bool prim(long long x)
9 {
10 if(x==2) return 1;
11 if(x%2==0) return 0;
12 if(x<2) return 0;
13
14 for(int d=3; d*d<=x; d=d+2)
15 if(x%d==0) return 0;
16
17 return 1;
18 }
19
20 int nrc(long long x)
21 {
22 int N=0;
23 while(x)
24 {
25 N++;
26 x/=10;
27 }
28 return N;
29 }
30
31 long long c,x,i,n,max_p,n1,n2,n3,Nc;
32 long long pz[]={1,10,100,1000,10000,100000,1000000,10000000,
33 100000000,1000000000,10000000000};
34
35 int main()
36 {
37 f>>c;
38 if(c==1)
39 {
40 f>>n;
41 for(i=1;i<=n;i++)
42 {
43 f>>x;
44 if(prim(x))
45 max_p=max(x,max_p);
46 }
47 if(max_p==1) max_p=0;
48 g<<max_p<<endl;
49 }
50 else
51 if(c==2)
52 {
53 f>>n;
54 for(i=1;i<=n;i++)
55 {
56 f>>x;
57 Nc=nrc(x);
58 for(int j=1;j<Nc;j++)
59 {
60 n1=x/pz[j];
61 n2=x%pz[j];
CAPITOLUL 1. OJI 2020 17

62 if(prim(n1)) max_p=max(max_p,n1);
63 if(prim(n2)) max_p=max(max_p,n2);
64 }
65 }
66 g<<max_p<<endl;
67 }
68 else
69 {
70 f>>n;
71
72 for(i=1;i<=n;i++)
73 {
74 f>>x;
75 Nc=nrc(x);
76 long long X=x;
77
78 for(int j=1;j<Nc-1;j++)
79 {
80 n3=x%pz[j];
81 x=x/pz[j];
82 int Nrc=Nc-j;
83
84 for(int k=1;k<Nrc;k++)
85 {
86 n2=x%pz[k];
87 n1=x/pz[k];
88 // g<<n1<<" "<<n2<<" "<<n3<<endl;
89 if(prim(n1)) max_p=max(max_p,n1);
90 if(prim(n2)) max_p=max(max_p,n2);
91 if(prim(n3)) max_p=max(max_p,n3);
92 }
93 x=X;
94 }
95 }
96 g<<max_p<<endl;
97 }
98
99 f.close();
100 g.close();
101
102 return 0;
103 }

1.2.3 *Rezolvare detaliat 


Capitolul 2

OJI 2019

2.1 Aur
Problema 1 - Aur 90 de
puncte
Dup  ce au mers împreun  prin lume, P cal  ³i Tândal  au strâns o c ruµ  plin  de b nuµi
de aur, iar acum îi r stoarn  pe toµi în curtea casei ³i îi împart în N gr mezi. P cal  num r 
b nuµii din ecare gr mad  ³i îi dicteaz  lui Tândal  N numere naturale pe care acesta trebuie
s  le scrie în ordine pe o t bliµ . Dup  ore bune de munc , P cal  constat  c  Tândal  a scris pe
un singur rând, în ordine, de la stânga la dreapta, toate numerele dictate de el, dar lipite unul de
altul. Acum pe t bliµ  e doar un ³ir lung de cifre. Ce s  fac  P cal  acum?

Cerinµe
Cunoscând cele N numere naturale dictate de P cal , scrieµi un program care s  determine:
1. num rul cifrelor scrise pe t bliµ  de Tândal ;
2. ce-a de-a K-a cifr  de pe t bliµ , în ordine de la stânga la dreapta;
3. cel mai mare num r ce se poate forma cu exact P cifre al turate de pe t bliµ , considerate
în ordine de la stânga la dreapta.

Date de intrare
Fi³ierul aur.in conµine:
- pe prima linie un num r natural C care reprezint  num rul cerinµei ³i poate avea valorile 1,
2 sau 3.
- pe cea de-a doua linie un num r natural N dac  cerinµa este 1, sau dou  numere naturale N ³i
K (desp rµite printr-un spaµiu) dac  cerinµa este 2, sau dou  numere naturale N ³i P (desp rµite
printr-un spaµiu) dac  cerinµa este 3.
- pe cea de-a treia linie, N numere naturale desp rµite prin câte un spaµiu, ce reprezint , în
ordine, numerele pe care P cal  i le dicteaz  lui Tândal .

Date de ie³ire
Fi³ierul aur.out va conµine pe prima linie un singur num r natural ce reprezint  rezultatul de-
terminat conform ec rei cerinµe.

Restricµii ³i preciz ri
a 1&N & 100000 ³i 1 & K & 900000; Se garanteaz  c  exist  cel puµin K cifre scrise pe t bliµ .
a 1&P & 18; Se garanteaz  ca exist  cel puµin P cifre scrise pe t bliµ .
a toate numere dictate de P cal  sunt nenule ³i au cel mult 9 cifre ecare;
a Pentru rezolvarea corect  a primei cerinµe se acord  20 de puncte, pentru rezolvarea corect 
a celei de-a doua cerinµe se acord  30 de puncte, iar pentru rezolvarea corect  a celei de-a treia
cerinµe se acord  40 de puncte.

18
CAPITOLUL 2. OJI 2019 19

Exemple
aur.in aur.out Explicaµii
1 12 Se rezolv  cerinµa 1.
7 Tândal  a scris pe t bliµ : 259134592799.
25 9 13 459 2 79 9 Num rul cifrelor scrise de Tândal  este 12.
2 7 Se rezolv  cerinµa 2. N are valoarea 7 ³i K are
7 10 7
valoarea 10. Pe t bliµ  este scris: 259134592 99
25 9 13 459 2 79 9 Cea de-a zecea cifr  este 7.
3 9279 Se rezolv  cerinµa 3. N are valoarea 7 ³i P are valoarea 4.
7 4 Tândal  a scris pe t bliµ : 2591345 92799.
25 9 13 459 2 79 9 Cel mai mare num r format din patru cifre este 9279.

Timp maxim de executare/test: 0.5 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 15 KB
Sursa: aur.cpp, aur.c sau aur.pas va  salvat  în folderul care are drept nume ID-ul t u.

2.1.1 Indicaµii de rezolvare


Descriere a unei soluµii posibile

Cerinµa1 :
- pentru ecare num r citit din ³ier identic m cifrele sale;
- utiliz m o variabil  de tip contor pentru num rarea cifrelor tuturor numerelor.

Cerinµa 2:
- pentru ecare num r citit din ³ier determin m cifrele sale în ordine, de la stânga la dreapta;
- num r m cifrele pân  în momentul în care variabila care le contorizeaz  ajunge la valoare K.

Cerinµa 3
- consider m toate secvenµele posibile formate din P cifre al turate;
- cu cifrele ec rei secvenµe construim un num r natural;
- calcul m cea mai mare valoare a unui num r natural construit anterior.

Tipuri de date folosite - tipul întreg ³i/sau tipul caracter

Gradul de dicultate
Cerinµa 1 - 2
Cerinta 2 - 3
Cerinta 3 - 4

2.1.2 Cod surs 

Listing 2.1.1: aur_LC.cpp

1 #include <iostream>
2 #include <fstream>
3 #include <cmath>
4
5 using namespace std;
6
7 ifstream fin("aur.in");
8 ofstream fout("aur.out");
9
10 int main()
11 {
12 int p;
13 fin>>p;
14
15 if(p==1)
16 {
17 int n,nr=0;
18 char c;
19 fin>>n;
20 while(fin>>c)
21 if(c!=’ ’) nr++;
CAPITOLUL 2. OJI 2019 20

22 fout<<nr;
23 }
24
25 if(p==2)
26 {
27 int n,k,nr=0;
28 char c,a;
29 fin>>n>>k;
30
31 while(fin>>c)
32 {
33 if(c!=’ ’) nr++;
34 if(nr==k) a=c;
35 }
36
37 fout<<a;
38 }
39
40 if(p==3)
41 {
42 unsigned long long n, k, maxx=0, v, y=0, nr=0;
43 char c;
44
45 fin>>n>>k;
46
47 unsigned long long f1=1;
48 for(int i=1;i<k;i++)
49 f1=f1*10;
50
51 while(fin>>c)
52 {
53 if(c!=’ ’)
54 {
55 v=(int)c-48;
56 y=y*10+v;
57 }
58
59 nr++;
60 if(nr==k)
61 {
62 if(y>maxx) maxx=y;
63 y=y%f1;
64 nr--;
65 }
66 }
67
68 fout<<maxx;
69 }
70
71 return 0;
72 }

Listing 2.1.2: aur_sol.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("aur.in");
6 ofstream g("aur.out");
7
8 long long nr_max,p=1,nou,nr;
9
10 int main()
11 {
12 char c,cifraK;
13 int nr_cif=0,cerinta,K,N,i,P;
14
15 f>>cerinta>>N;
16
17 if (cerinta==2) f>>K;
18 else
19 if (cerinta==3) f>>P;
20
21 if (cerinta==1)
CAPITOLUL 2. OJI 2019 21

22 {
23 while(f>>c)
24 nr_cif++;
25 g<<nr_cif<<’\n’;
26 }
27 else
28 if (cerinta==2)
29 while(f>>c)
30 {
31 nr_cif++;
32 if (nr_cif==K)
33 {
34 g<<c<<’\n’;
35 break;
36 }
37 }
38 else
39 {
40 for(i=1; i<P; i++)
41 {
42 f>>c;
43 nr=nr*10+(c-’0’);
44 p=p*10;
45 }
46
47 nr_max=nr;
48
49 while(f>>c)
50 {
51 nou=(nr%p)*10+(c-’0’);
52 if(nou>nr_max) nr_max=nou;
53 nr=nou;
54 }
55
56 g<<nr_max<<’\n’;
57 }
58 return 0;
59 }

Listing 2.1.3: aur_td.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("aur.in");
6 ofstream g("aur.out");
7
8 long long c, i, N, K, P, cif, nr, y, p, x, aux, cate, q, t, maxf;
9
10 int main()
11 {
12 f>>c;
13
14 if(c==1)
15 {
16 f>>N;
17 cate=0;
18 for(i=1; i<=N; i++)
19 {
20 f>>x;
21 while(x)
22 {
23 cate++;
24 x /= 10;
25 }
26 }
27 g<<cate<<" \n";
28 }
29 else
30 if(c==2)
31 {
32 f>>N>>K;
33 nr=0;
34 for (i=1; i<=N; i++)
CAPITOLUL 2. OJI 2019 22

35 {
36 f>>x;
37 y=x;
38 p=1;
39
40 while (p<=y)
41 p *= 10;
42
43 p /= 10;
44 y=x;
45
46 while(p>=1)
47 {
48 nr++;
49 cif = y / p %10;
50 p /= 10;
51 if(nr == K)
52 {
53 g<<cif<<"\n";
54 return 0;
55 }
56 }
57 }
58 }
59 else
60 {
61 f>>N>>P;
62 q=1;
63
64 for(i=1; i<P; i++)
65 q=q*10;
66
67 nr=0;
68 t=0;
69 maxf=0;
70
71 for(i=1; i<=N; i++)
72 {
73 f>>x;
74 y=x;
75 p=1;
76
77 while(p<=y)
78 p *= 10;
79
80 p /= 10;
81 y=x;
82 while(p>=1)
83 {
84 nr++;
85 cif = y / p %10;
86 t = t % q;
87 t= t*10 + cif;
88 p /= 10;
89 if(nr == K)
90 {
91 maxf=t;
92 }
93 else
94 if(nr>K)
95 {
96 if(t > maxf) maxf=t;
97 }
98 }
99 }
100 g<<maxf;
101 }
102 return 0;
103 }

2.1.3 Rezolvare detaliat 

Etapa nr. 0:
CAPITOLUL 2. OJI 2019 23

Listing 2.1.4: Aur - Etapa nr. 0

1 #include<iostream>
2 #include<fstream>
3
4 using namespace std;
5
6 ifstream fin("aur.in");
7 ofstream fout("aur.out");
8
9 int C, N, K, P;
10 int nr; // cate un numar pe randul 3 (din cele N numere)
11 int nc; // numarul cifrelor scrise pe tablita
12 int ck; // cifra K scrisa pe tablita
13 int nrmaxp; // nr max format cu P cifre
14
15 void rezolva1()
16 {
17
18 }
19
20 void rezolva2()
21 {
22
23 }
24
25 void rezolva3()
26 {
27
28 }
29
30 int main()
31 {
32 fin>>C;
33 cout<<"C = "<<C<<"\n";
34
35 if(C==1) {rezolva1(); return 0;}
36 if(C==2) {rezolva2(); return 0;}
37 if(C==3) {rezolva3(); return 0;}
38
39 return 0;
40 }

Etapa nr. 1:

Listing 2.1.5: Aur - Etapa nr. 1

1 #include<iostream>
2 #include<fstream>
3
4 using namespace std;
5
6 ifstream fin("aur.in");
7 ofstream fout("aur.out");
8
9 int C, N, K, P;
10 int nr; // cate un numar pe randul 3 (din cele N numere)
11 int nc; // numarul cifrelor scrise pe tablita
12 int ck; // cifra K scrisa pe tablita
13 int nrmaxp; // nr max format cu P cifre
14
15 void rezolva1()
16 {
17 fin>>N;
18 cout<<"N = "<<N<<"\n";
19
20 nc=0;
21
22 unsigned char ch;
23 while(fin>>ch)
24 {
25 if(ch>=’0’ && ch<=’9’) nc++;
26 }
27 cout<<"nc = "<<nc<<"\n";
28 fout<<nc<<’\n’;
CAPITOLUL 2. OJI 2019 24

29 fout.close();
30 }
31
32 void rezolva2()
33 {
34
35 }
36
37 void rezolva3()
38 {
39
40 }
41
42 int main()
43 {
44 fin>>C;
45 cout<<"C = "<<C<<"\n";
46
47 if(C==1) {rezolva1(); return 0;}
48 if(C==2) {rezolva2(); return 0;}
49 if(C==3) {rezolva3(); return 0;}
50
51 return 0;
52 }

Etapa nr. 2:

Listing 2.1.6: Aur - Etapa nr. 2

1 #include<iostream>
2 #include<fstream>
3
4 using namespace std;
5
6 ifstream fin("aur.in");
7 ofstream fout("aur.out");
8
9 int C, N, K, P;
10 int nr; // cate un numar pe randul 3 (din cele N numere)
11 int nc; // numarul cifrelor scrise pe tablita
12 int ck; // cifra K scrisa pe tablita
13 int nrmaxp; // nr max format cu P cifre
14
15 void rezolva1()
16 {
17 fin>>N;
18 cout<<"N = "<<N<<"\n";
19
20 nc=0;
21
22 unsigned char ch;
23 while(fin>>ch)
24 {
25 if(ch>=’0’ && ch<=’9’) nc++;
26 }
27 cout<<"nc = "<<nc<<"\n";
28 fout<<nc<<’\n’;
29 fout.close();
30 }
31
32 void rezolva2()
33 {
34 fin>>N;
35 cout<<"N = "<<N<<"\n";
36
37 fin>>K;
38 cout<<"K = "<<K<<"\n";
39
40 nc=0;
41
42 unsigned char ch;
43 while(nc < K)
44 {
45 fin>>ch;
46 if(ch>=’0’ && ch<=’9’) nc++;
CAPITOLUL 2. OJI 2019 25

47 }
48 cout<<"ch = "<<ch<<"\n";
49 fout<<ch<<’\n’;
50 fout.close();
51 }
52
53 void rezolva3()
54 {
55
56 }
57
58 int main()
59 {
60 fin>>C;
61 cout<<"C = "<<C<<"\n";
62
63 if(C==1) {rezolva1(); return 0;}
64 if(C==2) {rezolva2(); return 0;}
65 if(C==3) {rezolva3(); return 0;}
66
67 return 0;
68 }

Etapa nr. 3:

Listing 2.1.7: Aur - Etapa nr. 3

1 #include<iostream>
2 #include<fstream>
3
4 using namespace std;
5
6 ifstream fin("aur.in");
7 ofstream fout("aur.out");
8
9 int C, N, K, P;
10 int nr; // cate un numar pe randul 3 (din cele N numere)
11 int nc; // numarul cifrelor scrise pe tablita
12 int ck; // cifra K scrisa pe tablita
13 long long nrmaxp; // nr max format cu P cifre
14
15 void rezolva1()
16 {
17 fin>>N;
18 cout<<"N = "<<N<<"\n";
19
20 nc=0;
21
22 unsigned char ch;
23 while(fin>>ch)
24 {
25 if(ch>=’0’ && ch<=’9’) nc++;
26 }
27 cout<<"nc = "<<nc<<"\n";
28 fout<<nc<<’\n’;
29 fout.close();
30 }
31
32 void rezolva2()
33 {
34 fin>>N;
35 cout<<"N = "<<N<<"\n";
36
37 fin>>K;
38 cout<<"K = "<<K<<"\n";
39
40 nc=0;
41
42 unsigned char ch;
43 while(nc < K)
44 {
45 fin>>ch;
46 if(ch>=’0’ && ch<=’9’) nc++;
47 }
48 cout<<"ch = "<<ch<<"\n";
CAPITOLUL 2. OJI 2019 26

49 fout<<ch<<’\n’;
50 fout.close();
51 }
52
53 void rezolva3()
54 {
55 fin>>N;
56 cout<<"N = "<<N<<"\n";
57
58 fin>>P;
59 cout<<"P = "<<P<<"\n";
60
61 // nr1 = c_1 c_2 ... c_p ---> nrnou = c_2 c_3 ...c_p c_{p+1}
62 // c_2 c_3 ... c_p = restul impartirii lui nr1 la prod10p_1
63 // = 10*10*...*10 de p-1 ori
64
65 long long prod10p_1=1;
66 for(int i=1; i<=P-1; i++) prod10p_1=prod10p_1*10;
67 cout<<"prod10p_1 = "<<prod10p_1<<"\n";
68
69 long long nr1=0LL;
70 unsigned char ch;
71 for(int i=1; i<=P; i++)
72 {
73 fin>>ch;
74 nr1=nr1*10+(ch-’0’);
75 }
76 cout<<"nr1 = "<<nr1<<"\n";
77
78 nrmaxp=nr1;
79 while(fin>>ch)
80 {
81 if(ch>=’0’ && ch<=’9’)
82 {
83 nr1=(nr1 % prod10p_1)*10 + (ch-’0’);
84 if(nr1 > nrmaxp) nrmaxp=nr1;
85 }
86 }
87 cout<<"nrmaxp = "<<nrmaxp<<"\n";
88 fout<<nrmaxp<<’\n’;
89 fout.close();
90 }
91
92 int main()
93 {
94 fin>>C;
95 cout<<"C = "<<C<<"\n";
96
97 if(C==1) {rezolva1(); return 0;}
98 if(C==2) {rezolva2(); return 0;}
99 if(C==3) {rezolva3(); return 0;}
100
101 return 0;
102 }

Etapa nr. 4 FINALA1 comentat mesajele ajutatoare:

Listing 2.1.8: Aur - Etapa nr. 4

1 #include<iostream>
2 #include<fstream>
3
4 using namespace std;
5
6 ifstream fin("aur.in");
7 ofstream fout("aur.out");
8
9 int C, N, K, P;
10 int nr; // cate un numar pe randul 3 (din cele N numere)
11 int nc; // numarul cifrelor scrise pe tablita
12 int ck; // cifra K scrisa pe tablita
13 long long nrmaxp; // nr max format cu P cifre
14
15 void rezolva1()
16 {
CAPITOLUL 2. OJI 2019 27

17 fin>>N;
18 //cout<<"N = "<<N<<"\n";
19
20 nc=0;
21
22 unsigned char ch;
23 while(fin>>ch)
24 {
25 if(ch>=’0’ && ch<=’9’) nc++;
26 }
27 //cout<<"nc = "<<nc<<"\n";
28 fout<<nc<<’\n’;
29 fout.close();
30 }
31
32 void rezolva2()
33 {
34 fin>>N;
35 //cout<<"N = "<<N<<"\n";
36
37 fin>>K;
38 //cout<<"K = "<<K<<"\n";
39
40 nc=0;
41
42 unsigned char ch;
43 while(nc < K)
44 {
45 fin>>ch;
46 if(ch>=’0’ && ch<=’9’) nc++;
47 }
48 //cout<<"ch = "<<ch<<"\n";
49 fout<<ch<<’\n’;
50 fout.close();
51 }
52
53 void rezolva3()
54 {
55 fin>>N;
56 //cout<<"N = "<<N<<"\n";
57
58 fin>>P;
59 //cout<<"P = "<<P<<"\n";
60
61 // nr1 = c_1 c_2 ... c_p ---> nrnou = c_2 c_3 ...c_p c_{p+1}
62 // c_2 c_3 ... c_p = restul impartirii lui nr1 la prod10p_1
63 // = 10*10*...*10 de p-1 ori
64
65 long long prod10p_1=1;
66 for(int i=1; i<=P-1; i++) prod10p_1=prod10p_1*10;
67 //cout<<"prod10p_1 = "<<prod10p_1<<"\n";
68
69 long long nr1=0LL;
70 unsigned char ch;
71 for(int i=1; i<=P; i++)
72 {
73 fin>>ch;
74 nr1=nr1*10+(ch-’0’);
75 }
76 //cout<<"nr1 = "<<nr1<<"\n";
77
78 nrmaxp=nr1;
79 while(fin>>ch)
80 {
81 if(ch>=’0’ && ch<=’9’)
82 {
83 nr1=(nr1 % prod10p_1)*10 + (ch-’0’);
84 if(nr1 > nrmaxp) nrmaxp=nr1;
85 }
86 }
87 //cout<<"nrmaxp = "<<nrmaxp<<"\n";
88 fout<<nrmaxp<<’\n’;
89 fout.close();
90 }
91
92 int main()
CAPITOLUL 2. OJI 2019 28

93 {
94 fin>>C;
95 //cout<<"C = "<<C<<"\n";
96
97 if(C==1) {rezolva1(); return 0;}
98 if(C==2) {rezolva2(); return 0;}
99 if(C==3) {rezolva3(); return 0;}
100
101 return 0;
102 }

Etapa nr. 5 FINALA2 sters mesajele ajutatoare:

Listing 2.1.9: Aur - Etapa nr. 5

1 #include<iostream>
2 #include<fstream>
3
4 using namespace std;
5
6 ifstream fin("aur.in");
7 ofstream fout("aur.out");
8
9 int C, N, K, P;
10 int nr; // cate un numar pe randul 3 (din cele N numere)
11 int nc; // numarul cifrelor scrise pe tablita
12 int ck; // cifra K scrisa pe tablita
13 long long nrmaxp; // nr max format cu P cifre
14
15 void rezolva1()
16 {
17 fin>>N;
18 nc=0;
19
20 unsigned char ch;
21 while(fin>>ch)
22 {
23 if(ch>=’0’ && ch<=’9’) nc++;
24 }
25 fout<<nc<<’\n’;
26 fout.close();
27 }
28
29 void rezolva2()
30 {
31 fin>>N;
32 fin>>K;
33 nc=0;
34
35 unsigned char ch;
36 while(nc < K)
37 {
38 fin>>ch;
39 if(ch>=’0’ && ch<=’9’) nc++;
40 }
41 fout<<ch<<’\n’;
42 fout.close();
43 }
44
45 void rezolva3()
46 {
47 fin>>N;
48 fin>>P;
49
50 // nr1 = c_1 c_2 ... c_p ---> nrnou = c_2 c_3 ...c_p c_{p+1}
51 // c_2 c_3 ... c_p = restul impartirii lui nr1
52 // la prod10p_1 = 10*10*...*10 de p-1 ori
53
54 long long prod10p_1=1;
55 for(int i=1; i<=P-1; i++) prod10p_1=prod10p_1*10;
56
57 long long nr1=0LL;
58 unsigned char ch;
59 for(int i=1; i<=P; i++)
60 {
CAPITOLUL 2. OJI 2019 29

61 fin>>ch;
62 nr1=nr1*10+(ch-’0’);
63 }
64
65 nrmaxp=nr1;
66 while(fin>>ch)
67 {
68 if(ch>=’0’ && ch<=’9’)
69 {
70 nr1=(nr1 % prod10p_1)*10 + (ch-’0’);
71 if(nr1 > nrmaxp) nrmaxp=nr1;
72 }
73 }
74 fout<<nrmaxp<<’\n’;
75 fout.close();
76 }
77
78 int main()
79 {
80 fin>>C;
81 if(C==1) {rezolva1(); return 0;}
82 if(C==2) {rezolva2(); return 0;}
83 if(C==3) {rezolva3(); return 0;}
84 return 0;
85 }

2.2 Cartele
Problema 2 - cartele 90 de
puncte
Într-o ³coal  exist  un sistem de acces cu ajutorul cartelelor, conectat la un calculator ³i
o imprimant . Fiecare elev al ³colii are câte o cartel . Într-o zi, la utilizarea ec rei cartele,
sistemul imprim  urm toarele informaµii pe hârtie, pe câte o linie, dup  regula urm toare:
- Caracterul b dac  elevul este b iat sau caracterul f dac  este fat . Caracterul va  urmat de
un spaµiu;
- Caracterul i dac  elevul a intrat în ³coal  sau caracterul e dac  a ie³it din ³coal . De
asemenea, acest caracter va  urmat de un spaµiu;
- Momentul utiliz rii cartelei, exprimat prin or , minute ³i secunde. Acestea vor  reprezentate
în cadrul liniei, exact în aceast  ordine, prin trei numere naturale, separate între ele prin câte un
spaµiu.

Cerinµe
Cunoscându-se toate cele N linii imprimate într-o zi determinaµi:
1. Câµi b ieµi ³i câte fete sunt la ³coal  dup  cele N acµiuni imprimate de sistem.
2. Care este num rul total de secunde în care, în ³coal , s-au aat un num r egal, nenul,
de fete ³i b ieµi, pân  în momentul utiliz rii ultimei cartele. Dac  nu exist  aceast  situaµie se
a³eaz  0.
3. Care este num rul maxim de secunde în care, în ³coal , pân  în momentul utiliz rii ultimei
cartele, s-au aat neîntrerupt un num r impar de b ieµi. Dac  nu exist  o astfel de situaµie se
a³eaz  0.

Date de intrare
Fi³ierul de intrare cartele.in conµine pe prima linie un num r natural C reprezentând num rul
cerinµei care poate avea valorile 1, 2 sau 3, pe a doua linie num rul natural N, iar pe urm toarele
N linii informaµiile imprimate de sistem sub forma descris  în enunµ, în ordinea strict cresc toare
a momentului folosirii cartelei.

Date de ie³ire
Dac  C = 1, atunci ³ierul de ie³ire cartele.out va conµine, în aceast  ordine, separate printr-un
spaµiu, num rul de b ieµi ³i num rul de fete determinat conform cerinµei 1.
Dac  C = 2 sau C = 3, atunci ³ierul de ie³ire cartele.out va conµine pe prima linie un singur
num r natural ce reprezint  rezultatul determinat conform cerinµei.
CAPITOLUL 2. OJI 2019 30

Restricµii ³i preciz ri
a 1&N & 10000
a La momentul utiliz rii primei cartele, în ³coal  nu se a  niciun elev
a Sistemul de acces nu permite folosirea simultan  a dou  cartele
a Pentru orice linie imprimat  de sistem 0 & ora & 23, 0 & minute & 59 ³i 0 & secunde & 59
a Pe ecare linie a ³ierului de intrare, dup  ultimul num r, reprezentând secundele, nu exist 
spaµiu.
a Pentru rezolvarea corect  a primei cerinµe se acord  20 de puncte, pentru rezolvarea corect 
a celei de-a doua cerinµe se acord  30 de puncte iar pentru rezolvarea corect  a celei de-a treia
cerinµe se acord  40 de puncte.

Exemple
cartele.in cartele.out Explicaµii
1 0 1 Se rezolv  cerinµa 1. Un b iat a intrat la momentul 0 0 24
3 (adic  ora 0, minutul 0 ³i secunda 24) ³i ie³it la momentul
b i 0 0 24 0 0 29. O fat  a intrat la momentul 0 0 26.
f i 0 0 26 Dup  cele 3 acµiuni, în ³coal  a r mas o fat .
b e 0 0 29 Num rul cifrelor scrise de Tândal  este 12.
2 3 Se rezolv  cerinµa 2. Între momentul 0 0 24 ³i 0 0 26 în
3 ³coal  este doar un b iat. Între momentul 0 0 26 ³i 0 0 29
b i 0 0 24 în ³coal  se a  un b iat ³i o fat  adic  un num r nenul
f i 0 0 26 egal de fete ³i b ieµi.
b e 0 0 29 Deci, num rul de secunde determinat este 3.
2 47 Se rezolv  cerinµa 2.
8 Între momentele 8 19 12 ³i 8 19 15 în ³coal  se a  1 b iat ³i 1
f i 8 19 10 fat , deci durata este 3 secunde
b i 8 19 12 Între momentele 8 20 0 ³i 8 20 4 în ³coal  se a  1 b iat ³i 1
b e 8 19 15 fat , deci durata este 4 secunde
b i 8 20 0 Între momentele 8 20 10 ³i 8 20 50 în ³coal  se a  1 b iat ³i 1
b e 8 20 4 fat , deci durata este 40 de secunde
b i 8 20 10
b i 8 20 50 Durata total  este 3+4+40=47 de secunde
b i 8 20 51
3 3 Se rezolv  cerinµa 2.
9 Între momentele 8 19 12 ³i 8 19 15 în ³coal  se a  1 b iat, deci
f i 8 19 10 durata este 3 secunde
b i 8 19 12 Între momentele 8 20 0 ³i 8 20 1 în ³coal  se a  1 b iat, deci
f e 8 19 13 durata este 1 secund 
b e 8 19 15 Între momentele 8 20 10 ³i 8 20 12 în ³coal  se a  3 b ieµi,
b i 8 20 0 deci durata este 2 secunde
b e 8 20 1
b i 8 20 10 Durata maxim  cerut  este de 3 secunde
b i 8 20 12
b i 8 20 13

Timp maxim de executare/test: 0.5 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 15 KB
Sursa: cartele.cpp, cartele.c sau cartele.pas va  salvat  în folderul care are drept nume
ID-ul t u.

2.2.1 Indicaµii de rezolvare

Descrierea soluµiei

Se vor citi datele în formatul specicat ³i se vor transforma în secunde momentele ec rei
acµiuni.

Cerinµa 1:
CAPITOLUL 2. OJI 2019 31

- se actualizeaz  num rul de b ieµi ³i fete în funcµie de acµiune (intrare sau ie³ire) ³i se a³eaz 
valorile nale, obµinute dup  a N -a linie citit .

Cerinµa 2 :
- în timpul parcurgerii se reactualizeaz  num rul de b ieµi ³i fete în funcµie de acµiune (intrare
sau ie³ire), vom determina durata de timp curent  care are proprietatea cerut  (num r egal de
fete ³i b ieµi prezenµi în ³coal , num r nenul) ³i adun m perioadele determinate.

Cerinµa 3:
- în timpul parcurgerii se actualizeaz  num rul de b ieµi ³i fete prezenµi în ³coal , în funcµie
de acµiune (intrare sau ie³ire). Vom determina durata neîntrerupt  de timp curent  care are
proprietatea cerut  ³i vom a³a maximul acestora.

Se folosesc tipurile de date caracter ³i întregi (char/int respectiv char/integer) apoi se simuleaz 
acµiunile descrise în secvenµe strict cresc toare de timpi.

Gradul de dicultate
Cerinµa 1 - 2
Cerinµa 2 - 3
Cerinµa 3 - 4

2.2.2 Cod surs 

Listing 2.2.1: cartele_LC.cpp

1 #include<iostream>
2 #include<fstream>
3 #include<cstdlib>
4
5 using namespace std;
6
7 int main()
8 {
9 ifstream f("cartele.in");
10 ofstream g("cartele.out");
11
12 short int C;
13 f>>C;
14
15 if(C==1)
16 {
17 int nr_Fete=0,nr_Baieti=0;
18 char c,c1;
19 int nr,h,m,s;
20
21 f>>nr;
22
23 for(int i=1; i<=nr; i++)
24 {
25 f>>c>>c1>>h>>m>>s;
26
27 if(c==’f’)
28 {
29 if(c1==’e’)
30 nr_Fete--;
31 else
32 nr_Fete++;
33 }
34 else
35 {
36 if(c1==’e’)
37 nr_Baieti--;
38 else
39 nr_Baieti++;
40 }
41
42 }
43 g<<nr_Baieti<<" "<<nr_Fete;
44 }
45
46 if(C==2)
47 {
48 int nr_Fete=0,nr_Baieti=0;
CAPITOLUL 2. OJI 2019 32

49 char c,c1;
50 int nr,s1,s2,h,m,s,timp_total=0;
51
52 f>>nr;
53
54 for(int i=1; i<=nr; i++)
55 {
56 f>>c>>c1>>h>>m>>s;
57
58 bool era_egal=false;
59
60 if(nr_Fete!=0 && nr_Fete==nr_Baieti)
61 era_egal=true;
62
63 if(c==’f’)
64 {
65 if(c1==’e’)
66 nr_Fete--;
67 else
68 nr_Fete++;
69 }
70 else
71 {
72
73 if(c1==’e’)
74 nr_Baieti--;
75 else
76 nr_Baieti++;
77 }
78
79 if(i==1)
80 {
81 s1=0;
82 s1+=h*3600;
83 s1+=m*60;
84 s1+=s;
85 }
86 else
87 {
88 s2=0;
89 s2+=h*3600;
90 s2+=m*60;
91 s2+=s;
92 if(era_egal)
93 timp_total+=s2-s1;
94 s1=s2;
95 }
96 }
97
98 g<<timp_total;
99 }
100
101 if(C==3)
102 {
103 int nr_Baieti=0,nr,s1=0,s2,timp_maxim=0;
104 char c,c1;
105 int h,m,s;
106
107 f>>nr;
108
109 for(int i=1; i<=nr; i++)
110 {
111 f>>c>>c1>>h>>m>>s;
112 bool era_impar=false;
113
114 if(nr_Baieti%2==1)
115 era_impar=true;
116
117 if(c==’b’)
118 {
119 if(c1==’e’)
120 nr_Baieti--;
121 else
122 nr_Baieti++;
123 }
124 if(nr_Baieti%2==1&&s1==0)
CAPITOLUL 2. OJI 2019 33

125 {
126 s1+=h*3600;
127 s1+=m*60;
128 s1+=s;
129 }
130 else
131 {
132 s2=0;
133 s2+=h*3600;
134 s2+=m*60;
135 s2+=s;
136
137 if(era_impar&&nr_Baieti%2==0)
138 {
139 if(s2-s1>timp_maxim)
140 timp_maxim=s2-s1;
141 s1=0;
142 }
143 }
144 }
145
146 g<<timp_maxim;
147 }
148 }

Listing 2.2.2: cartele_td.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("cartele.in");
6 ofstream g("cartele.out");
7
8 int maxim,sec1,sec,p,h,m,s,h1,m1,s1,i,N,max1,cb,cf,suma;
9 char c,a;
10
11 int main()
12 {
13 f>>p;
14 f>>N;
15
16 if (p==1)
17 {
18 cb=0;
19 cf=0;
20 for (i = 1; i <= N; i++)
21 {
22 f>>c>>a>>h>>m>>s;
23 if (c==’b’)
24 if (a==’i’) cb++;
25 else cb--;
26 else
27 if (a==’i’) cf++;
28 else cf--;
29 }
30
31 g<<cb<<" "<<cf<<"\n";
32 }
33 else
34 if (p==2)
35 {
36 f>>c>>a>>h1>>m1>>s1;
37
38 sec1=h1*3600+m1*60+s1;
39
40 if (c==’b’) cb=1,cf=0;
41 else cb=0,cf=1;
42
43 suma=0;
44 for (i = 2; i <= N; i++)
45 {
46 f>>c>>a>>h>>m>>s;
47
48 sec=h*3600+m*60+s;
CAPITOLUL 2. OJI 2019 34

49
50 if (cb==cf && cb>0) suma += (sec-sec1);
51
52 if (c==’b’)
53 if (a==’i’) cb++;
54 else cb--;
55 else
56 if (a==’i’) cf++;
57 else cf--;
58
59 sec1=sec;
60 }
61
62 g<<suma<<"\n";
63 }
64 else
65 {
66 f>>c>>a>>h1>>m1>>s1;
67
68 if (c==’b’) {cb=1; cf=0; sec1=h1*3600+m1*60+s1;}
69 else cb=0,cf=1;
70
71 maxim=0;
72 for (i = 2; i <= N; i++)
73 {
74 f>>c>>a>>h>>m>>s;
75 sec=h*3600+m*60+s;
76 if (c==’b’)
77 {
78 if (cb%2!=0 && sec-sec1 > maxim) maxim=sec-sec1;
79 if (a==’i’) cb++; else cb--;
80 sec1=sec;
81 }
82 else
83 if (a==’i’) cf++; else cf--;
84 }
85
86 g<<maxim<<"\n";
87 }
88 return 0;
89 }

2.2.3 Rezolvare detaliat 

Etapa nr. 0:

Listing 2.2.3: Cartele - Etapa nr. 0

1 #include<iostream>
2 #include<fstream>
3
4 using namespace std;
5
6 ifstream fin("cartele.in");
7 ofstream fout("cartele.out");
8
9 int C, N;
10 char elev; // ’b’ sau ’f’
11 char inout; // ’i’ sau ’e’
12 int ora, minut, sec;
13
14 int nrb, nrf; // nr_baieti, nr_fete
15 int nrtotsec; // nr total secunde
16 int nrmaxsec; // nr maxim secunde
17
18 void rezolva1()
19 {
20
21 }
22
23 void rezolva2()
24 {
CAPITOLUL 2. OJI 2019 35

25
26 }
27
28 void rezolva3()
29 {
30
31 }
32
33 int main()
34 {
35 fin>>C;
36 cout<<"C = "<<C<<"\n";
37
38 if(C==1) {rezolva1(); return 0;}
39 if(C==2) {rezolva2(); return 0;}
40 if(C==3) {rezolva3(); return 0;}
41
42 return 0;
43 }

Etapa nr. 1:

Listing 2.2.4: Cartele - Etapa nr. 1

1 #include<iostream>
2 #include<fstream>
3
4 using namespace std;
5
6 ifstream fin("cartele.in");
7 ofstream fout("cartele.out");
8
9 int C, N;
10 unsigned char elev; // ’b’ sau ’f’
11 unsigned char inout; // ’i’ sau ’e’
12 int ora, minut, sec;
13
14 int nrb, nrf; // nr_baieti, nr_fete
15 int nrtotsec; // nr total secunde
16 int nrmaxsec; // nr maxim secunde
17
18 void citesteCartela()
19 {
20 fin>>elev;
21 fin>>inout;
22 fin>>ora;
23 fin>>minut;
24 fin>>sec;
25 cout<<elev<<" "<<inout<<" "<<ora<<" "<<minut<<" "<<sec<<"\n";
26 }
27
28 void rezolva1()
29 {
30 fin>>N;
31 cout<<"N = "<<N<<"\n";
32
33 nrb=0;
34 nrf=0;
35
36 for(int i=1; i<=N; i++)
37 {
38 citesteCartela();
39
40 if(elev==’b’)
41 {
42 if(inout==’i’) nrb=nrb+1; else nrb=nrb-1;
43 }
44 else
45 if(elev==’f’)
46 {
47 if(inout==’i’) nrf=nrf+1; else nrf=nrf-1;
48 }
49 }
50
51 cout<<"nrb = "<<nrb<<" nrf = "<<nrf<<"\n";
CAPITOLUL 2. OJI 2019 36

52 fout<<nrb<<" "<<nrf<<’\n’;
53 fout.close();
54 }
55
56 void rezolva2()
57 {
58
59 }
60
61 void rezolva3()
62 {
63
64 }
65
66 int main()
67 {
68 fin>>C;
69 cout<<"C = "<<C<<"\n";
70
71 if(C==1) {rezolva1(); return 0;}
72 if(C==2) {rezolva2(); return 0;}
73 if(C==3) {rezolva3(); return 0;}
74
75 return 0;
76 }

Etapa nr. 2:

Listing 2.2.5: Cartele - Etapa nr. 2

1 #include<iostream>
2 #include<fstream>
3
4 using namespace std;
5
6 ifstream fin("cartele.in");
7 ofstream fout("cartele.out");
8
9 int C, N;
10 unsigned char elev; // ’b’ sau ’f’
11 unsigned char inout; // ’i’ sau ’e’
12 int ora, minut, sec;
13
14 int nrb, nrf; // nr_baieti, nr_fete
15 int nrtotsec; // nr total secunde
16 int nrmaxsec; // nr maxim secunde
17
18 void citesteCartela()
19 {
20 fin>>elev;
21 fin>>inout;
22 fin>>ora;
23 fin>>minut;
24 fin>>sec;
25 cout<<elev<<" "<<inout<<" "<<ora<<" "<<minut<<" "<<sec<<"\n";
26 }
27
28 void rezolva1()
29 {
30 fin>>N;
31 cout<<"N = "<<N<<"\n";
32
33 nrb=0;
34 nrf=0;
35
36 for(int i=1; i<=N; i++)
37 {
38 citesteCartela();
39
40 if(elev==’b’)
41 {
42 if(inout==’i’) nrb=nrb+1; else nrb=nrb-1;
43 }
44 else
45 if(elev==’f’)
CAPITOLUL 2. OJI 2019 37

46 {
47 if(inout==’i’) nrf=nrf+1; else nrf=nrf-1;
48 }
49 }
50
51 cout<<"nrb = "<<nrb<<" nrf = "<<nrf<<"\n";
52 fout<<nrb<<" "<<nrf<<’\n’;
53 fout.close();
54 }
55
56 void rezolva2()
57 {
58 nrtotsec=0;
59
60 fin>>N;
61 cout<<"N = "<<N<<"\n";
62
63 nrb=0;
64 nrf=0;
65
66 bool adunTimp=false;
67 int timp1, timp2;
68
69 timp1=0; // moment vechi
70 for(int i=1; i<=N; i++)
71 {
72 citesteCartela();
73
74 if(elev==’b’)
75 {
76 if(inout==’i’) nrb=nrb+1; else nrb=nrb-1;
77 }
78 else
79 if(elev==’f’)
80 {
81 if(inout==’i’) nrf=nrf+1; else nrf=nrf-1;
82 }
83
84 timp2=ora*60*60+minut*60+sec; // moment actual
85
86 if(adunTimp) nrtotsec=nrtotsec+(timp2-timp1);
87
88 timp1=timp2;
89 if(nrb==nrf && nrb>0) adunTimp=true; else adunTimp=false;
90 }
91
92 cout<<"nrtotsec = "<<nrtotsec<<"\n";
93 fout<<nrtotsec<<’\n’;
94 fout.close();
95 }
96
97 void rezolva3()
98 {
99
100 }
101
102 int main()
103 {
104 fin>>C;
105 cout<<"C = "<<C<<"\n";
106
107 if(C==1) {rezolva1(); return 0;}
108 if(C==2) {rezolva2(); return 0;}
109 if(C==3) {rezolva3(); return 0;}
110
111 return 0;
112 }

Etapa nr. 3:

Listing 2.2.6: Cartele - Etapa nr. 3

1 #include<iostream>
2 #include<fstream>
3
CAPITOLUL 2. OJI 2019 38

4 using namespace std;


5
6 ifstream fin("cartele.in");
7 ofstream fout("cartele.out");
8
9 int C, N;
10 unsigned char elev; // ’b’ sau ’f’
11 unsigned char inout; // ’i’ sau ’e’
12 int ora, minut, sec;
13
14 int nrb, nrf; // nr_baieti, nr_fete
15 int nrtotsec; // nr total secunde
16 int nrmaxsec; // nr maxim secunde
17
18 void citesteCartela()
19 {
20 fin>>elev;
21 fin>>inout;
22 fin>>ora;
23 fin>>minut;
24 fin>>sec;
25 cout<<elev<<" "<<inout<<" "<<ora<<" "<<minut<<" "<<sec<<"\n";
26 }
27
28 void rezolva1()
29 {
30 fin>>N;
31 cout<<"N = "<<N<<"\n";
32
33 nrb=0;
34 nrf=0;
35
36 for(int i=1; i<=N; i++)
37 {
38 citesteCartela();
39
40 if(elev==’b’)
41 {
42 if(inout==’i’) nrb=nrb+1; else nrb=nrb-1;
43 }
44 else
45 if(elev==’f’)
46 {
47 if(inout==’i’) nrf=nrf+1; else nrf=nrf-1;
48 }
49 }
50
51 cout<<"nrb = "<<nrb<<" nrf = "<<nrf<<"\n";
52 fout<<nrb<<" "<<nrf<<’\n’;
53 fout.close();
54 }
55
56 void rezolva2()
57 {
58 nrtotsec=0;
59
60 fin>>N;
61 cout<<"N = "<<N<<"\n";
62
63 nrb=0;
64 nrf=0;
65
66 bool adunTimp=false;
67 int timp1, timp2;
68
69 timp1=0; // moment vechi
70 for(int i=1; i<=N; i++)
71 {
72 citesteCartela();
73
74 if(elev==’b’)
75 {
76 if(inout==’i’) nrb=nrb+1; else nrb=nrb-1;
77 }
78 else
79 if(elev==’f’)
CAPITOLUL 2. OJI 2019 39

80 {
81 if(inout==’i’) nrf=nrf+1; else nrf=nrf-1;
82 }
83
84 timp2=ora*60*60+minut*60+sec; // moment actual
85
86 if(adunTimp) nrtotsec=nrtotsec+(timp2-timp1);
87
88 timp1=timp2;
89 if(nrb==nrf && nrb>0) adunTimp=true; else adunTimp=false;
90 }
91
92 cout<<"nrtotsec = "<<nrtotsec<<"\n";
93 fout<<nrtotsec<<’\n’;
94 fout.close();
95 }
96
97 void rezolva3()
98 {
99 nrmaxsec=0;
100
101 fin>>N;
102 cout<<"N = "<<N<<"\n";
103
104 nrb=0;
105
106 int timp1, timp2;
107
108 timp1=0; // moment inainte de citire cartela
109 for(int i=1; i<=N; i++)
110 {
111 citesteCartela();
112
113 if(elev==’b’) // s-a schimbat paritatea numarului de baieti
114 {
115 timp2=ora*60*60+minut*60+sec; //moment actual(dupa citire cartela)
116
117 if(inout==’i’) nrb=nrb+1; else nrb=nrb-1;
118
119 if(nrb%2==1) // a fost nr par de baieti si a venit acum un baiat ...
120 { // ... incepe timp !!!
121 // impar este oricum diferit de zero ... deci ...
122 // ... nu verific nrb==0
123 timp1=timp2;
124 cout<<" nrb = "<<nrb<<" timp1 = "<<timp1<<"\n";
125 }
126 else // a fost nr impar de baieti si ... a venit acum un baiat
127 {
128 if(nrmaxsec < (timp2-timp1)) nrmaxsec = timp2-timp1;
129 cout<<" nrb = "<<nrb<<" timp2 = "<<timp2<<"\n";
130 }
131 }
132 }
133
134 cout<<"nrmaxsec = "<<nrmaxsec<<"\n";
135 fout<<nrmaxsec<<’\n’;
136 fout.close();
137 }
138
139 int main()
140 {
141 fin>>C;
142 cout<<"C = "<<C<<"\n";
143
144 if(C==1) {rezolva1(); return 0;}
145 if(C==2) {rezolva2(); return 0;}
146 if(C==3) {rezolva3(); return 0;}
147
148 return 0;
149 }

Etapa nr. 4 FINALA1 comentat mesajele ajutatoare:


Tema !!!
CAPITOLUL 2. OJI 2019 40

Etapa nr. 5 FINALA2 sters mesajele ajutatoare:


Tema !!!
Capitolul 3

OJI 2018

3.1 Patrate
Problema 1 - Patrate 90 de puncte
Un elev a desenat un set format din mai multe p trate care conµin numere naturale nenule,
distincte, consecutive, dispuse în num r egal pe laturi. Pe latura ec rui p trat sunt scrise un
num r impar de valori. În ecare p trat, numerele sunt scrise în ordine cresc toare parcurgând
laturile sale, începând din colµul stânga-jos, în sensul invers al acelor de ceasornic. Elevul a
numerotat p tratele cu 1, 2, 3 etc., în ordinea strict cresc toare a num rului de valori conµinute
de ecare. Diferenµa dintre cel mai mic num r din p tratul P 1 $ P ³i cel mai mare num r din
p tratul P  1 este egal  cu 1. Primele patru p trate sunt:

Figura 3.1: Patrate

Astfel, primul p trat conµine numerele naturale distincte consecutive de la 1 la 8, dispuse


câte trei pe ecare latur  a p tratului. Al doilea p trat conµine urm toarele 16 numere naturale
distincte consecutive, dispuse câte cinci pe ecare latur . Al treilea p trat conµine urm toarele 24
de numere naturale distincte consecutive, dispuse câte ³apte pe ecare latur . Al patrulea p trat
conµine urm toarele 32 de numere naturale distincte consecutive, dispuse câte nou  pe ecare
latur  etc.

Cerinµe
Scrieµi un program care rezolv  urm toarele dou  cerinµe:
1. cite³te un num r natural M ³i determin  num rul K de valori conµinute de p tratul nume-
rotat cu M;
2. cite³te un num r natural N ³i determin  num rul T al p tratului care conµine num rul N
pe una dintre laturi.

Date de intrare
Fi³ierul de intrare patrate.in conµine pe prima linie un num r natural C reprezentând cerinµa
din problem  care trebuie rezolvat  (1 sau 2). Dac  C 1, atunci ³ierul conµine pe a doua linie
num rul natural M. Dac  C 2, atunci ³ierul conµine pe a doua linie num rul natural N.

Date de ie³ire
41
CAPITOLUL 3. OJI 2018 42

Dac  C 1, atunci ³ierul de ie³irepatrate.out conµine pe prima linie num rul K , reprezen-


tând r spunsul la cerinµa 1 a problemei. Dac  C 2, atunci ³ierul de ie³ire patrate.out conµine
pe prima linie num rul natural T , reprezentând r spunsul la cerinµa 2.

Restricµii ³i preciz ri
a 1 & M & 260000000
a 7 & N & 2147302920
a Numerele N, M, T ³i K sunt numere naturale
a NU exist  dou  p trate cu acela³i num r de valori scrise pe laturi
a Pentru rezolvarea corect  a cerinµei 1 se acord  10 puncte; pentru rezolvarea corect  a cerinµei
2 se acord  80 de puncte. Se acord  10 puncte din ociu.

Exemple
patrate.in patrate.out Explicaµii
1 24 Cerinµa este 1. P tratul numerotat cu M 3 conµine
3 K 24 de numere naturale (vezi gura din enunµ).
2 4 Cerinµa este 2. Num rul N 73 este conµinut de p tratul
73 K 24 numerotat cu T 4 (vezi gura din enunµ).

Timp maxim de executare/test: 0.3 secunde


Memorie: 8M B
Dimensiune maxim  a sursei: 5KB

3.1.1 Indicaµii de rezolvare

Descrierea soluµiei

Autor prof. Carmen Minc 


Colegiul Naµional de Informatic  "Tudor Vianu" - Bucure³ti

P tratele conµin numere naturale distincte consecutive.


Primul p trat are pe latur  L 3 2˜11 numere ³i conµine în total K 4˜L4 8˜1
numere
Al doilea p trat are pe latur  L 5 2 ˜ 2  1 numere ³i conµine în total K 4˜L4 2˜8
numere
Al treilea p trat are pe latur  L 7 2 ˜ 3  1 numere ³i conµine în total K 4˜L4 3˜8
numere
...........
Al T -lea L
2 ˜ T  1 numere ³i conµine în total 4 ˜ L  4 T ˜ 8 numere
p trat are pe latur 
Cerinµa 1. M sunt scrise 8 ˜ M numere naturale distincte.
Pe laturile p tratului
Cerinµa 2.Num rul de numere folosite în primele T  1 p trate este:
8 ˜ 1  8 ˜ 2  8 ˜ 3  ...  8 ˜ T  1 8 ˜ 1  2  3  ...  T  1 4 ˜ T ˜ T  1
Numerele din p tratul T sunt: 4 ˜ T T  1  1, 4 ˜ T T  1  2, 4 ˜ T T  1  3, ...,
4 ˜ T ˜ T  1  8 ˜ T 4 ˜ T ˜ T  1
Num rul N este în p tratul T dac  este adev rat  relaµia: 4 ˜ T T  1  1 & N & 4 ˜ T ˜ T  1

3.1.2 Cod surs 

Listing 3.1.1: patrate_AS.cpp

1 //#include <iostream>
2 #include <fstream>
3 #include<cmath>
4
5 using namespace std;
6
7 int N,C,K,M,T;
8
9 int main()
10 {
CAPITOLUL 3. OJI 2018 43

11 ifstream in("patrate.in");
12 ofstream out("patrate.out");
13
14 in>>C;
15
16 if(C==1)
17 {
18 in>>M;
19 out<<8*M<<endl;
20 }
21 else
22 {
23 in>>N;
24 T=sqrt(N);
25 if(T%2)T++;
26 out<<T/2<<endl;
27 }
28 return 0;
29 }

Listing 3.1.2: patrate_cpp_CM.cpp

1 #include <fstream>
2 using namespace std;
3
4 ifstream f("patrate.in");
5 ofstream g("patrate.out");
6
7 int main()
8 {
9 int N,C,M,T,K,nr=0;
10 f>>C;
11
12 if(C==1)
13 {
14 f>>M;
15 K=8*M;
16 g<<K<<endl;
17 }
18 else
19 {
20 f>>N;
21 T=0;
22 nr=0;
23 while(8*(T+1)<=N-nr)
24 {
25 ++T;
26 K=8*T;
27 nr=nr+K;
28 }
29 if(N>nr){ ++T; }
30
31 g<<T<<endl;
32 }
33
34 return 0;
35 }

Listing 3.1.3: patrate_FB.cpp

1 //#include <iostream>
2 #include <fstream>
3
4 using namespace std;
5
6 ifstream f("patrate.in");
7 ofstream g("patrate.out");
8
9 long long c,N,x,k,T,M;
10
11 int main()
12 {
13 f>>c;
14 if(c==1)
CAPITOLUL 3. OJI 2018 44

15 {
16 f>>M;
17 g<<8*M;
18 }
19 else
20 {
21 f>>N;
22 k=8;
23 T=1;
24 while(N-k>0)
25 {
26 N=N-k;
27 k=k+8;
28 T++;
29 }
30
31 g<<T;
32 }
33 return 0;
34 }

Listing 3.1.4: patrate_VG.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 int main()
6 { int m, cer, n;
7 long long t,x;
8
9 ifstream f("patrate.in");
10 ofstream g("patrate.out");
11
12 f>>cer>>n;
13
14 if(cer==1)
15 g<<8*n<<endl;
16 else
17 {
18 if(n<8) g<<1<<endl;
19 else
20 {
21 m=1; t=0; x=0;
22 while(t<n)
23 {
24 t=8*(m+x);
25 x+=m;
26 m++;
27 }
28 g<<m-1<<endl;
29 }
30 }
31 return 0;
32 }

3.1.3 *Rezolvare detaliat 

3.2 forus
Problema 2 - forus 90 de puncte
La ora de educaµie tehnologic  a clasei a V-a profesorul Forus, pasionat de matematic , a adus
pentru ecare dintre cei N elevi câte un carton pe care este scris câte un num r natural nenul.
Fiecare elev poate folosi cartonul a³a cum l-a primit sau poate s  taie o singur  dat  cartonul
între dou  cifre ³i s  lipeasc  partea stâng  la nalul p rµii drepte. Elevul NU are voie s  fac 
o t ietur  în faµa cifrei 0, deci niciunul dintre numerele obµinute NU poate s  înceapă cu cifra
0. Dintre toate numerele pe care le poate obµine, elevul îl alege pe cel care are num r minim de
CAPITOLUL 3. OJI 2018 45

divizori, iar dac  poate obµine mai multe astfel de numere, îl alege pe cel mai mic dintre ele. La
sfâr³itul orei, profesorul strânge cartoanele cu numerele alese, în ordinea distribuirii lor.
De exemplu, dac  iniµial elevul prime³te cartonul cu num rul 25082 atunci el are doar urm -
toarele trei variante de t iere ³i lipire:

Figura 3.2: forus

Cerinµe
Scrieµi un program care cite³te num rul natural N ³i cele N numere scrise pe cartoanele aduse
de profesorul Forus, apoi rezolv  urm toarele dou  cerinµe:
1. determin  num rul de cartoane pe care elevii au voie s  le taie de oriunde (NU conµin cifre
în faµa c rora NU au voie s  taie);
2. determin , în ordinea strângerii cartoanelor, numerele preluate de c tre profesorul Forus la
nalul orei.

Date de intrare
Fi³ierul de intrare forus.in conµine pe prima linie un num r natural C reprezentând cerinµa
din problem  care trebuie rezolvat  (1 sau 2). A doua linie din ³ier conµine un num r natural N,
reprezentând num rul de elevi, iar a treia linie din ³ier conµine N numere naturale, separate prin
câte un spaµiu, reprezentând numerele scrise pe cartoanele aduse de profesor, în ordinea distribuirii
lor.

Date de ie³ire
Dac  C 1, ³ierul de ie³ire forus.out conµine pe prima linie un num r natural reprezentând
r spunsul la cerinµa 1.
Dac  C 2, ³ierul de ie³ire forus.out conµine pe prima linie N numere naturale, separate
prin câte un spaµiu, reprezentând r spunsul la cerinµa 2; numerele sunt scrise în ordinea în care
au fost strânse.

Restricµii ³i preciz ri
a 2 & N & 30
a 1 & num rul natural de pe carton $ 1000000000
a Pentru rezolvarea corect  a cerinµei 1 se acord  20 de puncte; pentru rezolvarea corect  a
cerinµei 2 se acord  70 de puncte. Se acord  10 puncte din ociu.

Exemple
forus.in forus.out Explicaµii
1 3 Cerinµa este 1. Sunt 3 numere care pot 
3 t iate de oriunde: 1234, 543, 52.
1234 25082 543 52 150
2 15 2341 25082 453 501 Cerinµa este 2. Pentru cartonul cu num rul
5 51 se pot obµine numerele 15 ³i 51. Ambele
51 1234 50822 345 150 numere au câte 4 divizori. Astfel, se va alege
num rul 15, ind cel mai mic.
Pentru cartonul cu num rul 1234 (4 divizori)
pot  obµinute numerele: 2341 (2 divizori),
3412 (6 divizori) ³i 4123 (8 divizori). Se va
alege num rul 2341 pentru c  are num rul
minim de divizori. Analog se va proceda
pentru toate celelalte numere din ³ir.
CAPITOLUL 3. OJI 2018 46

Timp maxim de executare/test: 0.5 secunde


Memorie: 8M B
Dimensiune maxim  a sursei: 10KB

3.2.1 Indicaµii de rezolvare

Descrierea soluµiei

Autor prof. FLAVIUS BOIAN


Colegiul Naµional "SPIRU HARET" TG-JIU

Cerinµa 1. Pentru ecare num r citit, se veric  dac  conµine cel puµin o cifr  de 0 în scrierea
sa. Se vor contoriza numerele citite care nu conµin cifra 0.
Cerinµa 2. Pentru ecare num r citit se construiesc prin permut ri circulare la dreapta cu
o poziµie toate numerele posibile. Dintre acestea se va alege num rul cu un num r minim de
divizori, cu observaµia c  num rul ales trebuie s  aib  acela³i num r de cifre ca ³i num rul iniµial
(nu am voie s  tai înaintea cifrei 0). Vom genera toate aceste numerele care se pot forma ³i vom
calcula num rul de divizori, reµinând de ecare dat  pe cel cu num r minim de divizori, iar în caz
de egalitate a num rului de divizori îl vom reµine pe cel mai mic.

3.2.2 Cod surs 

Listing 3.2.1: forus_CM_100.cpp

1 ///#include <iostream>
2 #include <fstream>
3 using namespace std;
4
5 ifstream f("forus.in");
6 ofstream g("forus.out");
7
8 int nrdiv(int N)
9 {
10 int d, nrd=1;
11 for(d=1;d*d<N;d++)
12 if(N%d==0)nrd+=2;
13 if(d*d==N) ++nrd;
14 return nrd;
15 }
16
17 int main()
18 {
19 int C,N,nr;
20 f>>C>>N;
21 if(C==1)
22 {
23 int r=0,ok;
24 for(int i=1; i<=N; i++)
25 {
26 f>>nr;
27 //cout<<nr<<" ";
28 ok=1;
29 while(nr && ok)
30 {
31 if (nr%10==0)ok=0;
32 nr=nr/10;
33 }
34 r=r+ok;
35 }
36 g<<r<<endl;
37 }
38 else
39 {
40 int y,p,nrc,x,pr,ult,pu,xmin,nrdm,nrd,z;
41 for(int i=1; i<=N; i++)
42 {
43 f>>nr;
44 p=1;nrc=1;pu=10;
CAPITOLUL 3. OJI 2018 47

45 xmin=nr; nrdm=nrdiv(nr);
46 x=nr;
47 while(x>0)
48 {
49 x=x/10;
50 p=p*10;
51 nrc++;
52 }
53 p=p/10;z=p;
54 for(int i=1; i<nrc; i++)
55 {
56 pr=nr/p;
57 ult=nr%p;
58 x=ult*pu+pr;
59 if(x/z>0)
60 {
61 nrd=nrdiv(x);
62 if(nrd<nrdm)
63 {
64 xmin=x;
65 nrdm=nrd;
66 }
67 else
68 if(nrd==nrdm) xmin=min(xmin,x);
69 }
70 pu=pu*10;
71 p=p/10;
72 }
73 g<<xmin<<" ";
74 }
75 g<<endl;
76 }
77
78 return 0;
79 }

Listing 3.2.2: forus_nvl_100.cpp

1 /// Nicu Vlad-Laurentiu


2
3 #include <bits/stdc++.h>
4
5 using namespace std;
6
7 ifstream fin("forus.in");
8 ofstream fout("forus.out");
9
10 int nr_div(int x)
11 {
12 int p,d=2,N=1;
13 while(x>1)
14 {
15 p=0;
16 while(x%d==0)
17 {
18 p++;
19 x/=d;
20 }
21 if(p)N*=(p+1);
22 if(d*d<x) d++;
23 else d=x;
24 }
25 return N;
26 }
27
28 int pow10(int nc)
29 {
30 int P=1;
31 for(int i=1; i<=nc; ++i)
32 P*=10;
33 return P;
34 }
35
36 int main()
37 {
CAPITOLUL 3. OJI 2018 48

38 int n,x,cer;
39 fin>>cer>>n;
40 if(cer==1)
41 {
42 int nr=0,nc,n0;
43 for(; n; n--)
44 {
45 fin>>x;
46 nc=0,n0=0;
47 if(x==0) nr++;
48 while(x)
49 {
50 if(x%10==0) n0++;
51 nc++;
52 x/=10;
53 }
54 if(n0==0) nr++;
55 }
56 fout<<nr;
57 }
58 else
59 {
60 int nc;
61 long long put,nrmax=0,val,nrc;
62 for(; n; n--)
63 {
64 fin>>x;
65
66 nc=log10(x);
67 put=pow10(nc);
68 nrmax=nr_div(x);
69 val=x;
70
71 for(int i=1; i<=nc; ++i)
72 {
73 x=x%put*10+x/put;
74 if(x/put!=0)
75 {
76 nrc=nr_div(x);
77 if(nrc<nrmax)
78 {
79 nrmax=nrc;
80 val=x;
81 }
82 else if(nrc==nrmax &&val>x) val=x;
83 }
84 }
85 fout<<val<<" ";
86 }
87 }
88 return 0;
89 }

Listing 3.2.3: forus_VG_100.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 int main()
6 {
7 ifstream f("forus.in");
8 ofstream g("forus.out");
9
10 long long x,mx;
11 int c, n, a,b, r,i,ok,nd,d,y,nc,p,j,nz;
12
13 f>>c;
14 if(c==1)
15 {
16 f>>n;
17 r=0;
18 for(i=1;i<=n;i++)
19 {
20 f>>x;
CAPITOLUL 3. OJI 2018 49

21 ok=1;
22 while(x>0 && ok)
23 if(x%10==0) ok=0;
24 else x/=10;
25 if(ok) r++;
26 }
27
28 g<<r;
29 }
30 else
31 {
32 f>>n;
33 for(i=1;i<=n;i++)
34 {
35 f>>x;
36 if(x<10)
37 g<<x<<’ ’;
38 else
39 {
40 y=x;
41 mx=1000000000;
42 nc=0;
43 p=1;
44 while(x)
45 {
46 nc++;
47 x/=10;
48 p=p*10;
49 }
50
51 p=p/10;
52 x=y;
53
54 do
55 {
56 nd=0;
57 for(d=1;d*d<x;d++)
58 if(x%d==0) nd+=2;
59 if(d*d==x) nd++;
60
61 // g<<x<<’ ’<<nd<<’ ’<<’\n’;
62 if(nd<mx)
63 {
64 r=x;
65 mx=nd;
66 }
67 else
68 if(nd==mx) if(x<r) r=x;
69
70 if(x/(p/10)%10==0)
71 {
72 nz=0;
73 y=p/10;
74 while(x/y%10==0 && y>1)
75 {
76 y=y/10;
77 nz++;
78 }
79 a=x/p;
80 x=x*10+a;
81 x=x%p;
82 for(j=1;j<=nz;j++)
83 x=x*10;
84 nc=nc-nz;
85 }
86 else
87 {
88 a=x/p;
89 b=x%p;
90 x=b*10+a;
91 }
92
93 nc--;
94
95 } while(nc>0);
96
CAPITOLUL 3. OJI 2018 50

97 g<<r<<’ ’;
98 }
99 }
100 }
101 return 0;
102 }

Listing 3.2.4: ocial_FB_100.cpp

1 #include <iostream>
2 #include <fstream>
3 #include <cmath>
4 using namespace std;
5
6 ifstream f("forus.in");
7 ofstream g("forus.out");
8
9 int N,P,i,u,x,ok,k,t,cifre,minim,numar,pf,ps,p,ajt;
10 int main()
11 {
12 f>>P>>N;
13 if(P==1)
14 {
15 for(i=1; i<=N; i++)
16 {
17 f>>x;
18 ok=1;
19 while(x)
20 {
21 u=x%10;
22 if(u==0)
23 {
24 ok=0;
25 break;
26 }
27 x=x/10;
28 }
29 if(ok==1) k++;
30 }
31 g<<k;
32 }
33 if(P==2)
34 {
35 for(i=1; i<=N; i++)
36 {
37 f>>x;
38 t=x;
39 cifre=0;
40 while(t)
41 {
42 t=t/10;
43 cifre++;
44 }
45 t=x;
46
47 int prod=1,d,putere=0;
48 while(t%2==0)
49 {
50 t=t/2;
51 putere++;
52 }
53 if(putere>0) prod=prod*(putere+1);
54 d=3;
55 while(t>1)
56 {
57 putere=0;
58 while(t%d==0)
59 {
60 t=t/d;
61 putere++;
62 }
63 if(putere>0)
64 prod=prod*(putere+1);
65 d=d+2;
66 if(d*d>t)
CAPITOLUL 3. OJI 2018 51

67 d=t;
68 }
69 minim=prod;
70
71 t=x;
72 numar=x;
73 k=cifre-1;
74 p=1;
75 while(k)
76 {
77 p*=10;
78 k--;
79 }
80 k=cifre-1;
81 while(k)
82 {
83 if(t%10!=0)
84 {
85 pf=t%10;
86 ps=t/10;
87 t=pf*p+ps;
88 prod=1,putere=0;
89 ajt=t;
90 while(t%2==0)
91 {
92 t=t/2;
93 putere++;
94 }
95 if(putere>0) prod=prod*(putere+1);
96 d=3;
97 while(t>1)
98 {
99 putere=0;
100 while(t%d==0)
101 {
102 t=t/d;
103 putere++;
104 }
105 if(putere>0) prod=prod*(putere+1);
106 d=d+2;
107 if(d*d>t) d=t;
108 }
109 if(prod<minim)
110 {
111 minim=prod;
112 numar=ajt;
113 }
114 if(prod==minim and ajt<numar)
115 {
116 numar=ajt;
117 }
118 t=ajt;
119 }
120 else
121 {
122 pf=t%10;
123 ps=t/10;
124 t=pf*p+ps;
125 }
126 k--;
127 }
128 g<<numar<<" ";
129 }
130 }
131 return 0;
132 }

3.2.3 *Rezolvare detaliat 


Capitolul 4

OJI 2017

4.1 numere
Problema 1 - numere 90 de puncte
Un copil construie³te un triunghi cu numerele naturale nenule astfel:
- în vârful triunghiului scrie valoarea 1;
- completeaz  liniile triunghiului de sus în jos, iar c suµele de pe aceea³i linie de la stânga la
dreapta cu numere naturale consecutive, ca în gurile urm toare.

Figura 4.1: Numere

În gura 1 este ilustrat un astfel de triunghi având 5 linii, conµinând numerele naturale de la
1 la 15. În acest triunghi copilul începe s  construiasc  drumuri, respectând urm toarele reguli:
- orice drum începe din 1;
- din orice c suµ  se poate deplasa e în c suµa situat  pe linia urm toare în stânga sa (deplasare
codicat  cu 1), e în c suµa situat  pe linia urm toare în dreapta sa (deplasare codicat  cu 2);
- orice drum va  descris prin succesiunea deplas rilor efectuate.
De exemplu, drumul ilustrat în gura 2 poate  descris astfel: 1222.

Cerinµe
Scrieµi un program care rezolv  urm toarele dou  cerinµe:
1. cite³te descrierea unui drum ³i a³eaz  num rul la care se termin  drumul;
2. cite³te un num r natural nenul K , determin  un drum care se termin  cu num rul K pentru
care suma numerelor prin care trece drumul este maxim  ³i a³eaz  aceast  sum .

Date de intrare
Fi³ierul de intrare numere.in conµine pe prima linie un num r natural C reprezentând cerinµa
din problem  care trebuie rezolvat  (1 sau 2).
Dac  C este egal cu 1, a doua linie din ³ier conµine un num r natural N, reprezentând
lungimea drumului, iar a treia linie din ³ier conµine descrierea drumului sub forma a N valori, 1
sau 2, separate între ele prin câte un spaµiu.
Dac  C este egal cu 2, a doua linie din ³ier conµine num rul natural K.

Date de ie³ire

52
CAPITOLUL 4. OJI 2017 53

Fi³ierul de ie³ire numere.out va conµine o singur  linie pe care va  scris un singur num r
natural. Dac  C 1, va  scris num rul cu care se termin  drumul descris în ³ierul de intrare.
Dac  C 2, va  scris  suma maxim  a numerelor aate pe un drum care se termin  cu num rul
K.

Restricµii ³i preciz ri
a 1&N & 10000
a 1&K & 10001 ˜ 10002©2
a Pentru rezolvarea corect  a cerinµei 1 se acord  40 de puncte; pentru rezolvarea corect  a
cerinµei 2 se acord  50 de puncte. 10 puncte se acord  din ociu.

Exemple
numere.in numere.out Explicaµii
1 13 Cerinµa este 1. Drumul descris are lungimea 4 ³i trece
4 prin numerele 1, 2, 5, 8, 13 .
1 2 1 2
2 19 Cerinµa este 2. Suma maxim  se obµine pe drumul
9 care trece prin numerele 1, 3, 6, 9 1  3  6  9 19.

Timp maxim de executare/test: 0.2 secunde


Memorie: 2 MB din care 1 MB pentru stiv 
Dimensiune maxim  a sursei: 10 KB

4.1.1 Indicaµii de rezolvare

prof. Cerasela-Daniela Carda³, Colegiul Naµional A.T.Laurian Boto³ani

1.Initializam casuta curenta si numarul liniei de pornire cu 1.

Pentru fiecare din cei n pasi din descriere:


- o alegere de tip 1 presupune actualizarea casutei curente cu valoarea casuta_cure
- o alegere de tip 2 conduce la actualizarea casutei curente cu casuta_curenta+lini
- incrementam numarul liniei curente.

2. Daca linia pe care se afla numarul K este l si numarul de ordine al numarului K


pe linia l este c, se observa ca suma maxima se obtine din insumarea ultimelor valo
de pe liniile 1,2,...,c si a valorilor de pe pozitia c din liniile c+1,c+2...,l.

Fie ultim - valoarea ultimului element de pe fiecare linie si l valoarea liniei cur
Initial ultim=1, l=0.
Cat timp ultim < K,incrementam linia, actualizam ultim cu ultim<-ultim+l, calculam
numerelor de linie.
Cand ultim>=K, elemc<-K
Repetat
-eliminam din suma s ultimul element de pe linia l si adunam elementul de pe poziti
-elemc<-elemc-l+1
-decrementam linia l
pana cand l=c

4.1.2 Cod surs 

Listing 4.1.1: numere_cardas.cpp

1 ///autor prof. Cerasela-Daniela Cardas, Colegiul National A.T.Laurian Botosani


2 #include <fstream>
3
4 using namespace std;
5
CAPITOLUL 4. OJI 2017 54

6 ifstream fin("numere.in");
7 ofstream fout("numere.out");
8
9 unsigned C,N,K,pas,curent,linie,rest,s,ultim;
10
11 int main()
12 {
13 fin>>C;
14 if(C==1)
15 { fin>>N;curent=1;
16 for(linie=1;linie<=N;linie++)
17 {
18 fin>>pas;
19 curent+=linie;
20 if(pas==2)
21 curent++;
22 }
23 fout<<curent<<’\n’;
24 return 0;
25 }
26 ///C=2
27 fin>>K;
28 while(ultim<K)
29 {
30 ultim+=++linie;
31 s+=ultim;
32 }
33 rest=ultim-K;
34 s-=rest*(rest+1)/2;
35 fout<<s<<’\n’;
36 return 0;
37 }

Listing 4.1.2: numere_cerchez.cpp

1 //Emanuela Cerchez 90 puncte


2 #include <fstream>
3
4 using namespace std;
5
6 ifstream fin("numere.in");
7 ofstream fout("numere.out");
8 int c, n, K, nr, sum;
9
10 int main()
11 {
12 int lin, col, i, j, d, ultim;
13 fin>>c;
14 if (c==1)
15 {
16 fin>>n;
17 col=1;
18 for (i=0; i<n; i++)
19 {
20 fin>>d;
21 col+=d-1;
22 }
23 lin=n+1;
24 nr=lin*(lin-1)/2;//1+2+...lin-1
25 nr+=col;
26 fout<<nr<<’\n’;
27 }
28 else
29 {
30 fin>>K;
31 for (lin=1; K>lin*(lin+1)/2; lin++);
32 col=K-lin*(lin-1)/2;
33 sum=ultim=0;
34 for (i=1; i<=col; i++)
35 {
36 ultim+=i;
37 sum+=ultim;
38 }
39 for (i=col+1; i<=lin; i++)
40 {
CAPITOLUL 4. OJI 2017 55

41 ultim+=i;
42 sum+=(ultim-(i-col));
43 }
44 fout<<sum<<’\n’;
45 }
46 fout.close();
47 return 0;
48 }

Listing 4.1.3: numere_jakab.cpp

1 #include <iostream>
2 #include <fstream>
3 #include <stdlib.h>
4
5 using namespace std;
6
7 int main()
8 {
9 ifstream in("numere.in");
10 ofstream out("numere.out");
11
12 int p,a,b,n,i,nr=1,lin,col;
13 in>>p;
14
15 if(p==1)
16 {
17 in>>n;
18 for(i=2;i<=n+1;i++)
19 {
20 in>>a;
21 if(a==1)
22 nr=nr+i-1;
23 else
24 nr=nr+i;
25 }
26 out<<nr<<endl;
27 }
28
29 if(p==2)
30 {
31 in>>nr;
32 a=1;lin=1;
33 while(a<nr)
34 {
35 lin++;
36 a=a+lin;
37 }
38
39 col=(a+nr)%lin;
40 a=1;
41 b=1;
42 for(i=2;i<=col;i++)
43 {
44 b=b+i;
45 a=a+b;
46 }
47 for(i=col;i<lin;i++)
48 {
49 b=b+i;
50 a=a+b;
51 }
52 out<<a;
53 }
54 in.close();
55 out.close();
56 return 0;
57 }

Listing 4.1.4: numere_sandor.cpp

1 #include <fstream>
2
3 using namespace std;
CAPITOLUL 4. OJI 2017 56

4
5 ifstream fin("numere.in");
6 ofstream fout("numere.out");
7
8 int main()
9 {
10 int C,N,nr,i,x;
11 fin>>C;
12 if(C==1)
13 {
14 fin>>N;nr=1;
15 for(i=1;i<=N;i++)
16 {
17 fin>>x;
18 if(x==1)
19 nr=nr+i;
20 else
21 nr=nr+i+1;
22 }
23 fout<<nr;
24 }
25 else
26 {
27 int n,S;
28 fin>>N;
29 n=1;
30 while(n*(n+1)/2<N)
31 n++;
32 S=N;
33 while(n*(n+1)/2!=N)
34 {
35 n--;
36 N=N-n;
37 S=S+N;
38 }
39 n--;
40 while(n>=1)
41 {
42 S=S+n*(n+1)/2;
43 n--;
44 }
45 fout<<S;
46 }
47 return 0;
48 }

Listing 4.1.5: numere_vladescu.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream fin("numere.in");
6 ofstream fout("numere.out");
7
8 int n,c,nr,i,k,x,s,a,b,j;
9
10 int main()
11 {
12 fin>>c;
13 if (c==1)
14 {
15 fin>>n;
16 nr=1;
17 for (i=1;i<=n;i++)
18 {
19 fin>>x;
20 if (x==1)
21 nr=nr+i;
22 else
23 nr=nr+i+1;
24 }
25 fout<<nr;
26 }
27 else
CAPITOLUL 4. OJI 2017 57

28 {
29 fin>>k;
30 i=1; a=1;
31 while (a<k)
32 {
33 a=i*(i+1)/2;
34 if (k>a)
35 i=i+1;
36 }
37 b=0;
38 a=(i-1)*i/2;
39 while (a<k)
40 {
41 a=a+1;
42 b=b+1;
43 }
44 for (j=1;j<=b;j++)
45 s=s+j*(j+1)/2;
46 for (j=b+1;j<=i-1;j++)
47 s=s+j*(j-1)/2+b;
48 s=s+k;
49 fout<<s;
50 }
51 return 0;
52 }

4.1.3 *Rezolvare detaliat 

4.2 robot
Problema 2 - robot 90 de puncte
Paul dore³te s  înveµe cum s  programeze un robot. Pentru început s-a gândit s  construiasc 
un robot format dintr-un mâner, 10 butoane aranjate circular ³i un ecran. Pe butoane sunt scrise,
în ordine cresc toare, cifrele de la 0 la 9, ca în gur .

Figura 4.2: Robot

Un roboprogram va  format dintr-o secvenµ  de instrucµiuni. Instrucµiunile pot :

Instrucµiune Explicaµii
Dp Mânerul robotului se deplaseaz  spre dreapta cu p poziµii (p este o cifr ).
Sp Mânerul robotului se deplaseaz  spre stânga cu p poziµii (p este o cifr ).
A Este ap sat butonul în dreptul c ruia se a  mânerul robotului ³i pe ecran
apare cifra scris  pe buton.
T Terminarea programului (se utilizeaz  o singur  dat  la nal ³i este precedat 
de cel puµin o instrucµiune A).

Iniµial mânerul robotului este plasat în dreptul butonului 0, iar ecranul este gol.
De exemplu, în urma execut rii roboprogramului D4AS1AAD6AT robotul apas  butoanele pe
care sunt scrise cifrele 4, 3, 3, 9, iar pe ecran va ap rea 4339.

Cerinµe
S  se scrie un program care rezolv  urm toarele cerinµe:
1. cite³te un roboprogram ³i determin  num rul de cifre a³ate pe ecran dup  executarea
roboprogramului;
CAPITOLUL 4. OJI 2017 58

2. cite³te un roboprogram ³i determin  cifrele a³ate pe ecran dup  executarea roboprogra-


mului;
3. cite³te un num r natural N ³i construie³te un roboprogram de lungime minim  prin execu-
tarea c ruia pe ecran se va obµine num rul N ; deoarece robotului îi place s  se deplaseze în special
spre dreapta, dac  exist  mai multe roboprograme de lungime minim , se va a³a roboprogramul
cu num r maxim de instrucµiuni D.

Date de intrare
Fi³ierul de intrare robot.in conµine pe prima linie un num r natural C , reprezentând cerinµa
care urmeaz  s  e rezolvat  (1, 2 sau 3). Dac  C 1 sau C 2, pe a doua linie a ³ierului se
a  un roboprogram. Dac  C 3, pe a doua linie a ³ierului de intrare se a  num rul natural
N.

Date de ie³ire
Fi³ierul de ie³ire robot.out va conµine o singur  linie. Dac  C 1, pe prima linie se va scrie
un num r natural reprezentând num rul de cifre a³ate pe ecran dup  executarea roboprogra-
mului din ³ierul de intrare. Dac  C 2, pe prima linie vor  scrise cifrele a³ate pe ecran în
urma execut rii roboprogramului din ³ierul de intrare. Dac  C 3, pe prima linie va  scris
roboprogramul solicitat de cerinµa 3.

Restricµii ³i preciz ri
a 0&N & 1000000000
a Lungimea roboprogramului citit din ³ierul de intrare sau scris în ³ierul de ie³ire este cel
mult 1000 de caractere.
a Dac  mânerul este plasat în dreptul butonului 0 ³i se deplaseaz  spre dreapta, se va îndrepta
c tre butonul 1; dac  deplasarea este spre stânga, se va îndrepta c tre butonul 9.
a Pentru rezolvarea corect  a primei cerinµe se acord  10 de puncte, pentru rezolvarea corect 
a celei de a doua cerinµe se acord  30 de puncte, iar pentru rezolvarea corect  a celei de a treia
cerinµe se acord  50 de puncte. 10 puncte se acord  din ociu.

Exemple
robot.in robot.out Explicaµii
1 3 C 1, pentru acest test se rezolv  cerinµa 1.
D1AD2AS1AT Se a³eaz  pe ecran 3 cifre (132) .
2 3 C 2, pentru acest test se rezolv  cerinµa 2.
S0AD2AS1AT Mânerul robotului se deplaseaz  cu 0 unit µi la stânga, deci
r mâne în dreptul butonului 0 ³i apas , apoi se deplaseaz  2
unit µi spre dreapta ³i ajunge în dreptul butonului 2, apas , apoi
se deplaseaz  1 unitate la stânga ³i ajunge în dreptul butonului
1 ³i apas  acest buton 
021.
3 3 C 3, pentru acest test se rezolv  cerinµa 3.
19332 Pentru a a³a cifra 1, mânerul robotului se deplaseaz  1 uni-
tate la dreapta dup  care apas  (D1A). Pentru a a³a cifra 9,
din poziµia curent  mânerul robotului se deplaseaz  2 unit µi la
stânga ³i apas  (S2A). Pentru a a³a cifra 3, din poziµia curent 
mânerul robotului se deplaseaz  4 unit µi la dreapta dup  care
apas  (D4A). Pentru a a³a a doua cifra 3, mânerul robotului
r mâne în poziµia curent  ³i apas  butonul. Pentru a a³a cifra
2, din poziµia curent  mânerul robotului se deplaseaz  1 unitate
la stânga dup  care apas  (S1A). Programul se termin  cu in-
strucµiunea T  D1AS2AD4AAS1AT .

Timp maxim de executare/test: 0.2 secunde


Memorie: total 2 MB din care pentru stiv  1 MB
Dimensiune maxim  a sursei: 10 KB
CAPITOLUL 4. OJI 2017 59

4.2.1 Indicaµii de rezolvare

prof. Jakab Irma-Tunde, Liceul Teoretic "Bolyai Farkas"

Punctul 1

Numarul de cifre afisate pe ecran dupa executarea roboprogramului inseamna de cate


apasa robotul un anumit buton, adica de cate ori trebuie sa se execute instructiune

Astfel, se citeste roboprogramul caracter cu caracter si se numara caracterele ’A’.

Punctul 2

Determinarea cifrelor afisate pe ecran dupa executarea roboprogramului inseamna det


cifrei in dreptul careia se va pozitiona manerul robotului la executarea instructiu

Se citesc datele caracter cu caracter, se identifica directia si pozitia iar in fun


directia indicata se determina cifra care trebuie afisata.

Pentru stabilirea pozitiei, caracterele cifre din roboprogram trebuie transformate


cifre numerice.

Daca directia indicata este dreapta si deoarece manerul robotului se deplaseaza cir
numarul de pozitii efectuate va fi suma dintre pozitia (cifra curenta) si cifra ind
in program modulo 10 (avand in total 10 cifre). Daca directia indicata este dreapta
din cauza deplasarii circulare din pozitia curenta se scade cifra din roboprogram,
rezultatul este negativ, se aduna 10.

Trebuie sa se tina cont de faptul ca instructiunile pot sa indice cifre 0 chiar la


respectiv cifrele pot aparea de mai multe ori datorita prezentei repetate a instruc

Punctul 3

Pentru numarul citit, instructiunile trebuie asociate incepand de la cifra cea mai
semnificativa spre cifra unitatilor si trebuie acordat atentie cifrelor 0 de la sfa
numarului dat (se determina oglinditul numarului si se retine numarul de zerouri de
sfarsitul numarului citit).

Numarul citit se prelucreaza cifra cu cifra, se calculeaza numarul de deplasari nec


spre stanga si spre dreapta, se alege directia in care deplasarea se va face intr-u
minim de pasi.
In calcularea numarului de deplasari se tine cont de miscarea circulara a manerului
In cazul in care cele doua numere sunt egale, se alege directia dreapta.

Daca numarul citit avea zerouri la sfarsitul numarului, se determina numarul de dep
necesare afisarii acestora si se introduc in roboprogram un numar de instructiuni A
numarul de zerouri calculate.

4.2.2 Cod surs 

Listing 4.2.1: robot_cerchez.cpp

1 //Em. Cerchez 90 puncte


2 #include <fstream>
3
4 using namespace std;
5
6 ifstream fin("robot.in");
7 ofstream fout("robot.out");
CAPITOLUL 4. OJI 2017 60

8
9 int cerinta, n;
10
11 int main()
12 {
13 char c;
14 int nr, st, dr, poz, zero, cat, cifra;
15
16 fin>>cerinta;
17
18 if(cerinta==1)
19 {
20 c=’*’; nr=0;
21 while (c!=’T’)
22 {
23 fin>>c;
24 if (c==’A’) nr++;
25 }
26 fout<<nr<<’\n’;
27 fout.close();
28 return 0;
29 }
30
31 if(cerinta==2)
32 {
33 c=’*’; nr=0; poz=0;
34 while (c!=’T’)
35 {
36 fin>>c;
37 if (c==’A’) fout<<poz;
38 else
39 if (c==’D’)
40 {
41 fin>>c;
42 cat=c-’0’;
43 poz=(poz+cat)%10;
44 }
45 else
46 if (c==’S’)
47 {
48 fin>>c;
49 cat=c-’0’;
50 poz-=cat;
51 if(poz<0) poz+=10;
52 }
53 }
54 fout<<’\n’;
55 fout.close();
56 return 0;
57 }
58
59 fin>>n;
60
61 if (n==0){fout<<"AT\n"; fout.close(); return 0; }
62 zero=0;
63 while (n%10==0) {zero++;n/=10;}
64 nr=0;
65 while (n) {nr=nr*10+n%10; n/=10;}
66
67 //obtin nr
68 poz=0;
69 while (nr)
70 {
71 cifra=nr%10; nr/=10;
72 if (cifra!=poz)
73 {
74 if (cifra<poz)
75 {
76 st=poz-cifra;
77 dr=10+cifra-poz;
78 }
79 else
80 {
81 dr=cifra-poz;
82 st=10+poz-cifra;
83 }
CAPITOLUL 4. OJI 2017 61

84 if (st<dr)
85 fout<<"S"<<st;
86 else
87 fout<<"D"<<dr;
88 }
89 poz=cifra;
90 fout<<"A";
91 }
92
93 if (zero)
94 {
95 if (poz)
96 {
97 dr=10-poz; st=poz;
98 if (st<dr)
99 fout<<"S"<<st;
100 else
101 fout<<"D"<<dr;
102 }
103 while (zero) {fout<<"A"; zero--;}
104 }
105 fout<<"T\n";
106 fout.close();
107 return 0;
108 }

Listing 4.2.2: robot_cerchez_ok.cpp

1 //Em. Cerchez 90 puncte


2 #include <fstream>
3
4 using namespace std;
5
6 ifstream fin("robot.in");
7 ofstream fout("robot.out");
8
9 int cerinta, n;
10
11 int main()
12 {
13 char c;
14 int nr, st, dr, poz, zero, cat, cifra;
15 fin>>cerinta;
16 if (cerinta==1)
17 {
18 c=’*’; nr=0;
19 while (c!=’T’)
20 {
21 fin>>c;
22 if (c==’A’) nr++;
23 }
24 fout<<nr<<’\n’;
25 fout.close();
26 return 0;
27 }
28
29 if (cerinta==2)
30 {
31 c=’*’; nr=0; poz=0;
32 while (c!=’T’)
33 {
34 fin>>c;
35 if (c==’A’) fout<<poz;
36 else
37 if (c==’D’)
38 {
39 fin>>c;
40 cat=c-’0’;
41 poz=(poz+cat)%10;
42 }
43 else
44 if (c==’S’)
45 {
46 fin>>c;
47 cat=c-’0’;
CAPITOLUL 4. OJI 2017 62

48 poz-=cat;
49 if(poz<0) poz+=10;
50 }
51 }
52 fout<<’\n’;
53 fout.close();
54 return 0;
55 }
56
57 fin>>n;
58 if (n==0){fout<<"AT\n"; fout.close(); return 0; }
59 zero=0;
60 while (n%10==0) {zero++;n/=10;}
61 nr=0;
62 while (n) {nr=nr*10+n%10; n/=10;}
63
64 //obtin nr
65 poz=0;
66 while (nr)
67 {
68 cifra=nr%10; nr/=10;
69 if (cifra!=poz)
70 {
71 if (cifra<poz)
72 {
73 st=poz-cifra;
74 dr=10+cifra-poz;
75 }
76 else
77 {
78 dr=cifra-poz;
79 st=10+poz-cifra;
80 }
81 fout<<"D"<<dr;
82 }
83 poz=cifra;
84 fout<<"A";
85 }
86
87 if (zero)
88 {
89 if (poz)
90 {
91 dr=10-poz; st=poz;
92 fout<<"D"<<dr;
93 }
94 while (zero) {fout<<"A"; zero--;}
95 }
96 fout<<"T\n";
97 fout.close();
98 return 0;
99 }

Listing 4.2.3: robot_jakab.cpp

1 //Jakab Tunde
2 #include <iostream>
3 #include <fstream>
4 #include <stdlib.h>
5
6 using namespace std;
7
8 int main()
9 {
10 ifstream in("robot.in");
11 ofstream out("robot.out");
12 char c;
13 int a=0,b=0,n=0,m=0,z=0,e,d,p;
14 in>>p;
15
16 if(p==1)
17 {
18 while(!in.eof())
19 {
20 in>>c;
CAPITOLUL 4. OJI 2017 63

21 if (c==’A’)a++;
22 }
23 out<<a<<endl;
24 }
25
26 if(p==2)
27 {
28 in>>c;
29 b=0;
30 while(c!=’T’)
31 {
32 if (c==’D’)
33 {
34 in>>c;
35 a=c-48;
36 b=(b+a)%10;
37 }
38 else
39 if (c==’S’)
40 {
41 in>>c;
42 a=c-48;
43 b=(b+10-a)%10;
44 }
45 if(c==’A’) out<<b;
46 in>>c;
47 }
48 }
49
50 if(p==3)
51 {
52 in>>a;
53 if(a==0)out<<"A";
54 else
55 if(a<10)
56 {
57 if(10-a<a)
58 out<<’S’<<10-a<<’A’;
59 else
60 out<<’D’<<a<<’A’;
61 }
62 else
63 {
64 z=0;
65 while(a%10==0)
66 {
67 z++;
68 a=a/10;
69 }
70 while(a!=0)
71 {
72 b=b*10+a%10;
73 a=a/10;
74 }
75
76 a=b;
77 b=a%10;
78 if(10-b<b)
79 out<<’S’<<10-b<<’A’;
80 else
81 out<<’D’<<b<<’A’;
82 a=a/10;
83 while(a!=0)
84 {
85 if(b==a%10)
86 out<<’A’;
87 else
88 if(b>a%10)
89 if(10-b+a%10<=b-a%10)
90 out<<’D’<<10-b+a%10<<’A’;
91 else
92 out<<’S’<<b-a%10<<’A’;
93 else
94 if(10-a%10+b<a%10-b)
95 out<<’S’<<10-a%10+b<<’A’;
96 else
CAPITOLUL 4. OJI 2017 64

97 out<<’D’<<a%10-b<<’A’;
98 b=a%10;
99 a=a/10;
100 }
101
102 if(z!=0)
103 {
104 if(10-b<b)
105 out<<’D’<<b;
106 else
107 out<<’S’<<b;
108 while(z!=0)
109 {
110 out<<’A’;
111 z--;
112 }
113 }
114 }
115
116 out<<’T’;
117 }
118 in.close();
119 out.close();
120 return 0;
121 }

4.2.3 *Rezolvare detaliat 


Capitolul 5

OJI 2016

5.1 colier
Problema 1 - colier 90 de
puncte
Maria are în camera sa N m rgele a³ezate una lâng  alta. Pe ecare dintre ele este scris un
num r natural format din cifre nenule distincte. Pentru ecare m rgea, Maria ³terge num rul ³i
în locul s u scrie altul, având doar dou  cifre, respectiv cifra minim  ³i cifra maxim  din num rul
scris iniµial, în ordinea în care aceste cifre ap reau înainte de ³tergere. Acum Maria consider  c 
m rgelele sunt de dou  tipuri, în funcµie de num rul de dou  cifre scris pe ele: tipul 1 (cele care
au cifra zecilor mai mic  decât cifra unit µilor) ³i tipul 2 (celelalte). Folosind m rgelele, fetiµa
dore³te ca prin eliminarea unora dintre ele (dar f r  s  le schimbe ordinea celorlalte) s  obµin 
un colier circular cât mai lung care s  respecte proprietatea c  oricare dou  m rgele vecine ale
sale sunt de tipuri diferite. În colierul format cu m rgelele r mase dup  eliminare se consider  c 
prima m rgea este vecin  cu ultima.

Cerinµe
1) determinaµi num rul de m rgele de tipul 1;
2) determinaµi num rul maxim de m rgele pe care le poate avea colierul;

Date de intrare
Fi³ierul colier.in conµine pe prima linie un num r natural T . Pe linia a doua se g se³te un
num r natural N. Pe linia a treia sunt N numere naturale ce reprezint , în ordine, valorile scrise
iniµial pe m rgele. Aceste numere sunt separate prin câte un spaµiu.

Date de ie³ire
Dac  valoarea lui T este 1, se va rezolva numai punctul 1) din cerinµe. În acest caz, ³ierul de
ie³ire colier.out va conµine pe prima linie un num r natural reprezentând r spunsul la cerinµa 1).
Dac  valoarea lui T este 2, se va rezolva numai punctul 2) din cerinµe. În acest caz, ³ierul de
ie³ire colier.out va conµine pe prima linie un num r natural reprezentând r spunsul la cerinµa 2).
Restricµii ³i preciz ri
a 1&N & 50000;
a Numerele scrise iniµial pe m rgele au cifrele distincte, nu conµin cifra 0 ³i sunt cuprinse între
12 ³i987654321;
a T va  1 sau 2;
a Pentru obµinerea colierului, Maria poate decide s  nu elimine nicio m rgea;
a Colierul obµinut poate  format ³i dintr-o singur  m rgea;
a Pentru teste în valoare de 20 de puncte avem T 1 ³i toate numerele scrise iniµial pe m rgele
au dou  cifre;
a Pentru teste în valoare de 30 de puncte avem T 1 ³i dintre numerele scrise iniµial pe
m rgele sunt ³i unele cu mai mult de dou  cifre;
a Pentru teste în valoare de 50 de puncte avem T 2.

65
CAPITOLUL 5. OJI 2016 66

Exemple
colier.in colier.out Explicaµii
1 3 Numerele scrise de Maria pe m rgele vor , în ordine: 12 68 31
5 24 93. Trei dintre ele (12, 68 ³i 24) sunt de tipul 1. (T ind 1
12 678 312 24 938 se rezolv  doar cerinµa 1).
2 4 Numerele scrise de Maria pe m rgele vor , în ordine: 12 68 31
5 24 93. Eliminând m rgeaua de pe poziµia 1 sau pe cea de pe
12 678 312 24 938 poziµia 2 ³i a³ezându-le pe celelalte circular obµinem un colier cu
4 m rgele în care oricare dou  vecine sunt de tipuri diferite. (T
ind 2 se rezolv  doar cerinµa 2). Maria este obligat  s  elimine
una din cele dou  m rgele, altfel ar exista m rgele vecine de
acela³i tip.

Timp maxim de executare/test: 0.5 secunde


Memorie: total 32 MB
Dimensiune maxim  a sursei: 15 KB

5.1.1 Indicaµii de rezolvare

prof. Marius Nicoli, C.N. Fratii Buze³ti, Craiova

Prima cerinµ  se rezolv  prin aplicarea pentru ecare num r a algoritmului de parcurgere a
cifrelor sale, identicând cifra maxim  si cea minim  a sa, precum ³i poziµiile lor.

Pentru cerinµa a doua, determin m câte secvenµe maximale formate din valori de acela³i tip
exist . Dac  prima ³i ultima secvenµ  sunt formate din acela³i tip de m rgele, sc dem 1 din
valoarea dererminat  anterior.

Ambele cerinµe se rezolv  procesând numerele în momentul citirii, deci f r  a  necesare tablouri
de memorie.

5.1.2 Cod surs 

Listing 5.1.1: colier_gina.cpp

1 #include<fstream>
2
3 using namespace std;
4
5 ifstream f("colier.in");
6 ofstream g("colier.out");
7
8 int main()
9 {
10 int x,P,M,p,m,poz=0,n,t,s=0,a,b,k=1;
11
12 f>>t>>n;
13 f>>x;
14
15 poz=0;
16 m=10;
17 M=-1;
18 while(x)
19 {
20 poz++;
21 if(x%10>M)
22 {
23 M=x%10;
24 P=poz;
25 }
26 if(x%10<m)
27 {
28 m=x%10;
29 p=poz;
30 }
CAPITOLUL 5. OJI 2016 67

31 x=x/10;
32 }
33
34 s+=(1+(p<P))==1;
35 a=1+(p<P);
36 for(int i=2;i<=n;i++)
37 {
38 f>>x;
39 poz=0;
40 m=10;
41 M=-1;
42 while(x)
43 {
44 poz++;
45 if(x%10>M)
46 {
47 M=x%10;
48 P=poz;
49 }
50 if(x%10<m)
51 {
52 m=x%10;
53 p=poz;
54 }
55 x=x/10;
56 }
57
58 s+=(1+(p<P))==1;
59 b=1+(p<P);
60 if(a!=b)
61 {
62 k++;
63 a=b;
64 }
65 }
66 if(k%2)k--;
67
68 if(t==1)
69 g<<s<<’\n’;
70 else
71 g<<k<<’\n’;
72 f.close();
73 g.close();
74 return 0;
75 }

Listing 5.1.2: colier_Marius.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 int n, i, x, c, maxim, minim, nr, pmaxim, pminim, tip, tipa, sol1, sol2, first, t;
6
7 int main ()
8 {
9 ifstream fin ("colier.in");
10 ofstream fout("colier.out");
11
12 fin>>t>>n;
13 sol2 = 1;
14 for(i=1;i<=n;i++)
15 {
16 fin>>x;
17 maxim = 0;
18 minim = 9;
19 nr = 0;
20 while(x != 0)
21 {
22 c = x % 10;
23 nr++;
24 if(c > maxim)
25 {
26 maxim = c;
27 pmaxim = nr;
CAPITOLUL 5. OJI 2016 68

28 }
29 if(c < minim)
30 {
31 minim = c;
32 pminim = nr;
33 }
34 x /= 10;
35 }
36
37 if(pmaxim < pminim)
38 {
39 tip = 1;
40 sol1++;
41 }
42 else
43 {
44 tip = 2;
45 }
46 if(i == 1)
47 first = tip;
48 else
49 {
50 if (tip != tipa)
51 {
52 sol2++;
53 }
54 }
55 tipa = tip;
56 }
57
58 if (tip == first)
59 sol2--;
60
61 if (t == 1)
62 fout<<sol1<<"\n";
63 else
64 {
65 if (sol1 == n || sol1 == 0)
66 fout<<"1\n";
67 else
68 fout<<sol2<<"\n";
69 }
70 return 0;
71 }

Listing 5.1.3: colier_Miana.cpp

1 #include<fstream>
2
3 using namespace std;
4
5 ifstream f("colier.in");
6 ofstream g("colier.out");
7
8 int main()
9 {
10 int n, nr=1, tip1=0, tip2=0,x,c,u,k=0,cmin=10,cmax=0,pcmin,pcmax,p,i,t;
11 f>>t>>n>>x;
12
13 while (x)
14 {
15 c=x%10;
16 k++;
17 if (c<cmin) { cmin=c; pcmin=k; }
18 if (c>cmax) { cmax=c; pcmax=k; }
19 x/=10;
20 }
21
22 if (pcmin>pcmax) { tip1++; u=p=1; }
23 else { tip2++; u=p=2; }
24
25 for (i=2; i<=n; i++)
26 {
27 f>>x;
28 k=0; cmin=10; cmax=0;
CAPITOLUL 5. OJI 2016 69

29
30 while (x)
31 {
32 c=x%10;
33 k++;
34 if (c<cmin) { cmin=c; pcmin=k; }
35 if (c>cmax) { cmax=c; pcmax=k; }
36 x/=10;
37 }
38
39 if (pcmin>pcmax)
40 {
41 tip1++;
42 if (u!=1) {nr++; u=1;}
43 }
44 else
45 {
46 tip2++;
47 if (u!=2) {nr++; u=2;}
48 }
49 }
50
51 if (u==p) nr--;
52 if (t==1)
53 g<<tip1<<’\n’;
54 else
55 g<<nr<<’\n’;
56
57 return 0;
58 }

Listing 5.1.4: colier_sanda.cpp

1 #include <iostream>
2 #include <fstream>
3
4 using namespace std;
5
6 ifstream f("colier.in");
7 ofstream out("colier.out");
8
9 int main()
10 {
11 int n,m,x,y,a,b,c,T,maxim,minim,maxi,mini,tipa,tipb,tipul,tip1=0,i,k;
12
13 ifstream in("colier.in");
14
15 in>>T;
16 in>>n;m=n;
17 in>>a;
18 y=a; maxim=0; maxi=0; minim=999999999; mini=0, k=0;
19 while(y)
20 {
21 c=y%10;k++;
22 if(c>maxim)
23 maxim=c,maxi=k;
24 if(c<minim)
25 minim=c,mini=k;
26 y/=10;
27 }
28
29 if(mini>maxi)
30 tip1++,tipa=1;
31 else
32 tipa=2;
33
34 tipul=tipa;
35 // cout<<"a="<<a<<endl;
36 // cout<<"*"<<n<<" "<<tip1<<" "<<tipa<<endl;
37
38 for(i=2;i<=m;i++)
39 {
40 in>>b; // cout<<"b="<<b<<endl;
41 y=b;maxim=0;maxi=0;minim=999999999; mini=0;k=0;
42 while(y)
CAPITOLUL 5. OJI 2016 70

43 {
44 c=y%10;k++;
45 if(c>maxim) maxim=c, maxi=k;
46 if(c<minim) minim=c, mini=k;
47 y/=10;
48 }
49 if(mini>maxi)
50 tip1++,tipb=1;
51 else
52 tipb=2;
53 if(tipa==tipb) n--;
54 //cout<<"!"<<n<<" "<<tip1<<" "<<tipb<<endl;
55 a=b,tipa=tipb;
56 }
57
58 if(tipb==tipul) n--;
59 // cout<<"*"<<n<<" "<<tip1<<" "<<tipb<<" "<<tipul<<endl;
60 if(T==1)
61 out<<tip1;
62 else
63 out<<n;
64
65 return 0;
66 }

5.1.3 *Rezolvare detaliat 

5.2 Palindrom
Problema 2 - Palindrom 90 de
puncte
Un num r se nume³te palindrom dac  prima lui cifr  este egal  cu ultima, a doua cu penultima
³i a³a mai departe. De exemplu numerele 1221, 505 ³i 7 sunt palindromuri, în vreme ce 500, 1410
³i 2424 nu sunt palindromuri.
Similar, un num r se nume³te aproape palindrom dac  are acelea³i perechi de cifre identice
ca un palindrom, mai puµin o pereche în care cifrele difer . De exemplu numerele 500, 1411,
2444, 1220, 53625, 14 ³i 4014 sunt numere aproape palindromuri (cu perechea de cifre neidentice
îngro³at ), în vreme ce 1221, 1410, 6, 505, 22 ³i 512125 nu sunt numere aproape palindromuri
deoarece e sunt palindromuri, e au prea multe perechi de cifre diferite.
Mai denim palindromul asociat al unui num r x ca ind cel mai mic num r palindrom p
strict mai mare decât x (p % x). De exemplu palindromul asociat al lui 5442 este 5445, palindromul
asociat al lui 2445 este 2552, al lui 545 este 555, al lui 39995 este 40004, al lui 500 este 505, iar al
lui 512125 este 512215.

Cerinµe
Scrieµi un program care citind un num r natural nenul n ³i apoi un ³ir de n numere naturale
determin :
1. câte dintre cele n numere sunt palindrom
2. câte dintre cele n numere sunt aproape palindrom
3. palindromurile asociate pentru cele n numere citite.

Date de intrare
Fi³ierul de intrare palindrom.in conµine pe prima linie un num r C . Pentru toate testele, C
poate lua numai valorile 1, 2 sau 3. Pe a doua linie se a  num rul n, iar pe a treia linie cele n
numere naturale desp rµite prin câte un spaµiu.

Date de ie³ire
Fi³ierul de ie³ire palindrom.out:
a dac  C 1, va conµine un singur num r natural reprezentând num rul de numere palindrom
din ³ir
CAPITOLUL 5. OJI 2016 71

a dac  C 2, va conµine num rul de numere din ³ir care sunt aproape palindrom
a dac  C 3, va conµine numerele palindrom asociate celor n numere din ³ir, separate prin
câte un spaµiu

Restricµii ³i preciz ri
a 1 & n & 10000
a 1 & numerele din ³ir & 2000000000
a Pentru rezolvarea corect  a primei cerinµe se acord  20 de puncte, pentru rezolvarea corect 
a celei de a doua cerinµe se acord  30 de puncte, iar pentru rezolvarea corect  a celei de a treia
cerinµe se acord  50 de puncte.

Exemple
palindrom.in palindrom.out
1 5
7
1221 500 53635 505 7 4004 1410
Explicaµie: Cele 5 numere palindrom sunt 1221, 53635, 505, 7 ³i 4004
(C ind 1, se rezolv  doar prima cerinµ ).
2 3
4
5442 2445 545 39995
Explicaµie: Cele 3 numere aproape palindrom sunt 5442, 2445 ³i 39995
(C ind 2, se rezolv  doar a doua cerinµ ).
3 7 1441 2552 1331 515 1221 53635 22 4114 1441 33
11
6 1411 2444 1221 505 1220 53625 14 4014 1410 22
Explicaµie: Palindromul asociat lui 6 este 7, al lui 1411 este 1441, al lui 2444 este 2552 etc.
(C ind 3, se rezolv  doar a treia cerinµ ).

Timp maxim de executare/test: 0.5 secunde


Memorie: total 32MB
Dimensiune maxim  a sursei: 15 KB

5.2.1 Indicaµii de rezolvare

autor Cristian Francu

Cerinta 1
Punctul 1 al problemei este relativ banal, cerand sa spunem cate numere palindrom exista
intr-un sir de numere. Cu toate acestea trebuie avut grija deoarece algoritmul standard calculeaza
rasturnatul numarului, care poate sa depaseasca valoarea maxima a unui intreg, de circa doua
miliarde (de exemplu numarul 1234554327). Pentru a nu depasi intregul putem proceda in mai
multe moduri:

1. Putem sa extragem cifrele din capetele opuse ale numarului, spre a le compara, iar apoi le
eliminam. Pentru aceasta vom calcula p10, puterea maxima a lui 10 care este mai mica sau egala
cu numarul nostru, x. Apoi avem:

prima_cifra = x / p10;
ultima_cifra = x % 10;
x = x % p10 / 10;
p10 = p10 / 100;

2. Putem sa rasturnam numarul doar pana la jumatatea sa. Facem acest lucru la fel ca in
algoritmul clasic, adaugand cifrele de la coada lui x la coada lui y, cu diferenta ca ne vom opri
atunci cand x <= y.
CAPITOLUL 5. OJI 2016 72

Cerinta 2
Cerinta 2 se rezolva similar cu punctul 1, numai ca de data aceasta vom numara cate diferente
avem intre perechile de cifre. Cu algoritmul clasic rasturnam numarul x in y si apoi extragem pe
rand cifre din coada ambelor numere calculand cate perechi diferite avem.
Daca numarul de perechi diferite este 0, numarul este palindrom, iar daca este 2 atunci numarul
este aproape palindrom.
Avem aceeasi problema insa, ca si la punctul 1, anume pe anumite numere vom depasi intregul.
Pentru a nu depasi putem iar aplica metodele descrise la punctul 1.

Cerinta 3
Punctul 3 al problemei se reduce la a calcula pentru un numar x cel mai mic palindrom strict
mai mare ca x. Putem rezolva direct, incrementand x si testand daca este palindrom, avand grija
la depasire. Aceasta metoda este destul de lenta si va depasi timpul la cateva teste. O metoda
mai rapida este urmatoarea:

Vom porni cu numarul x x  1 si vom calcula cel mai mic palindrom mai mare sau egal cu x.
Pentru aceasta calculam y , simetrizarea lui x, ca ind copierea primei jumatati in cea de-a
doua, rasturnata. De exemplu pentru 123456 vom calcula 123321, iar pentru 4066345 vom calcula
4066604. Daca palindromul calculat, y , este mai mare sau egal cu x, atunci el este chiar raspunsul.
Altfel, daca este mai mic, va trebui sa calculam numarul z caruia i se aduna unu la ultima cifra
dinainte de jumatatea a doua a numarului. Daca simetrizam z vom obtine raspunsul.

5.2.2 Cod surs 

Listing 5.2.1: palindrom_Marius.cpp

1 #include <fstream>
2 #include <cstring>
3
4 using namespace std;
5
6 char s[12];
7 int t, n, i, j, k, t1, t2, nr;
8
9
10 int main ()
11 {
12 ifstream fin("palindrom.in");
13 ofstream fout("palindrom.out");
14
15 fin>>t>>n;
16
17 for (i=1;i<=n;i++)
18 {
19 fin>>s;
20 int nr = 0;
21 for (j=0, k=strlen(s)-1; j<k; j++, k--)
22 {
23 if (s[j] != s[k]) nr++;
24 }
25 if (nr == 0) t1++;
26 if (nr == 1) t2++;
27
28 if (t == 3)
29 {
30 int number = 0;
31 int noua = 1;
32 for (j=0;s[j]!=0;j++)
33 {
34 if (s[j] != ’9’) { noua = 0; }
35 number = number*10 + s[j] - ’0’;
36 }
37 if (noua)
38 {
39 fout<<1;
40 for (j=0;s[j+1]!=0;j++) fout<<0;
41 fout<<"1 ";
42 continue;
CAPITOLUL 5. OJI 2016 73

43 }
44
45 if (strlen(s) % 2 == 0)
46 {
47 int left = 0;
48 for (j=0;j<strlen(s)/2;j++)
49 left = left * 10 + s[j] - ’0’;
50 int auxleft = left;
51 int rez = left;
52 while (left != 0)
53 {
54 rez = rez * 10 + left % 10;
55 left /= 10;
56 }
57 if (rez > number)
58 {
59 fout<<rez<<" ";
60 continue;
61 }
62 else
63 {
64 left = auxleft + 1;
65 rez = left;
66 while (left != 0)
67 {
68 rez = rez * 10 + left % 10;
69 left /= 10;
70 }
71 fout<<rez<<" ";
72 continue;
73 }
74 }
75 else
76 {
77 int left = 0;
78 for (j=0;j<=strlen(s)/2;j++)
79 left = left * 10 + s[j] - ’0’;
80 int auxleft = left;
81 int rez = left;
82 left /= 10;
83 while (left != 0)
84 {
85 rez = rez * 10 + left % 10;
86 left /= 10;
87 }
88 if (rez > number)
89 {
90 fout<<rez<<" ";
91 continue;
92 }
93 else
94 {
95 left = auxleft + 1;
96 rez = left;
97 left /= 10;
98 while (left != 0)
99 {
100 rez = rez * 10 + left % 10;
101 left /= 10;
102 }
103 fout<<rez<<" ";
104 continue;
105 }
106 }
107 }
108 }
109
110 if (t == 1) fout<<t1<<"\n";
111 if (t == 2) fout<<t2<<"\n";
112 return 0;
113 }

Listing 5.2.2: palindrom_Sanda.cpp

1 #include <iostream>
CAPITOLUL 5. OJI 2016 74

2 #include <fstream>
3
4 using namespace std;
5
6 ifstream in("palindrom.in");
7 ofstream out("palindrom.out");
8
9 int main()
10 {
11 int c,n,i,j,k,d=1, nrap=0,nrpal=0;
12 long long x,y,z=0,a,b;
13
14 in>>c;
15 in>>n;
16
17 for(i=1;i<=n;i++)
18 {
19 in>>x;
20 y=x;
21 z=k=0;
22 while(y)
23 {
24 z=z*10+y%10;
25 k++;
26 y/=10;
27 }
28 if(c==1)
29 {
30 if(x==z) nrpal++;
31 }
32 else
33 if(c==2)
34 {
35 a=x,b=z,d=0;
36 while(a && d<=2){
37 if(a%10!=b%10) d++;
38 a/=10,b/=10;
39 }
40 if(d==2)
41 nrap++;
42 }
43 else
44 {
45 int m=1,prim,ultim;
46 for(j=1;j<=k/2;j++) m*=10;
47
48 y=x/m*m+z%m;
49 if(y<=x)
50 {
51 if(k%2==0)
52 a=b=(x/m+1);
53 else
54 a=b=(x/m+1)/10;
55 z=0;
56 while(b)
57 {
58 z=z*10+b%10;
59 b=b/10;
60 }
61 y=(x/m+1)*m+z;
62 }
63 out<<y<<’ ’;
64 }
65 }
66 if(c==1) out<<nrpal;
67 else
68 if(c==2) out<<nrap;
69
70 return 0;
71 }

5.2.3 *Rezolvare detaliat 


Capitolul 6

OJI 2015

6.1 Cuart
Problema 1 - Cuart 100 de puncte
Gina ³i Mihai joac  împreun  jocul Cuart. Ei au la dispoziµie un ³ir de 2˜N cartona³e ce conµin
numere naturale. Primele N cartona³e, de la stânga la dreapta, sunt ale Ginei, iar urm toarele
N ale lui Mihai. Gina travereseaz  ³irul, de la stânga la dreapta ³i scrie pe o foaie de hârtie, pe
primul rând, un ³ir de numere obµinut din numerele de pe cartona³ele sale, din care a ³ters toate
cifrele pare. La fel procedeaz  Mihai care scrie pe foaia sa de hârtie, pe primul rând, ³irul de
numere obµinut din numerele de pe cartona³ele sale, din care a ³ters toate cifrele impare. Dac 
dintr-un num r s-au ³ters toate cifrele, sau au r mas doar cifre egale cu 0, atunci num rul este
ignorat, deci pe hârtie nu se scrie nimic.
Fiecare copil, noteaz  pe hârtia sa, pe al doilea rând, un alt ³ir de numere obµinut astfel:
pentru ecare num r X scris pe primul rând, copilul va scrie cel mai mare num r natural K cu
proprietatea c  1  5  9  13  ...  K & X. În jocul copiilor, num rul X se nume³te cuarµ dac 
1  5  9  13  ...  K X .

Figura 6.1: Cuart

În exemplul de mai sus, Gina nu a scris niciun num r cuarµ pe primul rând, iar Mihai a scris
unul singur (6=1+5). Regulile de câ³tig ale jocului sunt urm toarele:
a Câ³tig  acel copil care are scrise pe primul rând cele mai multe numere cuarµ. În acest caz,
valoarea de câ³tig a jocului este egal  cu num rul de numere cuarµ scrise de copilul câ³tig tor.
a Dac  cei doi copii au scris acela³i num r de numere cuarµ, atunci va câ³tiga cel care are primul
num r scris pe primul rând, mai mare decât al celuilalt. Acest prim num r scris de câ³tig tor va
reprezenta valoarea de câ³tig.
a Dac  nici Gina ³i nici Mihai nu au scris niciun num r pe hârtie, se consider  egalitate ³i nu
câ³tig  niciunul.

Cerinµe
Scrieµi un program care s  citeasc  num rul N reprezentând num rul de cartona³e ale unui
copil ³i cele 2˜N numere de pe cartona³e, în ordine de la stânga la dreapta ³i care s  determine:
1) Cel mai mare num r de pe cele 2˜N catona³e, pentru care nu s-a scris niciun num r pe
primul rând (a fost omis), nici pe hârtia Ginei, nici pe hârtia lui Mihai; dac  nu a fost omis niciun
num r, se va scrie 0;
2) Câ³tig torul jocului ³i a³eaz  num rul 1 dac  a câ³tigat Gina, 2 pentru Mihai sau 0 în caz
de egalitate.
3) Valoarea de câ³tig a jocului, sau 0, în caz de egalitate.

Date de intrare

75
CAPITOLUL 6. OJI 2015 76

Fi³ierul de intrare cuart.in conµine pe prima linie un num r natural P . Pentru toate testele
de intrare, num rul P poate avea doar valoarea 1, valoarea 2 sau valoarea 3. Pe a doua linie a
³ierului de intrare cuart.in se g se³te num rul natural N reprezentând num rul de cartona³e
ale ec rui copil ³i pe a treia linie, în ordine de la stânga la dreapta, numerele de pe cele 2˜N
cartona³e, separate prin câte un spaµiu.

Date de ie³ire
Dac  valoarea lui P este 1, se va rezolva numai punctul 1) din cerinµe. În acest caz, ³ierul de
ie³ire cuart.out va conµine pe prima linie un num r natural reprezentând r spunsul la cerinµa 1).
Dac  valoarea lui P este 2, se va rezolva numai punctul 2) din cerinµe. În acest caz, ³ierul de
ie³ire cuart.out va conµine pe prima linie un num r natural reprezentând r spunsul la cerinµa 2).
Dac  valoarea lui P este 3, se va rezolva numai punctul 3) din cerinµe. În acest caz, ³ierul de
ie³ire cuart.out va conµine pe prima linie un num r natural reprezentând r spunsul la cerinµa 3).
Restricµii ³i preciz ri
a 1 & N & 1000
a 1 & numerele de pe cartona³e $ 100000000
a Pentru rezolvarea corect  a primei cerinµe se acord  20 de puncte, pentru rezolvarea corect 
a celei de a doua cerinµe se acord  30 de puncte, pentru rezolvarea corect  a celei de a treia cerinµe
se acord  50 de puncte.

Exemple
cuart.in cuart.out Explicaµii
1 284260 P = 1, pentru acest test, se rezolv  cerinµa 1).
4 Gina a scris pe hârtia sa, pe dou  rânduri nume-
1234 48 284260 75 756 1232515 153 98 rele:
13 75
5 21
Mihai a scris pe hârtie numerele:
6 22 8
5 9 5
Cel mai mare num r omis este 284260
2 2 P = 2, pentru acest test, se rezolv  cerinµa 2). A
4 câ³tigat Mihai deoarece are un num r cuarµ, iar
1234 48 284260 75 756 1232515 153 98 Gina niciunul.
3 28 P = 3, pentru acest test, se rezolv  cerinµa 3).
1 Gina a scris pe hârtia sa, pe dou  rânduri nume-
154 2181 rele:
15
9
Mihai a scris pe hârtie numerele:
28
13
Ambii copii au scris câte un num r cuarµ, îns 
a câ³tigat Mihai care are primul num r scris pe
primul rând mai mare decât al Ginei. Valoarea
de câ³tig a jocului este 28.

Timp maxim de executare/test: 1.0 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 5 KB

6.1.1 Indicaµii de rezolvare

Pentru primele N cartonase:


* se citeste, pe rand, cate un numar (cartonas) si se sterg cifrele sale pare. Daca numarul
ramas X este diferit de 0, atunci:

ˆ daca este primul, il salvez intr-o variabila


CAPITOLUL 6. OJI 2015 77

ˆ caut kmax cu proprietatea ca 1+5+9+...+k <= X. Cautarea luik se poate face cu ajutorul
unei formule (1+5+9+...+(4M+1) = (M+1)(2M+1), unde k =4M+1) sau prin calcularea
efectiva a sumei

ˆ daca obtinem egalitate in relatia anterioara, atunci marim numarul de numere cuart ale
Ginei cu 1

Pentru urmatoarele N cartonase se repeta pasii anteriori cu modicarea aferenta.

6.1.2 Cod surs 

Listing 6.1.1: cuart_dl.cpp

1 #include <cstdio>
2 #include <algorithm>
3 #include <cassert>
4
5 #define MRD 99999999
6
7 using namespace std;
8
9 int K, N, A, B, N1, N2, Nr, P, first1, first2,
10 cuart1, cuart2, Max, i, Sum, t, p, x,X, cx, d, u, nr;
11 bool ok;
12
13 int main()
14 {
15 freopen("cuart.in", "r",stdin);
16 freopen("cuart.out","w",stdout);
17
18 scanf("%d\n%d",&P, &N);
19 assert(N<=1000 && N>=1 && P>0 && P<4);
20
21 first1=cuart1=0;
22
23 for(int i=1; i<=N; i++)
24 {
25 scanf("%d",&X);
26 assert(X<100000000 && X>0);
27
28 p=1; x=0; cx=X;
29 while(cx)
30 {
31 if(cx%2) {x=x + cx%10 *p; p*=10;}
32 cx/=10;
33 }
34
35 if(x)
36 {
37 if(!first1) first1=x;
38 Sum=0; t=1;
39 while (Sum + t <= x)
40 {
41 Sum+=t;
42 t+=4;
43 }
44 if(Sum==x) cuart1++;
45 }
46 else Max=max(X, Max);
47 }
48
49 first2=cuart2=0;
50 for(int i=1; i<=N; i++)
51 {
52 scanf("%d",&X);
53 assert(X<100000000 && X>0);
54
55 p=1; x=0; cx=X;
56 while(cx)
57 {
58 if(cx%2==0) {x=x + cx%10 *p; p*=10;}
59 cx/=10;
CAPITOLUL 6. OJI 2015 78

60 }
61
62 if(x)
63 {
64 if(!first2) first2=x;
65 Sum=0; t=1;
66 while (Sum + t <= x)
67 {
68 Sum+=t;
69 t+=4;
70 }
71 if(Sum==x) cuart2++;
72 }
73 else Max=max(X, Max);
74 }
75
76 if(P==1)
77 printf("%d\n", Max);
78 else
79 {
80 if(cuart1>cuart2)
81 {
82 if (P==2) printf("1\n"); else printf("%d\n",cuart1);
83 }
84 else
85 if(cuart1<cuart2)
86 {
87 if (P==2) printf("2\n"); else printf("%d\n", cuart2);
88 }
89 else
90 if(first1==0 && first2 ==0)
91 {
92 if (P==2) printf("0\n"); else printf("%d\n", 0);
93 }
94 else
95 if (first1>first2)
96 {
97 if (P==2) printf("1\n"); else printf("%d\n",first1);
98 }
99 else
100 {
101 if (P==2) printf("2\n"); else printf("%d\n",first2);
102 }
103 }
104 return 0;
105 }

Listing 6.1.2: cuart_dt.cpp

1 #include <fstream>
2 #include<math.h>
3
4 using namespace std;
5
6 ifstream f("cuart.in");
7 ofstream g("cuart.out");
8
9 int n,x;
10
11 int main()
12 {
13 int i,max1=0,p=1,nr=0,y,q1=0,q2=0,k,s,
14 prim1=0, prim2=0,max2=0,nr1=0,nr2=0,P;
15
16 f>>P>>n;
17
18 for(i=1; i<=n; i++)
19 {
20 f>>x;
21 y=x;
22 while(x!=0)
23 {
24 if(x%10%2)
25 {
26 nr=nr+x%10*p;
CAPITOLUL 6. OJI 2015 79

27 p=p*10;
28 }
29 x=x/10;
30 }
31 if(nr==0&&max1<y) max1=y;
32 if(nr)
33 {
34 nr1++;
35 if(prim1==0) prim1=nr;
36 k=1;
37 s=0;
38 while (s<nr)
39 {
40 s=s+k;
41 k=k+4;
42 }
43 if(s==nr) q1++;
44 }
45 nr=0;
46 p=1;
47
48 }
49 for(i=1; i<=n; i++)
50 {
51 f>>x;
52 y=x;
53 while(x!=0)
54 {
55 if(x%10%2==0)
56 {
57 nr=nr+x%10*p;
58 p=p*10;
59 }
60 x=x/10;
61 }
62 if(nr==0&&max2<y) max2=y;
63 if(nr)
64 {
65 nr2++;
66 if(prim2==0) prim2=nr;
67 k=1;
68 s=0;
69 while (s<nr)
70 {
71 s=s+k;
72 k=k+4;
73 }
74 if(s==nr) q2++;
75 }
76 nr=0;
77 p=1;
78
79 }
80 if(P==1)
81 if(max1>max2) g<<max1<<’\n’;
82 else g<<max2<<’\n’;
83 else
84 {
85 if(nr1==0&&nr2==0) g<<0<<’\n’;
86 else
87 {
88 if(q1>q2) if(P==2) g<<1<<’\n’; else g<<q1<<’\n’;
89 if(q1<q2) if(P==2) g<<2<<’\n’; else g<<q2<<’\n’;
90 if(q1==q2)
91 {
92 if(prim1>prim2) if(P==2) g<<1<<’\n’; else g<<prim1<<’\n’;
93 else if(P==2) g<<2<<’\n’; else g<<prim2<<’\n’;
94 }
95 }
96 }
97
98 f.close();
99 g.close();
100 return 0;
101 }
CAPITOLUL 6. OJI 2015 80

Listing 6.1.3: cuart_la.cpp

1 #include<fstream>
2
3 using namespace std;
4
5 int main()
6 {
7 int pp,n,nr1=0,nr2=0,p1=0,p2=0,max1=0,
8 nrcuart1=0,nrcuart2=0,c,y,x,p,i,k,s;
9
10 ifstream f("cuart.in");
11 ofstream g("cuart.out");
12
13 f>>pp>>n;
14
15 for (i=1; i<=n; i++)
16 {
17 f>>c;
18 x=c;
19 p=1;
20 y=0;
21 while (x)
22 {
23 if (x%2==1)
24 {
25 y=y+x%10*p;
26 p=p*10;
27 }
28 x=x/10;
29 }
30
31 if (y!=0)
32 {
33 nr1++;
34 if (nr1==1) p1=y;
35 s=1;
36 k=5;
37 while (s+k<=y)
38 {
39 s=s+k;
40 k=k+4;
41 }
42
43 if (s==y) nrcuart1++;
44 }
45 else if (c>max1) max1=c;
46 }
47
48 for (i=1; i<=n; i++)
49 {
50 f>>c;
51 x=c;
52 p=1;
53 y=0;
54 while (x)
55 {
56 if (x%2==0)
57 {
58 y=y+x%10*p;
59 p=p*10;
60 }
61 x=x/10;
62 }
63
64 if (y!=0)
65 {
66 nr2++;
67 if (nr2==1) p2=y;
68 s=1;
69 k=5;
70 while (s+k<=y)
71 {
72 s=s+k;
73 k=k+4;
74 }
CAPITOLUL 6. OJI 2015 81

75 if (s==y) nrcuart2++;
76 }
77 else if (c>max1) max1=c;
78 }
79
80 if (pp==1)
81 g<<max1<<’\n’;
82 else
83 if (pp==2)
84 {
85 if (nrcuart1>nrcuart2)
86 g<<"1\n";
87 else
88 if (nrcuart2>nrcuart1)
89 g<<"2\n";
90 else
91 {
92 if (p1>p2)
93 g<<"1\n";
94 else
95 if(p2>p1)
96 g<<"2\n";
97 else
98 g<<"0\n";
99 }
100 }
101 else
102 {
103 if (nrcuart1>nrcuart2)
104 g<<nrcuart1;
105 else
106 if (nrcuart2>nrcuart1)
107 g<<nrcuart2;
108 else
109 {
110 if (p1>p2)
111 g<<p1<<"\n";
112 else
113 if (p2>p1)
114 g<<p2<<"\n";
115 else
116 g<<"0\n";
117 }
118 }
119 return 0;
120 }

Listing 6.1.4: cuartAI.cpp

1 #include <fstream>
2 #include <math.h>
3
4 using namespace std;
5
6 ifstream f("cuart.in");
7 ofstream g("cuart.out");
8
9 int N,P,B,C,m1,m2,maxo,K,M,q1,q2,
10 primul1,primul2,k,i,x,p,q,nr1,nr2;
11
12 int main()
13 {
14 //citire-prelucrare
15 f>>P>>N;
16
17 //Gina
18 for(i=1;i<=N;i++)
19 {
20 f>>K;x=K;p=1;q=0;
21 while(x>0)
22 {
23 if(x%2==1){q+=p*(x%10);p*=10;}
24 x/=10;
25 }
26 if(q==0){if(K>maxo)maxo=K;}
CAPITOLUL 6. OJI 2015 82

27 else
28 {
29 nr1++;
30 if(primul1==0)primul1=q;
31 //1+5+9+...+(4M+1)=(M+1)(2M+1)
32 //k=M*4+1;
33 M=0;
34 while(2*M*M+3*M+1<q) M++;
35 if(q==(M+1)*(2*M+1)) q1++;
36 }
37 }
38
39 //Mihai
40 for(i=1;i<=N;i++)
41 {
42 f>>K;x=K;p=1;q=0;
43
44 while(x>0)
45 {
46 if(x%2==0){q+=p*(x%10);p*=10;}x/=10;
47 }
48
49 if(q==0){if(K>maxo)maxo=K;}
50 else
51 {
52 nr2++;
53 if(primul2==0)primul2=q;
54 //k=M*4+1;
55 M=0;
56 while(2*M*M+3*M+1<q )M++;
57 if(q==(M+1)*(2*M+1))q2++;
58 }
59 }
60
61 //afisare a)
62
63 if(P==1)g<<maxo<<’\n’;
64
65 //afisare b) si c)
66
67 if(q1<q2)
68 B=2,C=q2;
69 else
70 if(q1>q2)
71 B=1,C=q1;
72 else
73 if(primul1>primul2)
74 B=1,C=primul1;
75 else
76 if(primul1<primul2)
77 B=2,C=primul2;
78 else
79 B=C=0;
80
81 if(P==2)g<<B<<’\n’;
82 if(P==3)g<<C<<’\n’;
83
84 f.close();
85 g.close();
86 return 0;
87 }

Listing 6.1.5: cuartAI_ecuatie.cpp

1 #include <fstream>
2 #include <math.h>
3
4 using namespace std;
5
6 ifstream f("cuart.in");
7 ofstream g("cuart.out");
8
9 int P,N,m1,m2,maxo,A,B,C,M,q1,q2,
10 primul1,primul2,k,i,x,q,p,nr1,nr2;
11
CAPITOLUL 6. OJI 2015 83

12 int main()
13 {
14 //citire-prelucrare
15 f>>P>>N;
16
17 //Gina
18 for(i=1;i<=N;i++)
19 {
20 f>>A;x=A;p=1;q=0;
21 while(x>0)
22 {
23 if(x%2==1)
24 {
25 q+=p*(x%10);
26 p*=10;
27 }
28 x/=10;
29 }
30
31 if(q==0)
32 {
33 if(A>maxo) maxo=A;
34 }
35 else
36 {
37 nr1++;
38 if(primul1==0)primul1=q;
39 //1+5+9+...+(4M+1)=(M+1)(2M+1)
40 M=(-3+sqrt(1+8*q))/4;
41 //k=M*4+1;
42 if(q==(M+1)*(2*M+1))q1++;
43 }
44 }
45
46 //Mihai
47 for(i=1;i<=N;i++)
48 {
49 f>>A; x=A; p=1; q=0;
50 while(x>0)
51 {
52 if(x%2==0)
53 {
54 q+=p*(x%10);
55 p*=10;
56 }
57 x/=10;
58 }
59
60 if(q==0){if(A>maxo)maxo=A;}
61 else
62 {
63 nr2++;
64 if(primul2==0)primul2=q;
65 M=(-3+sqrt(1+8*q))/4;
66 //k=M*4+1;
67 if(q==(M+1)*(2*M+1))q2++;
68 }
69 }
70
71 //afisare a)
72 if(P==1)g<<maxo<<’\n’;
73
74 //afisare b) si c)
75 if(q1<q2) B=2,C=q2;
76 else if(q1>q2) B=1,C=q1;
77 else if(primul1>primul2)B=1,C=primul1;
78 else if(primul1<primul2)B=2,C=primul2;
79 else B=C=0;
80
81 if(P==2)g<<B<<’\n’;
82 if(P==3)g<<C<<’\n’;
83
84 f.close();
85 g.close();
86 return 0;
87 }
CAPITOLUL 6. OJI 2015 84

6.1.3 *Rezolvare detaliat 

6.2 speciale
Problema 2 - speciale 100 de puncte
Maria a aat c  numerele naturale care încep cu cifra 1 ³i au toate cifrele ordonate strict
cresc tor ³i consecutive sau încep cu cifra 9 ³i au toate cifrele ordonate strict descresc tor ³i
consecutive se numesc numere speciale. Interesat  s  descopere leg tura dintre numerele speciale
cu acela³i num r de cifre, a observat c  poate construi tabelul al turat.

Figura 6.2: speciale

Cerinµe
Scrieµi un program care citind patru numere naturale K, N , A ³i B determin :
1) cel mai mare num r special situat în tabel pe linia K ;
2) num rul special obµinut din num rul N prin ³tergerea unei cifre;
3) num rul de numere speciale din mulµimea {A , A  1, A  2, A  3, ..., B  1, B }.
Date de intrare
Fi³ierul de intrare speciale.in conµine pe prima linie un num r natural P . Pentru toate testele
de intrare, num rul P poate avea doar valoarea 1, valoarea 2 sau valoarea 3. Pe a doua linie a
³ierului speciale.in se g sesc, în aceast  ordine, numerele naturale K , N , A ³i B , separate prin
câte un spaµiu.

Date de ie³ire
Dac  valoarea lui P este 1, se va rezolva numai punctul 1) din cerinµe. În acest caz, ³ierul de
ie³ire speciale.out va conµine pe prima linie un num r natural reprezentând cel mai mare num r
special situat în tabel pe linia K.
Dac  valoarea lui P este 2, se va rezolva numai punctul 2) din cerinµe. În acest caz, ³ierul
de ie³ire speciale.out va conµine pe prima linie un num r natural reprezentând num rul special
obµinut din num rul N prin ³tergerea unei cifre sau 0 dac  un astfel de num r nu se poate obµine;
Dac  valoarea lui P este 3, se va rezolva numai punctul 3) din cerinµe. În acest caz, ³ierul de
ie³ire speciale.out va conµine pe prima linie un num r natural reprezentând num rul de numere
speciale din mulµimea {A, A  1, A  2, A  3, ..., B  1, B }.

Restricµii ³i preciz ri
a 1&K&9
a 1 & N & 999999999
a 1 & A & B & 999999999
a Pentru rezolvarea corect  a primei cerinµe se acord  20 de puncte, pentru rezolvarea corect 
a celei de a doua cerinµe se acord  40 de puncte, pentru rezolvarea corect  a celei de a treia cerinµe
se acord  40 de puncte.

Exemple
CAPITOLUL 6. OJI 2015 85

speciale.in speciale.out Explicaµii


13 125345 320 888888 987 P = 1, pentru acest test, se rezolva cerinµa 1).
Numerele speciale de pe linia a treia a tabelului sunt 123 ³i 987,
cel mai mare ind 987.
23 125345 320 888888 12345 P = 2, pentru acest test, se rezolva cerinµa 2).
“tergând cifra 5 aat  pe poziµia a treia în 125345 se obµine
num rul special 12345.
33 125345 320 888888 6 P = 3, pentru acest test, se rezolva cerinµa 3).
Sunt 6 numere speciale în mulµimea {320, 321,..., 888888} ³i
anume 987, 1234, 9876, 12345, 98765, 123456.

Timp maxim de executare/test: 0.5 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 5 KB

6.2.1 Indicaµii de rezolvare

Cerinta 1
Se formeaza numarul special care incepe cu cifra 9 si contine k cifre cu ajutorul unei structuri
repetitive.

Cerinta 2
O solutie posibila: numaram cifrele numarului N (nr); construim numarul special cu un numar
de cifre egal cu nr  1; comparam cifrele numarului N cu cifrele numarului special construit (cifra
cu cifra de la dreapta la stanga); daca toate sunt egale (pe aceeasi pozitie) si numai una difera,
atunci asam numarul special construit, altfel asam valoarea 0.

Cerinta 3
O solutie posibila: Calculam cate cifre are numărul A. Construim numerele speciale care
sa contina tot atatea cifre cate contine numarul A. Comparam valoarea numerelor speciale cu
valoarea numarului A si B iar apoi construim prin adaugare de cifre crescatore/descrescatore
urmatoarele numere speciale pana cand ajungem la valoarea numarului B.

6.2.2 Cod surs 

Listing 6.2.1: speciale_dc.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream fin("speciale.in");
6 ofstream fout("speciale.out");
7
8 int main()
9 {
10 unsigned P,N,K,A,B,x,special,i,p,NN,Ncif;
11
12 x=special=Ncif=0;
13
14 fin>>P>>K>>N>>A>>B; NN=N;
15
16 if(P==1)
17 {
18 for(i=9;i>=10-K;i--) fout<<i;
19 fout<<’\n’;
20 return 0;
21 }
22
23 if(P==2)
24 {
25 ///cerinta 2
CAPITOLUL 6. OJI 2015 86

26 while(NN)
27 {
28 NN/=10;
29 special=special*10+Ncif;
30 Ncif++;
31 }
32
33 if(N%10==Ncif-1||N/10%10==Ncif-1)///verific daca N este de forma 1234...
34 {
35 NN=N;i=Ncif-1;p=1;
36 while(NN)
37 {
38 if(NN%10!=i)
39 {
40 if(N/(p*10)*p+N%p==special) x=special;
41 break;
42 }
43 else {i--;p*=10;NN/=10;}
44 }
45 if(NN==0)x=special;
46 }
47
48 //verific daca N este de forma 987...
49 if(x==0&&(N%10==11-Ncif||N/10%10==11-Ncif))
50 {
51 NN=N;i=11-Ncif;p=1;
52 while(NN)
53 {
54 if(NN%10!=i)
55 {
56 if(N/(p*10)*p+N%p==special*8+Ncif-1)
57 x=special*8+Ncif-1;
58 break;
59 }
60 else {i++;p*=10;NN/=10;}
61 }
62 if(NN==0) x=special*8+Ncif-1;
63 }
64 fout<<x<<’\n’;
65 return 0;
66 }
67
68 if(P==3)
69 {
70
71 ///cerinta 3
72 for(x=special=0,i=1;special<=B;i++)
73 {
74 special=special*10+i;
75 if(special>=A&&special<=B) x++;
76 if(special*8+i>=A&&special*8+i<=B) x++;
77 }
78 fout<<x<<’\n’;
79 return 0;
80 }
81 return 0;
82 }

Listing 6.2.2: speciale_n_dt.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("speciale.in");
6 ofstream g("speciale.out");
7
8 int main()
9 {
10 int k,n,a,b,x=0,i,pr,nr=0,nr1=0,p1,fin_nr,ok=0,nr2,p;
11 f>>p>>k>>n>>a>>b;
12
13 if(p==1)
14 {
15 x=0;
CAPITOLUL 6. OJI 2015 87

16 for(i=9;i>9-k;i--)
17 x=i+x*10;
18 g<<x<<’\n’;
19 }
20
21 //cerinta 2
22 if(p==2)
23 {
24 pr=n;
25 while(pr)
26 {
27 pr=pr/10;
28 nr++;
29 }
30
31 nr--;
32 for(i=1;i<=nr;i++)
33 nr1=i+nr1*10;
34 p1=0;
35 pr=n;
36 fin_nr=nr1;
37
38 while(pr)
39 {
40 if(pr%10==nr1%10) {pr=pr/10;nr1=nr1/10;}
41 else {p1++;pr=pr/10;}
42 }
43
44 if(p1==1) {g<<fin_nr<<’\n’;ok=1;}
45 else
46 {
47 nr1=0;
48 for(i=9;i>9-nr;i--)
49 nr1=i+nr1*10;
50
51 p1=0;
52 pr=n;
53 fin_nr=nr1;
54
55 while(pr)
56 {
57 if(pr%10==nr1%10) {pr=pr/10;nr1=nr1/10;}
58 else {p1++;pr=pr/10;}
59 }
60
61 if(p1==1) {g<<fin_nr<<’\n’;ok=1;}
62 }
63 if(ok==0) g<<0<<’\n’;
64 }
65
66 //cerinta 3
67 if(p==3)
68 {
69 nr=0;
70 pr=a;
71 nr1=0;
72
73 while(pr){pr=pr/10;nr++;}
74
75 for(i=1;i<=nr;i++)
76 nr1=i+nr1*10;
77
78 nr2=0;
79 for(i=9;i>9-nr;i--)
80 nr2=i+nr2*10;
81
82 x=0;
83 if(nr1>=a) x++;
84 if(nr2>=a&&nr2<=b) x++;
85 nr++;
86 pr=nr2%10-1;
87 while(nr2<b && nr1<b)
88 {
89 nr2=nr2*10+pr;
90 nr1=nr1*10+nr;
91 nr++;pr--;
CAPITOLUL 6. OJI 2015 88

92 if(nr1<=b) x++;
93 if(nr2<=b) x++;
94 }
95 g<<x<<’\n’;
96 }
97
98 f.close();
99 g.close();
100 return 0;
101 }

Listing 6.2.3: speciale_SJ.cpp

1 #include <iostream>
2 #include <fstream>
3
4 using namespace std;
5
6 ifstream in("speciale.in");
7 ofstream out("speciale.out");
8
9 int main()
10 {
11 int P,k,n,A,B,m,nr=0,nrm=0,mr=0,i,l,sw1,sw2;
12 in>>P;
13
14 in>>k>>n>>A>>B;
15
16 if(P==1)
17 {
18 //a
19 for(i=1;i<=k;i++)
20 nrm=nrm*10+10-i;
21 out<<nrm<<’\n’;
22 }
23 else
24 if(P==2)
25 {
26 //b
27 nr=0;
28 m=n,l=0;
29 while(m)
30 l++,m/=10;
31
32 for(i=1;i<l;i++)
33 nr=nr*10+i;
34
35 mr=nr,sw1=0,m=n;
36 while(n)
37 {
38 if(n%10!=nr%10)
39 n/=10, sw1++;
40 else
41 n/=10,nr/=10;
42 }
43
44 n=m;
45 if(sw1==1&&nr==0)
46 out<<mr<<’\n’;
47 else
48 if(sw1==0 && n/10==0)
49 out<<mr<<’\n’;
50 else
51 {
52 nr=0;
53 for(i=9;i>10-l;i--)
54 nr=nr*10+i;
55
56 mr=nr,sw2=0,m=n;
57 while(n)
58 {
59 if(n%10!=nr%10)
60 n/=10, sw2++;
61 else
62 n/=10,nr/=10;
CAPITOLUL 6. OJI 2015 89

63 }
64
65 if(sw2==1&&n==0)
66 out<<mr<<’\n’;
67 else
68 if(sw2==0 && n/10==0)
69 out<<mr<<’\n’;
70
71 if(sw1!=1 && sw2!=1)
72 out<<0<<’\n’;
73 }
74 }
75 else
76 {
77 //c
78 m=A,l=0,nr=0,k=0;
79
80 while(m)
81 l++,m/=10;
82
83 for(i=1;i<=l;i++)
84 nr=nr*10+i;
85
86 if(nr<A)
87 {
88 m=nr*8+l;
89 if(m>=A && m<=B)
90 k++;
91 l++, nr=nr*10+l;
92 }
93
94 i=l;
95 while(nr>=A && nr<=B)
96 {
97 k++;
98 if(nr*8+i>=A && nr*8+i<=B)
99 k++;
100 i++;
101 nr=nr*10+i;
102 }
103
104 out<<k;
105 }
106 return 0;
107 }

Listing 6.2.4: specialedl.cpp

1 #include <cstdio>
2 #include <cctype>
3 #include <algorithm>
4 #include <cassert>
5
6 #define MRD 999999999
7
8 using namespace std;
9
10 int K, N, A, P, B, N1, N2, Nr, Na1, Na2, Special, i, p, x, d, u, nr;
11 bool ok;
12
13 int main()
14 {
15 freopen("speciale.in", "r",stdin);
16 freopen("speciale.out","w",stdout);
17
18 scanf("%d\n",&P);
19 scanf("%d%d%d%d",&K, &N, &A, &B);
20
21 assert(P>0 && P<=3 && K<10 && K>0 && N<=MRD && A<=MRD &&
22 B<=MRD && N>0 && A>0 && B>0 && A<=B);
23
24 if(P==1)
25 {
26 for(int i=1; i<=K; i++)
27 N2=N2*10 + 10 - i;
CAPITOLUL 6. OJI 2015 90

28 printf("%d\n", N2);
29 }
30 else
31 if(P==2)
32 {
33 p = 1;
34 Special=0;
35 while(N/p>0 && !Special)
36 {
37 Nr=N/(p*10)*p + N%p;
38 int cn=Nr;
39
40 while(cn>9) cn/=10;
41
42 if(Nr==1 ||Nr == 9)
43 Special = Nr;
44 else
45 {
46 d=(cn==9? 1: -1);
47 u=Nr%10;
48
49 ok=true;
50 while (Nr>0)
51 {
52 if ( u != Nr % 10 ) ok=false;
53 Nr/=10; u += d;
54 }
55
56 if (ok && (d==1 && u==10 || d==-1 && u==0))
57 Special=N/(p*10)*p + N%p;
58 }
59
60 p*=10;
61 }
62
63 printf("%d\n", Special);
64 }
65 else
66 {
67 Na1=Na2=nr=0;
68 for(int i=1; i<=9 ; i++ )
69 {
70 Na1=Na1*10 + i;
71 if(Na1>=A&&Na1<=B ) nr++;
72 Na2=Na2*10 + 10 - i;
73 if(Na2>=A&&Na2<=B) nr++;
74 }
75
76 printf("%d\n", nr);
77 }
78 return 0;
79 }

6.2.3 *Rezolvare detaliat 


Capitolul 7

OJI 2014

7.1 martisoare
Problema 1 - martisoare 100 de puncte
Gic  ³i Lic  lucreaz  la o fabric  de juc rii, în schimburi diferite. Anul acesta patronul fa-
bricii a hot rât s  confecµioneze ³i m rµi³oare. M rµi³oarele gata confecµionate sunt puse în cutii
numerotate consecutiv.
Cutiile sunt aranjate în ordinea strict cresc toare ³i consecutiv  a numerelor de pe acestea.
Gic  trebuie s  ia, în ordine, ecare cutie, s  lege la ecare m rµi³or câte un ³nur alb-ro³u ³i
apoi s  le pun  la loc în cutie.
În ecare schimb, Gic  scrie pe o tabl  magnetic , utilizând cifre magnetice, în ordine strict
cresc toare, numerele cutiilor pentru care a legat ³nururi la m rµi³oare.
Când se termin  schimbul lui Gic , Lic , care lucreaz  în schimbul urm tor, vine ³i ambaleaz 
cutiile cu numerele de pe tabl  ³i le trimite la magazine. Totul merge ca pe roate, pân  într-o zi,
când, dou  cifre de pe tabl  se demagnetizeaz  ³i cad, r mânând dou  locuri goale. Lic  observ 
acest lucru, le ia de jos ³i le pune la întâmplare pe tabl , în cele dou  locuri goale. Singurul lucru
de care µine cont este acela c  cifra 0 nu poate  prima cifr  a unui num r.

Figura 7.1: marti³oare

Cerinµe
Scrieµi un program care s  citeasc  numerele naturale N (reprezentând num rul de numere
scrise pe tabl ) ³i c1 , c2 , ..., cN (reprezentând numerele scrise, în ordine, pe tabl , dup  ce Lic  a
completat cele dou  locuri goale cu cifrele c zute) ³i care s  determine:
a) cele dou  cifre care au fost schimbate între ele, dac , dup  ce au completat locurile goale,
acestea au schimbat ³irul numerelor scrise de Gic ;
b) num rul maxim scris pe tabl  de Gic .

Date de intrare
Fi³ierul de intrare martisoare.in conµine pe prima linie num rul natural N reprezentând
num rul de numere de pe tabl . A doua linie a ³ierului conµine, în ordine, cele N numere
c1 , c2 , ..., cN , separate prin câte un spaµiu, reprezentând, în ordine, numerele existente pe tabl ,
dup  ce Lic  a completat cele dou  locuri libere cu cifrele c zute.

Date de ie³ire
Fi³ierul de ie³ire martisoare.out va conµine pe prima linie dou  cifre, în ordine cresc toare,
separate printr-un spaµiu, reprezentând cele dou  cifre care au fost schimbate între ele sau 0 0
în cazul în care cele dou  cifre magnetice c zute, dup  ce au fost puse înapoi pe tabl , nu au
schimbat ³irul numerelor scrise de Gic . A doua linie va conµine un num r reprezentând num rul
maxim din secvenµa de numere consecutive scris  de Gic  pe tabl .

91
CAPITOLUL 7. OJI 2014 92

Restricµii ³i preciz ri
a 4 & N & 100000
a 1 & ci & 100000, (1 & i & N )
a N , c1 , c2 , ..., cN sunt numere naturale;
a cele dou  cifre care cad de pe tabl  pot proveni din acela³i num r;
a Pentru rezolvarea cerinµei a) se acord  60% din punctaj, iar pentru cerinµa b) se acord  40%
din punctaj.

Exemple
martisoare.in martisoare.out Explicaµii
5 2 629 Gic  a scris pe tabl , în ordine, numerele: 25 26 27 28 29.
65 22 27 28 29 Au fost schimbate între ele cifra 2 din primul num r ³i cifra
6 din al doilea num r. Cel mai mare num r scris de Gic  pe
tabl  este 29. .
4 8 998 Gic  a scris pe tabl , în ordine, numerele: 95 96 97 98 Au
95 96 97 89 fost schimbate între ele cifrele ultimului num r. Cel mai mare
num r scris de Gic  pe tabl  este 98.
5 0 039 Gic  a scris pe tabl , în ordine, numerele: 35 36 37 38 39
35 36 37 38 39 ³irul numerelor nu a fost schimbat, cel mai mare num r ind
39.

Timp maxim de executare/test: 0.5 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 5 KB

7.1.1 Indicaµii de rezolvare

Solutie - complexitate O(N) - prof. Ana Intuneric


Solutia se bazeaza pe observatia ca este sucient sa determinam primul numar modicat.
Sunt doua cazuri clare
a) primele doua numere sunt nemodicate, caz in care se calculeaza imediat numarul maxim
si se cauta primul numar modicat comparand cifrele sale cu cifrele numarului care trebuia sa e
pe respectiva pozitie in sier
b) unul dintre primele doua numere sau amandoua sunt modicate. In acest caz se citesc doar
primele 4 numere si se trateaza combinatiile posibile de numere modicate

7.1.2 Cod surs 

Listing 7.1.1: mAna.cpp

1 // sursa oficiala - prof.Ana Intuneric


2 #include <fstream>
3
4 using namespace std;
5
6 ifstream f("martisoare.in");
7 ofstream g("martisoare.out");
8
9 int N,i,c1,c2,c3,c4,x,y,maxi,gasit;
10
11 int main()
12 {
13 f>>N;
14 f>>c1>>c2;
15
16 //caut primul numar modificat
17 if(c2-c1==1)
18 {
19 maxi=c1+N-1;
20 for(i=3;i<=N && !gasit;i++)
21 {
22 f>>c3;
CAPITOLUL 7. OJI 2014 93

23 if(c3-c2!=1)
24 {
25 x=c2+1;y=c3;gasit=1;
26 while(x!=0 && y!=0)
27 {
28 if(x%10!=y%10)
29 {
30 if(x%10<y%10)
31 g<<x%10<<’ ’<<y%10<<endl;
32 else
33 g<<y%10<<’ ’<<x%10<<endl;
34 break;
35 }
36 else
37 x/=10,y/=10;
38 }
39 }
40 else
41 c2=c3;
42 }
43 }
44 else
45 {
46 f>>c3>>c4;
47
48 //c1 modificat
49 if(c3-c2==1)
50 {
51 x=c2-1;
52 y=c1;
53 gasit=1;
54 maxi=c2+N-2;
55 }
56 else
57 if(c4-c2==2)
58 {
59 x=c2-1;
60 y=c1;
61 gasit=1;
62 maxi=c4+N-4;
63 }
64 //c2 este modificat
65 else
66 if(c4-c3==1)
67 {
68 x=c2;
69 y=c3-1;
70 gasit=1;
71 maxi=c3+N-3;
72 }
73 else
74 if(c3-c1==2)
75 {
76 x=c2;
77 y=c3-1;
78 gasit=1;
79 maxi=c3+N-3;
80 }//c2 modificat si c3 este bun
81 else
82 {
83 x=c2;
84 y=c4-2;
85 gasit=1;
86 maxi=c4+N-4;
87 }//c2 modificat si c4 este bun
88
89 while(x!=0 && y!=0)
90 {
91 if(x%10!=y%10)
92 {
93 if(x%10<y%10)
94 g<<x%10<<’ ’<<y%10<<endl;
95 else
96 g<<y%10<<’ ’<<x%10<<endl;break;
97 }
98 else
CAPITOLUL 7. OJI 2014 94

99 x/=10,y/=10;
100 }
101 }
102
103 if(!gasit)
104 g<<"0 0\n";
105
106 g<<maxi<<endl;
107
108 f.close();
109 g.close();
110 return 0;
111 }

Listing 7.1.2: mCarmen.cpp

1 #include <iostream>
2 #include <fstream>
3
4 using namespace std;
5
6 ifstream f("martisoare.in");
7 ofstream g("martisoare.out");
8
9 int v[100001];
10
11 int main()
12 {
13 int i,x,k=1,y,n, a=0,b=0;
14 f>>n>>x;
15
16 v[1]=x; y=x;
17 for(i=2;i<=n;i++)
18 {
19 f>>v[i];
20 x=max(x,v[i]);
21 y=min(y,v[i]);
22 }
23
24 if(y+n-1==x)
25 {
26 for(i=1; i<=n;i++,y++)
27 if(v[i]!=y)
28 {
29 a=v[i];
30 b=y;
31 break;
32 }
33 }
34 else
35 { int i=1;
36 if(v[1]!=y && v[2]==y)
37 {
38 if(v[3]==y+1)
39 {
40 a=v[1];
41 b=y-1;
42 x=b+n-1;
43 }
44 else
45 {
46 x=v[3]+n-3;
47 a=v[3]-1;
48 b=y;
49 }
50 }
51 else
52 {
53 i=2;
54 while(y+1==v[i] && i<=n)
55 {
56 i++;
57 y++;
58 }
59
CAPITOLUL 7. OJI 2014 95

60 a=v[i];
61 b=y+1;
62 x=y+(n-i+1);
63 }
64 }
65
66 if(a*b)
67 {
68 while(a%10==b%10)
69 {
70 a=a/10; b=b/10;
71 }
72
73 a=a%10;
74 b=b%10;
75 if(a>b) swap(a,b);
76 }
77
78 g<<a<<" "<<b<<endl<<x<<endl;
79
80 return 0;
81 }

Listing 7.1.3: mCristina.cpp

1 //martisoare - Cristina Sichim


2 #include <fstream>
3 using namespace std;
4
5 ifstream f("martisoare.in");
6 ofstream g("martisoare.out");
7
8 int n,a,b,c,d,u;
9
10 void cifre(int b, int c)
11 {
12 while(b%10==c%10)
13 b/=10,c/=10;
14
15 (b%10 < c%10) ? g<<b%10<<’ ’<<c%10<<’\n’ : g<< c%10<<’ ’<<b%10<<’\n’;
16 }
17
18 int main()
19 {
20 f>>n>>a>>b>>c;
21 if(a+1==b && b+1==c)
22 {
23 u=a+n-1; n-=3;
24 while(n && b+1==c)
25 f>>c,++b,--n;
26 if(b+1!=c)
27 cifre(b+1,c), g<<u<<’\n’;
28 else
29 g<<"0 0\n"<<u<<’\n’;
30 }
31 else // cifre schimbate in primele 3 numere
32 if(a+1==b)
33 cifre(b+1,c), g<<a+n-1<<’\n’;
34 else
35 if(b+1==c)
36 cifre(a,b-1), g<<b+n-2<<’\n’;
37 else
38 if(a+2==c)
39 cifre(a+1,b), g<<a+n-1<<’\n’;
40 else
41 {
42 f>>d;
43 if(a+3==d)
44 cifre(a+1,b), g<<a+n-1<<’\n’;
45 else
46 if(b+2==d)
47 cifre(a,b-1), g<<b+n-2<<’\n’;
48 else
49 cifre(b,c-1), g<<c+n-3<<’\n’;
50 }
CAPITOLUL 7. OJI 2014 96

51
52 f.close();
53 g.close();
54
55 return 0;
56 }

Listing 7.1.4: mMarilena.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("martisoare.in");
6 ifstream g("martisoare.in");
7 ofstream h("martisoare.out");
8
9 int n,vmin,vmax,t,x,x1,y,y1,a,b,c,d,i,poz;
10
11 int main()
12 {
13 f>>n>>a>>b>>c>>d;
14
15 // gasesc primul numar corect din sir si
16 // calculez extremitatile sirului [vmin, vmax]
17
18 if(b-a==1){vmin=a; vmax=a+n-1;}
19 else
20 if(c-b==1){vmin=b-1; vmax=b+n-2;}
21 else
22 if(d-c==1){vmin=c-2; vmax=c+n-3;}
23 else
24 if(c-a==2){vmin=a; vmax=a+n-1;}
25 else
26 if(d-b==2){vmin=b-1; vmax=b+n-2;}
27 else
28 if(d-a==3){vmin=a; vmax=a+n-1;}
29
30 f.close();
31
32 // caut cele 2 numere gresite
33 g>>n;
34 x=x1=vmin;
35 t=0;
36 for(i=1;i<=n;i++)
37 {
38 x=x1;
39 g>>y;
40 if(x!=y)
41 {
42 while(x!=0 && y!=0) //caut cifrele incurcate
43 {
44 if (x%10!=y%10)
45 {
46 t++;
47 if(t==1) a=x%10;
48 else b=x%10;
49 }
50
51 x=x/10;y=y/10;
52 }
53 }
54
55 if (t==2) i=n;
56 x1++;
57 }
58
59 if(t==0) h<<0<<’ ’<<0<<endl<<vmax;
60 else
61 {
62 if(a>b){t=a ;a=b; b=t;}
63 h<<a<<’ ’<<b<<endl<<vmax;
64 }
65
66 g.close();
CAPITOLUL 7. OJI 2014 97

67 h.close();
68
69 return 0;
70 }

Listing 7.1.5: mRaluca.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("martisoare.in");
6 ofstream g("martisoare.out");
7
8 int main()
9 {
10 int v[4], n, i, max=0, r, c, x, j, nr1=0,
11 p1, nr2=0, p2, nr, c1=0, c2=0, cc;
12
13 f>>n;
14 for(i=0;i<4;i++)
15 f>>v[i];
16
17 for(i=0; i<3; i++)
18 {
19 x=v[i]-i;c=1;
20 for(j=i+1;j<4; j++)
21 if(v[j]-j==x)c++;
22 if(c>max) max=c, r=x;
23 }
24
25 for(i=0;i<4;i++)
26 if(v[i]-i!=r)
27 if(nr1==0) nr1=v[i], p1=i;
28 else
29 if(nr2==0) nr2=v[i],p2=i;
30
31 for(i=4;i<n and nr2==0; i++)
32 {
33 f>>nr;
34 if(nr-i!=r)
35 if(nr1==0) nr1=nr, p1=i;
36 else
37 if(nr2==0) nr2=nr,p2=i;
38 }
39
40 if(nr1)
41 {
42 x=r+p1;
43 while(nr1)
44 {
45 c=nr1%10;
46 cc=x%10;
47 if(c!=cc)
48 if(c<cc) c1=c, c2=cc;
49 else c1=cc, c2=c;
50 nr1/=10;
51 x/=10;
52 }
53 }
54
55 g<<c1<<’ ’<<c2<<’\n’<<r+n-1<<’\n’;
56
57 f.close();
58 g.close();
59
60 return 0;
61 }

7.1.3 *Rezolvare detaliat 


CAPITOLUL 7. OJI 2014 98

7.2 piramide
Problema 2 - piramide 100 de puncte
Fascinat de Egiptul Antic, Rare³ vrea s  construiasc  cât mai multe piramide din cartona³e
p tratice identice. El are la dispoziµie N cartona³e numerotate de la 1 la N, albe sau gri, a³ezate
în ordinea strict cresc toare a numerelor.
a Prima piramid  o va construi folosind primele trei cartona³e. Baza piramidei va  format 
din cartona³ele 1 ³i 2 a³ezate al turat, peste care va a³eza cartona³ul 3 (vârful piramidei).
a A doua piramid  va avea baza format  din cartona³ele 4, 5 ³i 6 a³ezate al turat, deasu-
pra c rora se vor a³eza cartona³ele 7 ³i 8, al turate, peste care se va a³eza cartona³ul 9 (vârful
piramidei).
a Mai departe, va construi în ordine piramidele complete cu bazele formate din 4 cartona³e
(cu numerele de la 10 la 13), respectiv 5 cartona³e (cu numerele de la 20 la 24), 6 cartona³e (cu
numerele de la 35 la 40) etc., cât timp va putea construi o piramid  complet . De exemplu, dac 
Rare³ are N 75 cartona³e atunci el va construi piramidele complete 1, 2, 3, 4 ³i 5 din imaginile
urm toare. Din cele 75 de cartona³e el va folosi doar primele 55 de cartona³e, deoarece ultimele
20 cartona³e nu sunt suciente pentru a construi piramida 6, cu baza format  din 7 cartona³e.

Figura 7.2: Piramide

Cerinµe
Scrieµi un program care s  citeasc  numerele naturale N (reprezentând num rul de cartona³e),
X (reprezentând num rul unui cartona³), K (reprezentând num rul de cartona³e albe), numerele
celor K cartona³e albe c1 , c2 , ..., cK ³i care s  determine: a) num rul P al piramidei complete
ce conµine cartona³ul numerotat cu X; b) num rul M maxim de piramide complete construite
de Rare³; c) num rul C de cartona³e nefolosite; d) num rul A al primei piramide complete care
conµine cele mai multe cartona³e albe.

Date de intrare
Fi³ierul de intrare piramide.in conµine pe prima linie cele trei numere N , X ³i K, separate
prin câte un spaµiu, cu semnicaµia din enunµ. A doua linie a ³ierului conµine, în ordine, cele K
numere c1 , c2 , ..., cK , separate prin câte un spaµiu, reprezentând numerele celor K cartona³e albe
din cele N .

Date de ie³ire
Fi³ierul de ie³ire piramide.out va conµine pe prima linie num rul P sau valoarea 0 (zero)
dac  niciuna dintre piramidele complete construite nu conµine cartona³ul cu num rul X. A doua
linie a ³ierului va conµine num rul M. Cea de-a treia linie va conµine num rul C. Cea de-a
patra linie va conµine num rul A sau valoarea 0 (zero) dac  nicio piramid  complet  nu conµine
cel puµin un cartona³ alb.

Restricµii ³i preciz ri
N, X, K, c1 , c2 , ..., cK , P, M, A sunt numere naturale nenule.
a
3 & N & 100000; 1 & X & N ; 1 & K & N ; 1 & c1 $ c2 $ ... $ cK & N
a
a O piramid  complet  cu baza format  din b cartona³e se construie³te prin a³ezarea cartona-
³elor necesare pe b rânduri: b cartona³e pe primul rând (al bazei), apoi b  1 cartona³e pe rândul
al doilea, b  2 pe rândul al treilea, ..., dou  cartona³e pe rândul b  1 ³i un cartona³ (vârful
piramidei) pe rândul b.
a Pentru rezolvarea cerinµei a) se acord  20% din punctaj, pentru cerinµa b) 20% din punctaj,
pentru cerinµa c) 20% din punctaj ³i pentru cerinµa d) 40% din punctaj.
CAPITOLUL 7. OJI 2014 99

Exemple
piramide.in piramide.out
75 15 23 3
5 9 11 18 20 21 25 27 28 30 35 37 45 46 51 55 60 65 68 69 70 71 72 5
20
4
Explicaµie: Piramida 3 (P=3) construit  conµine cartona³ul cu num rul X 15. Rare³ poate
construi doar M 5 piramide complete, r mânând nefolosite 20 cartona³e (C 20) insuciente
pentru construirea piramidei 6. Num rul maxim de cartona³e albe dintr-o piramid  complet 
este egal cu 6. Piramidele 4 ³i5 conµin ecare un num r maxim de cartona³e albe (6), prima
dintre acestea ind piramida 4 (A 4). Ultimele 7 cartona³e albe (cu numerele: 60, 65, 68, 69,
70, 71, 72) nu sunt folosite în construirea piramidelor complete.

Timp maxim de executare/test: 0.5 secunde


Memorie: total 2MB din care pentru stiv  2MB
Dimensiune maxim  a sursei: 15KB

7.2.1 Indicaµii de rezolvare

Descriere soluµie
autor prof. Carmen Minc ,
Colegiul Naµional de Informatic  Tudor Vianu, Bucure³ti

O soluµie posibil  se poate obµine f r  a utiliza tablouri unidimensionale, prin citirea succesiv 
a datelor din ³ier combinat  cu prelucrarea acestora.
Se observ  c  pentru construirea piramidei complete care are baza formata din b cartona³e
sunt necesare: CB b  b  1  b  2  ...  3  2  1 b b  1©2
Simul m construirea num rului maxim M de piramide complete folosind cele N cartona³e.
Se cite³te num rul CA al primului cartona³ alb din ³ier.
Pornind de la prima piramid  (cea cu baza b 2), construim celelalte piramide cât timp avem
cartona³e nefolosite suciente ³i num rul cartona³elor folosite în construirea acestora este mai mic
ca CA.
Num r m piramida complet  curent  ³i veric m apartenenµa cartona³ului X la piramida
curent  folosindu-ne de num rul primului, respectiv ultimului, cartona³ din piramid .
La g sirea primei piramide ce conµine cartona³ul alb CA, citim din ³ierul de intrare nume-
rele urm toarelor cartona³e albe cµt timp numerele acestora sunt mai mici sau egale cu num rul
cartona³ului vµrf din piramida curent . La nalul acestei operaµii vom dispune de num rul carto-
na³elor albe din piramida curent . Se compar  acest num r cu cel maxim obµinut pµn  în acest
moment. Se actualizeaz  acest maxim dac  s-a obµinut o valoare mai mare memorµndu-se ³i
num rul piramidei curente.
Se trece la construirea urm toarei piramide, cu baza b1 dac  avem suciente cartona³e
nefolosite, altfel se încheie procesul de construire a piramidei.

7.2.2 Cod surs 

Listing 7.2.1: p_s_CM.cpp

1 //sursa oficiala - prof. Carmen Minca - C.N.I.T.Vianu- Bucuresti


2
3 #include <fstream>
4
5 using namespace std;
6
7 /*a) numarul P al piramidei ce conÈŻine cartonasul numerotat cu X;
8 b) numarul M maxim de piramide construite de Gigel;
9 c) numarul C de cartonaÈŹe nefolosite;
10 d) numarul A al primei piramide care contine cele mai multe cartonaÈŹe albe.
11 */
12
13 int n, x, k;
14
15 ifstream f("piramide.in");
CAPITOLUL 7. OJI 2014 100

16 ofstream g("piramide.out");
17
18 int main()
19 {
20 int p=0, a=0, m=0, c=0,i,ca,b=1,cfol=0,cp,nra, maxnra=0;
21 f>>n>>x>>k;
22 i=1;
23 f>>ca;
24 do //caut piramida ce contine cartonasul alb cu numarul ca
25 { b++;//nr cartonase din baza piramida curenta
26 nra=0;//caut in piramida curenta cartonasele albe
27 cp=b*(b+1)/2; //nr cartonase din care e formata piramida curenta
28
29 if(cp+cfol<=n) //daca am cele cp cartoane atunci pot construi piramida
30 { m++; //numar piramida construita
31
32 if(cfol<x && x<=cp+cfol) p=m; //verif daca contine cartonasul x
33 cfol+=cp;
34
35 while(ca<=cfol && i<=k)
36 { nra++;f>>ca;i++;} //numar cartonasele albe din piramida
37
38 if(nra>maxnra)
39 { a=m; maxnra=nra; }
40 }
41 else break;
42 } while (cfol<n);
43 c=n-cfol;
44 g<<p<<endl<<m<<endl<<c<<endl<<a<<endl;
45 return 0;
46 }

Listing 7.2.2: p_v_CM.cpp

1 //prof.Carmen Minca C.N.I.T.Vianu - Bucuresti


2
3 #include <fstream>
4
5 using namespace std;
6
7 /*a) numarul P al piramidei ce conÈŻine cartonasul numerotat cu X;
8 b) numarul M maxim de piramide construite de Gigel;
9 c) numarul C de cartonaÈŹe nefolosite;
10 d) numarul A al primei piramide care contine cele mai multe cartonaÈŹe albe.
11 */
12
13 int n, x, k, cart[100];
14
15 ifstream f("piramide.in");
16 ofstream g("piramide.out");
17
18 int main()
19 {
20 int p=0, a=0, m=0, c,i,ca,b,nra, maxnra=0,j;
21 f>>n>>x>>k;
22 b=1;
23 cart[1]=3;
24 m=0; b++;
25 while(cart[m]+b*(b+1)/2<=n)
26 {
27 m++;
28 cart[m]=b*(b+1)/2+cart[m-1];
29 b++;
30 if(x>cart[m-1] && x<=cart[m])p=m;
31 }
32
33 c=n-cart[m]; j=1;
34 i=1; f>>ca;
35
36 while(i<=k && j<=m)
37 {
38 while(ca>cart[j] && j<=m) j++;
39 if(j<=m)
40 {
41 nra=0;
CAPITOLUL 7. OJI 2014 101

42 while(ca<=cart[j] && i<=k)


43 {
44 nra++; f>>ca; i++;
45 }
46 if(nra>maxnra){a=j; maxnra=nra;}
47 }
48 }
49
50 g<<p<<endl<<m<<endl<<c<<endl<<a;
51
52 return 0;
53 }

Listing 7.2.3: pAna.cpp

1 #include <fstream>
2 using namespace std;
3
4 ifstream f("piramide.in");
5 ofstream g("piramide.out");
6
7 int N,X,K,i,ls,ld,P,nrpc,nrc,nrca,maxca,nrpmax,c,S,nr;
8
9 int main()
10 {
11 //citire
12 f>>N>>X>>K;
13
14 //a)
15 ls=1;ld=3;nrpc=1;
16 while(X>ld){nrpc++;ls=ld+1;ld+=(nrpc+1)*(nrpc+2)/2;}
17 if(N>=ld)g<<nrpc<<endl;
18 else g<<0<<endl;
19
20 //b)
21 S=0;nrpc=0;nr=1;
22 while(N>S){nrpc++;nr++;S+=nr*(nr+1)/2;}
23 if(N<S){S-=nr*(nr+1)/2;nrpc--;}
24 g<<nrpc<<endl;
25
26 //c)
27 g<<N-S<<endl;
28
29 //d)
30 ls=1;ld=3;nrpc=1;nrc=3;
31 f>>c;K--;//cartonasul alb curent
32 do
33 {
34 while(c>ld)
35 {
36 nrpc++;ls=ld+1;ld+=(nrpc+1)*(nrpc+2)/2;nrca=0;
37 }
38 nrca++;f>>c;K--;if(K==0)nrca++;
39 if(nrca>maxca && ld<=N){maxca=nrca;nrpmax=nrpc;}
40 }
41 while(K>0);
42
43 //afisare
44 g<<nrpmax<<endl;
45
46 f.close();
47 g.close();
48 return 0;
49 }

Listing 7.2.4: pCristina.cpp

1 //piramide - Cristina Sichim


2
3
4 #include <fstream>
5 using namespace std;
6
7 ifstream f("piramide.in");
CAPITOLUL 7. OJI 2014 102

8 ofstream g("piramide.out");
9
10 int n,x,k,p=1,l=2,amax,a,y,pmax=1,prim=1,ultim=3,px;
11
12 int main()
13 { f>>n>>x>>k>>y;
14
15 while(ultim<=n)
16 { if(x>=prim && x<=ultim)px=p;
17
18 while(k && y>=prim && y<=ultim) {a++,k--;if(k)f>>y;}
19
20 if(a>amax) amax=a,pmax=p;
21
22 ++p;++l;a=0;
23 prim=ultim+1; ultim+=l*(l+1)/2;
24 }
25
26 if(n<ultim)p--,ultim=prim-1;
27
28 g<<px<<’\n’<<p<<’\n’<<n-ultim<<’\n’;
29
30 if(amax) g<<pmax<<’\n’;else g<<"0\n";
31
32 f.close();
33 g.close();
34 return 0;
35 }

Listing 7.2.5: pGina.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("piramide.in");
6 ofstream g("piramide.out");
7
8 long N,X,K,c,k,S,i,A,maxa,P,M,piramida,nca,C;
9
10 int main()
11 { f>>N>>X>>K;k=1;
12
13 while(S<=N)
14 { if(P==0 && X<S) P=k-1;
15 S+=(k+1)*(k+2)/2; k++;
16 }
17
18 g<<P<<endl;
19
20 k--;
21 S=S-(k+1)*(k+2)/2;
22 k=k-1; C=N-S;
23
24 g<<k<<endl<<C<<endl;
25 // g<<S<<" k="<<k<<" "<<M<<endl;
26
27 maxa=0;A=0;nca=0;piramida=0;long cf=N-C;S=0;k=1;
28 for(i=1;i<=N;i++)
29 {
30 f>>c;
31 if(S>=c) nca++;
32 else
33 { if(maxa<nca){maxa=nca;A=k-1;}
34
35 while(S<=cf && S<=c)
36 { S+=(k+1)*(k+2)/2; k++;}
37
38 if(c<=S) nca=1; else nca=0;
39 }
40 }
41
42 g<<A<<endl;
43
44 return 0;
CAPITOLUL 7. OJI 2014 103

45 }

Listing 7.2.6: pMarilena.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 int N,K,S,S1,c,nr,ok,pmax,ppmax,vmin,vmax,np,nrc,i,ok1,x;
6
7 ifstream f("piramide.in");
8 ofstream g("piramide.out");
9
10 int main()
11 {
12 f>>N>>x>>K>>c;
13 for(i=2;i<=N;i++)
14 {
15 S1=i*(i+1)/2;
16
17 // piramida i-1 are numerele in intervalul [vmin,vmax]
18 vmin=S+1;vmax=S+S1;
19 S=S+S1;
20
21 //verifica daca se formeaza piramida i-1
22 if(N>=vmin&&N<=vmax){ np=i-2; nrc=N-vmin+1;i=N;ok1=1;}
23
24 if(ok1==0)//daca se formeaza piramida i-1
25 {
26 //verifica daca numarul x este in piramida i-1
27 if(x>=vmin&&x<=vmax)ok=i-1;
28 nr=0;
29
30 //numaram cartonasele albe din piramida i-1
31 while(c>=vmin&&c<=vmax&& !f.eof()){ nr++; f>>c;}
32 if (nr>pmax) {pmax=nr; ppmax=i-1;}
33 }
34 }
35
36 g<<ok<<endl<<np<<endl<<nrc <<endl<<ppmax;
37
38 f.close();
39 g.close();
40
41 return 0;
42 }

Listing 7.2.7: pRaluca.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("piramide.in");
6 ofstream g("piramide.out");
7
8 int n, x, k, c;
9
10 int main()
11 {
12 f>>n>>x>>k;
13
14 int cp=0, cc=3, pas=3, cn=n, pc=1, uc=3,px=0,c1;
15
16 while(cn>=cc)
17 {
18 cn-=cc;
19 cp++;
20 if(x>=pc and x<=uc) px=cp;
21 cc+=pas;
22 pas++;
23 pc=uc+1;
24 uc=pc+cc-1;
25 }
CAPITOLUL 7. OJI 2014 104

26
27 g<<px<<’\n’<<cp<<’\n’<<cn<<’\n’;
28
29 f>>c1;
30 pc=1;uc=3;cc=3;pas=3;
31 int cpp=1;
32
33 while(c1>uc)
34 {
35 cpp++;
36 cc+=pas;
37 pas++;
38 pc=uc+1;
39 uc=pc+cc-1;
40 }
41
42 int max=0, ca=1, pir=0,i;
43
44 for(i=2;i<=k and cpp<=cp;i++)
45 {
46 f>>c1;
47 if(c1<=uc)ca++;
48 else
49 {
50 if(ca>max and cpp<=cp)max=ca, pir=cpp;
51 ca=1;
52 while(c1>uc)
53 {
54 cpp++;
55 cc+=pas;
56 pas++;
57 pc=uc+1;
58 uc=pc+cc-1;
59 }
60 }
61 }
62
63 if(ca>max and cpp<=cp)
64 max=ca, pir=cp;
65
66 g<<pir<<’\n’;
67
68 f.close();
69 g.close();
70
71 return 0;
72 }

7.2.3 *Rezolvare detaliat 


Capitolul 8

OJI 2013

8.1 bete
Problema 1 - bete 100 de puncte
Ana ³i Bogdan au g sit la bunicul lor o cutie cu N beµe de aceea³i lungime. Dup  câteva
minute de joac  urmeaz  cearta. Bunicul le-a propus s  rup  cele N beµe ³i apoi Ana s  primeasc 
fragmentele din mâna stâng , iar Bogdan fragmentele din mâna dreapt . Zis ³i f cut. Copiii au
luat fragmentele, le-au numerotat ecare cu numere de la 1 la N, le-au m surat ³i acum î³i doresc
s  lipeasc  fragmentele primite, dar mai au nevoie de câteva informaµii.

Cerinµe
Cunoscând N num rul de beµe, a1 , a2 , ..., aN lungimile fragmentelor primite de Ana ³i
b1 , b2 , ..., bN lungimile fragmentelor primite de Bogdan, s  se scrie un program care s  determine:
a) lungimea iniµial  a beµelor;
b) lungimea celui mai lung b µ care se poate obµine prin lipirea unui fragment aparµinând Anei
cu un fragment care aparµine lui Bogdan;
c) num rul beµelor de lungime maxim  care se pot obµine prin lipirea unui fragment aparµinând
Anei cu un fragment care aparµine lui Bogdan.

Date de intrare
Fi³ierul de intrare bete.in conµine pe prima linie num rul natural N reprezentµnd num rul de
beµe. Pe a doua linie sunt N numere naturale a1 , a2 , ..., aN reprezentµnd lungimile fragmentelor
primite de Ana ³i pe a treia linie sunt N numere naturale b1 , b2 , ..., bN reprezentµnd lungimile
fragmentelor primite de Bogdan.

Date de ie³ire
Fi³ierul de ie³ire bete.out va conµine trei linii. Pe prima linie se va scrie num rul natural
L reprezentând lungimea iniµial  a beµelor, pe a doua linie se va scrie num rul natural K repre-
zentând lungimea celui mai lung b µ care se poate obµine prin lipirea unui fragment aparµinµnd
Anei cu un fragment care aparµine lui Bogdan, iar pe a treia linie se va scrie num rul natural P
reprezentând num rul beµelor de lungime maxim  care se pot obµine prin lipirea unui fragment
aparµinând Anei cu un fragment care aparµine lui Bogdan.

Restricµii ³i preciz ri
a 1 & N & 1000
a 1 & ai & 10000, (1 & i & N )
a 1 & bi & 10000, (1 & i & N )
a 1 & L & 20000
a 1 & K & 20000
a 1 & P & 1000
a Odat  lipite dou  fragmente, acestea nu se pot dezlipi.
a Pentru determinarea corect  a valorii L se acord  30% din punctaj, pentru determinarea
corect  a valorii K se acord  30% din punctaj, iar pentru determinarea corect  a valorii P se
acord  40% din punctaj.

105
CAPITOLUL 8. OJI 2013 106

Exemple
bete.in bete.out Explicaµii
6 10 Lungimea iniµial  este 10,
2 6 7 1 3 5 16 lungimea maxim  este 16
5 4 7 8 9 3 1 ³i se poate forma un singur b µ de lungime 16.

Timp maxim de executare/test: 0.5 secunde


Memorie: total 2 MB din care pentru stiv  1 MB
Dimensiune maxim  a sursei: 5 KB

8.1.1 Indicaµii de rezolvare


prof. Lucia Miron

Pentru a determina lungimea initiala a betelor $L$ vom determina in $S$ suma
numerelor citite. Apoi evident

\hspace{7mm} L = S div N

Determinam maximul elementelor din sirul a si numarul de aparitii al


maximului, notate maxa si nrmaxa, apoi determinam maximul elementelor
din b si numarul de aparitii al acestuia, notate maxb si nrmaxb. Evident

\hspace{7mm} K = maxa + maxb

\hspace{7mm} nrbetemax = min(nrmaxa, nrmaxb)

Toate datele necesare le determinam la citire, nu este necesara utilizarea


tablourilor

8.1.2 Cod surs 

Listing 8.1.1: bete_OFICIAL.cpp

1 //Lucia Miron
2
3 #include<fstream>
4
5 using namespace std;
6
7 ifstream fin("bete.in");
8 ofstream fout("bete.out");
9
10 int n,l,k,a,b,i,j,s,ma,mb,na,nb;
11
12 int main()
13 {
14 fin>>n;
15 fin>>a;
16
17 ma=a;na=1;s=a;
18 for(i=2;i<=n;i++)
19 {
20 fin>>a;
21 if(ma<a){ma=a;na=1;}
22 else if(ma==a)na++;
23 s+=a;
24 }
25
26 fin>>b;
27 mb=b;nb=1;s+=b;
28
29 for(i=2;i<=n;i++)
30 {
31 fin>>b;
CAPITOLUL 8. OJI 2013 107

32 if(mb<b){mb=b;nb=1;}
33 else
34 if(mb==b) nb++;
35 s+=b;
36 }
37
38 l=s/n;
39
40 fout<<l<<’\n’<<ma+mb<<’\n’<<min(na,nb)<<’\n’;
41 fout.close();
42 return 0;
43 }

Listing 8.1.2: bete_vectori.cpp

1 //octavian dumitrascu
2
3 #include<fstream>
4
5 using namespace std;
6
7 ifstream fin("bete.in");
8 ofstream fout("bete.out");
9
10 int n,l,k,a[1001],b[1001],i,j,s,p;
11
12 int main()
13 {
14 fin>>n;
15 s=0;
16 for(i=1;i<=n;i++)
17 {
18 fin>>a[i];
19 s+=a[i];
20 }
21 for(i=1;i<=n;i++)
22 {
23 fin>>b[i];
24 s+=b[i];
25 }
26
27 l=s/n;
28 k=0;
29
30 for(i=1;i<=n;i++)
31 for(j=1;j<=n;j++)
32 if(a[i]+b[j]>k)
33 k=a[i]+b[j];
34
35 for(i=1;i<=n;i++)
36 for(j=1;j<=n;j++)
37 if(a[i]+b[j]==k)
38 {
39 p++;
40 a[i]=-1;
41 b[j]=-1;
42 };
43
44 fout<<l<<’\n’<<k<<’\n’<<p;
45 fout<<’\n’;
46 fout.close();
47
48 return 0;
49 }

8.1.3 *Rezolvare detaliat 

8.2 chibrituri
Problema 2 - chibrituri 100 de puncte
CAPITOLUL 8. OJI 2013 108

Lui Gigel, elev în clasa a V-a, îi place grozav de tare s  se joace cu


cifrele, cu numerele ³i creeaz  tot felul de probleme pe care apoi încearc 
s  le rezolve. Acum se joac  cu o cutie de chibrituri ³i formeaz  cu ele
cifre. Apoi privirea i-a c zut pe cadranul unui ceas electronic ³i a v zut
Figura 8.1: chibrituri1
c  cifrele sunt formate din segmente orizontale ³i verticale ³i a început s 
formeze cu chibriturile cifrele care indic  ora (vezi gura).
“i imediat ³i-a pus o întrebare: oare dac  am n chibrituri puse vertical ³i m chibrituri puse
orizontal, care este ora minim  pe care o pot forma cu aceste chibrituri

Cerinµe
Fiind date un num r n de chibrituri verticale ³i un num r m de chibrituri orizontale, s  se
scrie un program care determin  num rul de ore posibile, ora minim  ³i ora maxim  care se
pot forma cu aceste chibrituri, în modul indicat mai sus, utilizând toate chibriturile respective ³i
nemodicµnd orientarea acestora.

Date de intrare
Fi³ierul de intrare chibrituri.in conµine pe prima linie dou  numere naturale n m, separate
printr-un spaµiu, indicând num rul de chibrituri verticale (n), respectiv orizontale (m).

Date de ie³ire
Fi³ierul de ie³ire chibrituri.out va conµine pe prima linie num rul de variante posibile de a
forma o or  corect , pe a doua linie ora minim  ce poate  obµinut  utilizând toate chibriturile
³i nemodicând orientarea acestora, iar pe a treia linie ora maxim  ce poate  obµinut  utilizând
toate chibriturile ³i nemodicând orientarea acestora. Ora minim  ³i, respectiv, ora maxim  se
vor scrie sub forma hh  mm, unde ora hh ³i minutul mm vor  formate din exact dou  cifre,
separate prin caracterul : (dou  puncte).

Restricµii ³i preciz ri
Pentru datele de test exist  întotdeauna soluµie. Cifrele sunt formate din chibrituri în felul
urm tor:

Figura 8.2: chibrituri2

Pentru determinarea corect  a num rului de variante se va acorda 20% din punctaj, pentru
determinarea corect  a num rului de variante ³i a orei minime se va acorda 60% din punctaj, iar
pentru determinarea corect  a num rului de variante, a orei minime ³i a orei maxime se va acorda
punctajul maxim.

Exemple
chibrituri.in chibrituri.out Explicaµii
14 10 17 17 variante posibile
00:28 Ora minim : 00:28
20:08 Ora maxim : 20:08

Timp maxim de executare/test: 0.1 secunde


Memorie: total 2 MB din care pentru stiv  1 MB
Dimensiune maxim  a sursei: 5 KB

8.2.1 Indicaµii de rezolvare


prof. Marinel “erban

Numar si retin pentru fiecare cifra numarul de chibrituri verticale si orizontale


necesare.
CAPITOLUL 8. OJI 2013 109

Retinerea valorilor o fac fie intr-un vector, fie in variabile fie ... pe hartie!

Plec de la ora 00:00, adica 0 minute

Marchez faptul ca inca nu am gasit nicio ora corecta

Parcurg toate orele posibile - intr-o zi sunt 24*60 minute

\begin{verbatim}
calculez ora
calculez minutele
calculez prima si a doua cifra a orei
calculez prima si a doua cifra a minutului

numar chibriturile verticale (fie din vector, fie din variabile, fie direct
ca si constante in instructiuni if sau switch)
numar chibriturile orizontale (la fel)

daca am gasit ambele valori corecte


mai am o solutie, o numar
daca este prima gasita aceasta este ora minima, o retin
daca nu este prima am mai gasit solutie deci aceasta este (deocamdata)
ora maxima, o retin
trec la ora (minutul) urmatoare

Asez tinand cont ca daca am doar o solutie, aceasta este si ora maxima

8.2.2 Cod surs 

Listing 8.2.1: chibrituri_OFICIAL.cpp

1 //Serban Marinel - ianuarie 2013


2 //solutie fara utilizarea vectorilor
3
4 #include <fstream>
5
6 using namespace std;
7
8 ifstream fin("chibrituri.in");
9 ofstream fout("chibrituri.out");
10
11 bool OK1;
12 short int t, h1, h2, m1, m2, v, o, vOK, oOK, Cate;
13 short int h1min, h2min, m1min, m2min;
14 short int h1max, h2max, m1max, m2max;
15
16 int main()
17 {
18 fin >> vOK >> oOK;
19 t = 0; //plec de la ora 00:00
20 OK1 = false; //inca nu am gasit nici o ora corecta
21 Cate = 0;
22 while (t < 24 * 60) //intr-o zi sunt 24*60 minute
23 { //trec pe la fiecare
24 m1 = t % 60; //ora
25 h1 = t / 60; //minute
26 h2 = h1 % 10; //a doua cifra a orei
27 h1 = h1 / 10; //prima cifra a orei
28 m2 = m1 % 10; //a doua cifra a minutului
29 m1 = m1 / 10; //prima cifra a minutului
30
31 v = 0; //numar chibrituri verticale
32 switch (h1)
33 {
34 case 1:
35 case 2:
36 case 3:
CAPITOLUL 8. OJI 2013 110

37 case 5:
38 case 7: v += 2; break;
39 case 4:
40 case 6:
41 case 9: v += 3; break;
42 case 0:
43 case 8: v += 4; break;
44 }
45 switch (h2)
46 {
47 case 1:
48 case 2:
49 case 3:
50 case 5:
51 case 7: v += 2; break;
52 case 4:
53 case 6:
54 case 9: v += 3; break;
55 case 0:
56 case 8: v += 4; break;
57 }
58 switch (m1)
59 {
60 case 1:
61 case 2:
62 case 3:
63 case 5:
64 case 7: v += 2; break;
65 case 4:
66 case 6:
67 case 9: v += 3; break;
68 case 0:
69 case 8: v += 4; break;
70 }
71 switch (m2)
72 {
73 case 1:
74 case 2:
75 case 3:
76 case 5:
77 case 7: v += 2; break;
78 case 4:
79 case 6:
80 case 9: v += 3; break;
81 case 0:
82 case 8: v += 4; break;
83 }
84
85 o = 0; //numar chibrituri orizontale
86 switch (h1)
87 {
88 case 1: o += 0; break;
89 case 4:
90 case 7: o += 1; break;
91 case 0: o += 2; break;
92 case 2:
93 case 3:
94 case 5:
95 case 6:
96 case 8:
97 case 9: o += 3; break;
98 }
99 switch (h2)
100 {
101 case 1: o += 0; break;
102 case 4:
103 case 7: o += 1; break;
104 case 0: o += 2; break;
105 case 2:
106 case 3:
107 case 5:
108 case 6:
109 case 8:
110 case 9: o += 3; break;
111 }
112 switch (m1)
CAPITOLUL 8. OJI 2013 111

113 {
114 case 1: o += 0; break;
115 case 4:
116 case 7: o += 1; break;
117 case 0: o += 2; break;
118 case 2:
119 case 3:
120 case 5:
121 case 6:
122 case 8:
123 case 9: o += 3; break;
124 }
125 switch (m2)
126 {
127 case 1: o += 0; break;
128 case 4:
129 case 7: o += 1; break;
130 case 0: o += 2; break;
131 case 2:
132 case 3:
133 case 5:
134 case 6:
135 case 8:
136 case 9: o += 3; break;
137 }
138
139 if (v == vOK && o == oOK) //daca am gasit ambele valori corecte
140 {
141 Cate++; //mai am o solutie, o numar
142 if (!OK1) //prima gasita? deci este ora minima, retin
143 {
144 h1min = h1, h2min = h2, m1min = m1, m2min = m2;
145 OK1 = true;
146 }
147 else //am mai gasit deci este (deocamdata) ora maxima
148 h1max = h1, h2max = h2, m1max = m1, m2max = m2;
149 }
150 t++; //trec la ora (minutul) urmatoare
151 }
152 fout << Cate << ’\n’;
153 fout << h1min << h2min << ’:’ << m1min << m2min << ’\n’;
154 if (Cate == 1) //daca am doar o solutie, aceasta este si ora maxima
155 fout << h1min << h2min << ’:’ << m1min << m2min << ’\n’;
156 else
157 fout << h1max << h2max << ’:’ << m1max << m2max << ’\n’;
158
159 fout.close();
160
161 return 0;
162 }

Listing 8.2.2: chibrituri_v.cpp

1 //Serban Marinel - ianuarie 2013


2 //solutie cu utilizarea vectorilor
3 #include <fstream>
4
5 using namespace std;
6
7 ifstream fin("chibrituri.in");
8 ofstream fout("chibrituri.out");
9
10 int OK1;
11 short int t, h1, h2, m1, m2, v, o, vOK, oOK, Cate;
12 short int h1min, h2min, m1min, m2min;
13 short int h1max, h2max, m1max, m2max;
14
15 short int Vert[] = {4, 2, 2, 2, 3, 2, 3, 2, 4, 3};
16 short int Oriz[] = {2, 0, 3, 3, 1, 3, 3, 1, 3, 3};
17
18 int main()
19 {
20 fin >> vOK >> oOK;
21 t = 0; //plec de la ora 00:00
22 OK1 = 0; //inca nu am gasit nici o ora corecta
CAPITOLUL 8. OJI 2013 112

23 Cate = 0;
24 while (t < 24 * 60) //intr-o zi sunt 24*60 minute
25 { //trec pe la fiecare
26 m1 = t % 60; //ora
27 h1 = t / 60; //minute
28 h2 = h1 % 10; //a doua cifra a orei
29 h1 = h1 / 10; //prima cifra a orei
30 m2 = m1 % 10; //a doua cifra a minutului
31 m1 = m1 / 10; //prima cifra a minutului
32
33 //numar chibrite verticale
34 v = Vert[h1] + Vert[h2] + Vert[m1] + Vert[m2];
35
36 //numar chibrite orizontale
37 o = Oriz[h1] + Oriz[h2] + Oriz[m1] + Oriz[m2];
38
39 if (v == vOK && o == oOK) //daca am gasit ambele valori corecte
40 {
41 Cate++; //mai am o solutie, o numar
42 if (OK1 == 0) //prima gasita? deci este ora minima, retin
43 {
44 h1min = h1, h2min = h2, m1min = m1, m2min = m2;
45 OK1 = 1;
46 }
47 else //am mai gasit deci este (deocamdata) ora maxima
48 h1max = h1, h2max = h2, m1max = m1, m2max = m2;
49 }
50
51 t++; //trec la ora (minutul) urmatoare
52 }
53
54 fout << Cate << ’\n’;
55 fout << h1min << h2min << ’:’ << m1min << m2min << ’\n’;
56 if (Cate == 1) //daca am doar o solutie, aceasta este si ora maxima
57
58 fout << h1min << h2min << ’:’ << m1min << m2min << ’\n’;
59 else
60 fout << h1max << h2max << ’:’ << m1max << m2max << ’\n’;
61
62 fout.close();
63 return 0;
64 }

8.2.3 *Rezolvare detaliat 


Capitolul 9

OJI 2012

9.1 alice
Problema 1 - alice 100 de puncte
Într-o zi frumoas  de var , Alice se juca în parc. Deodat , v zu un
iepure cu ceas, numit Iepurele Alb, s rind gr bit în scorbura unui copac.
Curioas , Alice îl urm ri ³i s ri ³i ea în scorbur . Spre mirarea ei, ajunse
într-o sal  mare cu N u³i încuiate. Pe ecare u³  era scris câte un num r
natural. Într-o clip , lâng  ea ap ru Iepurele Alb ³i-i spuse c  doar u³ile Figura 9.1: alice
cu numere magice pot  deschise dac  are cheile potrivite. Pentru a o
ajuta, Iepurele Alb i-a explicat c  un num r magic este un num r natural
care poate  redus la o cifr  prin complementarea cifrelor acestuia faµ  de cifra sa maxim  din
scrierea zecimal , apoi prin complementarea cifrelor num rului obµinut faµ  de cifra sa maxim 
³i a³a mai departe pân  când se obµine o cifr . Evident, nu toate numerele naturale sunt numere
magice. De exemplu, u³a cu num rul 1234 poate  deschis  cu cheia inscripµionat  cu cifra 1
deoarece 1234 este un num r magic ce poate  redus la cifra 1 prin complement ri repetate
(1234 3210 123 210 12 10 1), iar u³a cu num rul 1204 nu poate  deschis 
deoarece 1204 nu este un num r magic (indiferent de câte ori s-ar repeta complementarea nu
poate  redus la o cifr : 1204 3240 1204 3240 1204.).
Înainte s  dispar , Iepurele Alb îi d du o cheie aurie inscripµionat  cu cifra K ³i o avertiz  c 
poate deschide cu aceast  cheie doar u³ile cu numere magice ce pot  reduse la cifra K.

Cerinµe
Scrieµi un program care s  citeasc  numerele naturale N, K ³i cele N numere naturale scrise
pe cele N u³i, ³i care s  determine:
a) cel mai mare num r par dintre numerele scrise pe cele N u³i;
b) num rul u³ilor care pot  deschise cu cheia aurie inscripµionat  cu cifra K.

Date de intrare
Fi³ierul alice.in conµine:
- pe prima linie cele dou  numere naturale N ³i K, separate printr-un spaµiu;
- pe a doua linie N numere naturale, separate prin câte un spaµiu, reprezentând numerele scrise
pe cele N u³i.

Date de ie³ire
Fi³ierul alice.out va conµine:
- pe prima linie, un num r natural reprezentând cel mai mare num r par dintre numerele scrise
pe cele N u³i;
- pe a doua linie, un num r natural reprezentând num rul u³ilor care pot  deschise cu cheia
aurie inscripµionat  cu cifra K.

Restricµii ³i preciz ri

113
CAPITOLUL 9. OJI 2012 114

- complementarea cifrelor unui num r natural faµ  de cifra sa maxim  din scrierea zecimal 
const  în înlocuirea ec rei cifre c din num r cu diferenµa dintre cifra maxim  ³i cifra c; de
exemplu, cifra maxim  a num rului 1234 este 4 iar prin complementare se înlocuie³te cifra 1 cu
3( 4  1), cifra 2 cu 2( 4  2), cifra 3 cu 1 ( 4  3) ³i cifra 4 cu 0( 4  4) rezultând num rul
3210;
- 7 & N & 10000; 0 & K & 9;
- pe ecare u³  este scris un singur num r natural;
- exist  cel puµin o u³  pe care este scris un num r par;
- num rul scris pe oricare u³  (din cele N) este mai mare sau egal cu 10 ³i mai mic sau egal
cu 32800;
- pentru rezolvarea corect  a cerinµei a) se acord  20% din punctaj, iar pentru rezolvarea
corect  a ambelor cerinµe se acord  100% din punctaj.

Exemple
alice.in alice.out Explicaµii
7 1 1234 a) Sunt N=7 u³i pe care sunt scrise numerele 1204, 1234,
1204 1234 13 195 23 10 888 3 13, 195, 23, 10, 888. Cel mai mare num r par dintre cele
scrise pe u³i este 1234, num r care se va scrie pe prima
linie a ³ierului alice.out.
b) Cheia primit  este inscripµionat  cu cifra K=1 ³i des-
chide 3 u³i cu numerele 1234, 23 ³i 10 deoarece numerele
magice dintre cele scrise pe u³i sunt: 1234 (1234 3210
123 210 12 10 1), 13(13 20 2), 195(195
804 84 4), 23(23 10 1), 10(10 1), 888 (888
0). Num rul 1204 nu este un num r magic. Astfel nu-
m rul 3 se va scrie pe a doua linie a ³ierului alice.out.
Timp maxim de executare/test: 1.0 secunde
Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 10 KB

9.1.1 Indicaµii de rezolvare

Figura 9.2: AliceIR1


CAPITOLUL 9. OJI 2012 115

Figura 9.3: AliceIR2

Figura 9.4: AliceIR3

Figura 9.5: AliceIR4


CAPITOLUL 9. OJI 2012 116

9.1.2 Cod surs 

Listing 9.1.1: alice_CM2.cpp

1 //autor. prof. Carmen Minca


2
3 #include <fstream>
4
5 using namespace std;
6
7 int main()
8 {
9 int x,cmax,c,z,nrmax,i,nc=0,a, maxpar=0,n,j,nr=0,k;
10
11 ifstream f("alice.in");
12 ofstream g("alice.out");
13
14 f>>n>>k;
15 for(j=1;j<=n; j++)
16 {
17 f>>a;
18 z=x=a;
19 if(a%2==0 && maxpar<a)maxpar=a;
20
21 do
22 {
23 a=z; z=x; cmax=0; nc=0;
24 while(x)
25 {
26 c=x%10; x=x/10;nc++;
27 if(c>cmax)cmax=c;
28 }
29
30 nrmax=0;
31 for(i=1;i<=nc;i++)
32 nrmax=nrmax*10+cmax;
33
34 x=nrmax-z;
35 } while(x>9 && x!=z && x!=a);
36
37 if(x==k) nr++;
38 }
39
40 g<<maxpar<<endl<<nr;
41 return 0;
42 }

Listing 9.1.2: alice_CS.cpp

1 //prof. Cristina Sichim


2
3 #include <fstream>
4
5 using namespace std;
6
7 ifstream f("alice.in");
8 ofstream g("alice.out");
9
10 int i,n,x,m,k,nr;
11
12 int vm(int x)
13 {
14 int cmax=0,u=0;
15
16 while(x)
17 {
18 if(x%10>cmax) cmax=x%10;
19 x=x/10;
20 u=u*10+1;
21 }
22
23 return u*cmax;
24 }
CAPITOLUL 9. OJI 2012 117

25
26 int complement(int x)
27 {
28 int nr=0,u;
29
30 while(x>9 && nr<9)
31 {
32 u=vm(x);
33 x=u-x;
34 nr++;
35 }
36
37 if(x>9)return -1;
38 return x;
39 }
40
41 int main()
42 {
43 f>>n>>k;
44 while(n--)
45 {
46 f>>x;
47 if(x%2==0 && x>m) m=x;
48 if(complement(x)==k) nr++;
49 }
50
51 g<<m<<’\n’<<nr<<’\n’;
52 f.close();
53 g.close();
54
55 return 0;
56 }

Listing 9.1.3: alice_SJ.cpp

1 //prof.Sanda Junea
2 #include <iostream>
3 #include<fstream>
4
5 using namespace std;
6
7 ifstream f("alice.in");
8 ofstream g("alice.out");
9
10 int magic(int x);
11
12 int n,k,nr,maxim,x;
13
14 int main(void)
15 {
16 f>>n>>k;
17
18 for( int i = 0; i < n; ++i )
19 {
20 f>>x;
21 if(x%2==0 && x>maxim)
22 maxim=x;
23 if(magic(x)==k)
24 nr++;
25 }
26
27 g<<maxim<<endl;
28 g<<nr;
29
30 f.close();
31 g.close();
32
33 return 0;
34 }
35
36 int magic(int x)
37 {
38 int y=x,m=0,l=x,r=1,zero=0,ok=1,z=x;
39 if(x<10)
40 return x;
CAPITOLUL 9. OJI 2012 118

41 while(l>=10 && ok)


42 {
43 l=0;r=1,m=0;
44 y=x;
45 while(y)
46 {
47 if(y%10>m)
48 m=y%10;
49 y=y/10;
50 }
51
52 y=x;
53 while(y)
54 {
55 l=l+r*(m-y%10);
56 r=r*10;
57 y=y/10;
58 }
59
60 if(l==z)
61 ok=0;
62 else
63 {
64 ok=1;
65 z=x;
66 x=l;
67 }
68 }
69
70 if(l<10)
71 return l;
72 else
73 return -1;
74 }

9.1.3 *Rezolvare detaliat 

9.2 porumb
Problema 2 - porumb 90 de puncte
Locuitorii planetei Agria, numiµi agri, au hot rât ca în celebrul an 2012 s  le explice p mân-
tenilor cum trebuie cules ecient un rând cu n porumbi, numerotaµi, în ordine, cu 1, 2, 3, ..., n.
Cei n porumbi sunt cule³i de mai mulµi agri. Primul agri merge de-a lungul rândului, plecând
de la primul porumb ³i culege primul porumb întâlnit, al treilea, al cincilea ³i a³a mai departe
pân  la cap tul rândului. Atunci când ajunge la cap tul rândului, porne³te al doilea agri ³i culege
porumbi respectând aceea³i regul  ca ³i primul agri.
Metoda se repet  pân  când toµi porumbii sunt cule³i.
P mânteanul Ionel încearc  s  descopere ce ascunde aceast  metod  ³i se gânde³te câµi porumbi
culege primul agri, câµi agri culeg un rând cu n porumbi, la a câta trecere este cules porumbul cu
num rul x ³i care este num rul ultimului porumb cules.
Exemplu: Dac  pe un rând sunt n=14 porumbi atunci sunt 4 agri care culeg porumbii:
a primul agri culege porumbii
1,3,5,7,9,11,13;

a al doilea agri culege porumbii 2,6,10,14;

a al treilea agri culege porumbii 4 ³i 12;

a ultimul agri culege porumbul 8.

Figura 9.6: porumbi


Cerinµe
Pentru a-l ajuta pe Ionel s  descopere secretul acestei metode, scrieµi un program care cite³te cele
dou  numere naturale n ³i x ³i care determin :
CAPITOLUL 9. OJI 2012 119

a) num rul de porumbi cule³i de primul agri;


b) num rul de agri care culeg ³irul de n porumbi;
c) num rul trecerii la care este cules porumbul cu num rul x;
d) num rul ultimului porumb cules.

Date de intrare
Fi³ierul porumb.in conµine pe prima linie, separate printr-un spaµiu, cele dou  numere natu-
rale n ³i x cu semnicaµia din enunµ.

Date de ie³ire
Fi³ierul de ie³ire porumb.out va conµine patru linii:
- pe prima linie se va scrie un num r natural reprezentând num rul de porumbi cule³i de primul
agri;
- pe a doua linie se va scrie un num r natural reprezentând num rul de agri care culeg cei n
porumbi;
- pe a treia linie se va scrie un num r natural, reprezentând num rul trecerii la care este cules
porumbul x;
- pe a patra linie se va scrie un num r natural, reprezentând num rul ultimului porumb cules.

Restricµii ³i preciz ri
- 1 & x & n & 1000000000
- Trecerile se numeroteaz  în ordine, începând cu valoarea 1.
- Pentru rezolvarea corect  a cerinµei a) se acord  10% din punctaj.
- Pentru rezolvarea corect  a cerinµelor a) ³i b) se acord  40% din punctaj.
- Pentru rezolvarea corect  a cerinµelor a), b) ³i c) se acord  70% din punctaj.
- Pentru rezolvarea corect  a celor patru cerinµe se acord  100% din punctaj.

Exemple
porumb.in porumb.out Explicaµii
14 4 7 7 reprezint  num rul de porumbi cule³i de primul agri.
4 Sunt 4 agri care culeg rândul cu n 14 porumbi.
3 Porumbul x 4 este cules la a 3-a trecere iar ultimul
8 porumb cules are num rul 8.

Timp maxim de executare/test: |1.0 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 10 KB

9.2.1 Indicaµii de rezolvare


CAPITOLUL 9. OJI 2012 120

Figura 9.7: porumbIR1

Figura 9.8: P orumbIR2

9.2.2 Cod surs 

Listing 9.2.1: p100_AS.cpp

1 //prof.Adriana Simulescu
2
3 #include<iostream>
4 #include<fstream>
5
6 using namespace std;
7
8 int main()
9 {ofstream out("porumb.out");
10 ifstream in("porumb.in");
11
12 int p=1,n,na=1,x,randx;
13 in>>n>>x;
14 out<<(n+1)/2<<endl;
15
16 while(p<n)
17 {p=p*2;
18 na++;
19 if((x-p)%(p*2)==0) randx= na;
CAPITOLUL 9. OJI 2012 121

20 }
21
22 if(p>n) {p=p/2;na--;}
23
24 if(x%2==1) randx=1;
25 out<<na<<endl<<randx<<endl<<p<<endl;
26
27 in.close();
28 out.close();
29
30 return 0;
31 }

Listing 9.2.2: p100_CL.cpp

1 //prof. Chira Liliana


2 #include<cstdio>
3
4 using namespace std;
5
6 int n,x;
7
8 int main()
9 {
10 int m=1,k=0,nr=0;
11
12 freopen("porumb.in","r",stdin);
13 freopen("porumb.out","w",stdout);
14
15 scanf("%d%d", &n, &x);
16 printf("%d\n", (n+1)/2);
17
18 while(m<=n)
19 m*=2;
20
21 m/=2;
22
23 while(x%2==0)
24 {
25 x/=2;
26 k++;
27 }
28
29 while(n!=0)
30 {
31 nr++;
32 n/=2;
33 }
34
35 printf("%d\n%d\n%d\n", nr , k+1, m);
36
37 return 0;
38 }

Listing 9.2.3: p100_CM1.cpp

1 //prof.Carmen Minca
2
3 #include <fstream>
4 #include <iostream>
5
6 using namespace std;
7
8 int main()
9 {
10 ifstream f("porumb.in");
11 ofstream g("porumb.out");
12
13 int n,x,pas=1,t=0,tx=0,u=0,k=0,m;
14
15 f>>n>>x;
16 g<<(n+1)/2<<endl;
17
18 m=n;
CAPITOLUL 9. OJI 2012 122

19 while(k!=m)
20 { t++; //o noua trecere
21 k=k+(n+1)/2; //nr.porumbi culesi=nr de nr impare <=n
22 //sirul: pas(1,2,3,4,5,6,7), pas=2^(t-1)
23 u=n*pas;
24 if(n%2==0) u-=pas;
25 if(x%pas==0)tx=t;
26 n/=2; pas*=2;
27 }
28 if(x%2)tx=1;
29 g<<t<<endl<<tx<<endl<<u<<endl;
30 }

Listing 9.2.4: p100_CM2.cpp

1 //prof. Carmen Mica - o altfel de solutie


2
3 #include <fstream>
4 #include <iostream>
5 #include <cmath>
6
7 using namespace std;
8
9 int main()
10 {
11 ifstream f("porumb.in");
12 ofstream g("porumb.out");
13
14 int n,x,a,t,ult,u;
15
16 f>>n>>x;
17 g<<(n+1)/2<<endl;
18
19 u=log10(n*1.0)/log10(2.); //u<--log2(n)
20 a=u+1; //a<--2^(u+1)
21 ult=pow(2.0,u); //ult<--2^u
22
23 t=1;
24 while(x%2==0){t++; x>>=1;}
25
26 // x este pe randul care incepe cu
27 // 2^(t-1), t=maximum cu aceasta proprietate
28
29 g<<a<<endl<<t<<endl<<ult<<endl;
30
31 return 0;
32 }

Listing 9.2.5: p100_CS.cpp

1 //autor. prof Cristina Sichim


2
3 # include <fstream>
4
5 using namespace std;
6
7 long n,m,x,nr;
8
9 int main()
10 {ifstream f("porumb.in");
11 ofstream g("porumb.out");
12
13 f>>n>>x;
14
15 //a) nr.porumbi la prima trecere
16 g<<(n+1)/2<<’\n’;
17
18 //b) nr trasee
19 m=n;
20 while(m>0)nr++,m=m/2;
21 g<<nr<<’\n’;
22
23 //c)cand culege porumbul x
24 while(x%2==0) x=x/2,m++;
CAPITOLUL 9. OJI 2012 123

25 g<<m+1<<’\n’;
26
27 //d) ultimul porumb
28 m=1;
29 while(m*2<=n)m=m*2;
30
31 g<<m<<’\n’;
32
33 f.close();
34 g.close();
35 return 0;
36 }

Listing 9.2.6: p100_DT.cpp

1 //prof. Daniela Tarasa


2
3 #include<fstream>
4 #include<math.h>
5
6 using namespace std;
7
8 ifstream f("porumb.in");
9 ofstream g("porumb.out");
10
11 int nr,n,x,nr1=1,aux;
12 long long q;
13
14 int main()
15 {f>>n>>x;
16 aux=x;
17
18 //numarul de porumbi culesi de primul agri
19 if(n%2==0) g<<n/2<<’\n’;else g<<n/2+1<<’\n’;
20
21 //numarul de agri
22 while(n!=0)
23 {
24 n=n/2;
25 nr++;
26 }
27 g<<nr<<’\n’;
28
29 //numarul trecerii la care este cules porumbul x
30 while(x%2==0)
31 {
32 x=x/2;
33 nr1++;
34 }
35 if (aux%2!=0) g<<1<<’\n’;
36 else g<<nr1<<’\n’;
37
38 q=pow(2,nr-1);
39
40 g<<q<<’\n’;
41
42 f.close();
43 g.close();
44 return 0;
45 }

Listing 9.2.7: p100_JIT.cpp

1 //prof. Jakab Irma Tunde


2
3 #include <iostream>
4 #include <fstream>
5 #include <conio.h>
6 #include <math.h>
7
8 using namespace std;
9
10 int main(void)
11 {unsigned long n,x,p=1,e=0,a,b;
CAPITOLUL 9. OJI 2012 124

12
13 fstream f,g;
14 f.open("porumb.in", ios::in);
15 f>>n>>x;
16
17 while (p*2<n)
18 {
19 p*=2;
20 e++;
21 }
22
23 if (x%2)b=1;
24 else
25 {
26 a=p;b=0;
27 while (x%a!=0)
28 {
29 a/=2;
30 b++;
31 }
32 }
33
34 cout<<e+1<<’ ’<<e+1-b<<’ ’<<p;
35
36 g.open("porumb.out", ios::out);
37 g<<(n+1)/2<<endl<<e+1<<endl<<e+1-b<<endl<<p;;
38 g.close();
39 }

9.2.3 *Rezolvare detaliat 


Capitolul 10

OJI 2011

10.1 magic
Problema 1 - magic 100 de puncte
R ma³i singuri în p dure, Hansel ³i Grettel, ³tiu c  singura lor ³ans  de supravieµuire este s 
g seasc  ³i s  intre în Castelul de Turt  Dulce. Poarta castelului este închis  ³i pentru a intra
este nevoie de un cuvânt magic ³i de un num r fermecat.
Zâna cea Bun  îi vede pe copii ³i pentru c  vrea s -i ajute le spune: Mergeµi tot înainte,
iar în drumul vostru o s  întâlniµi copaci pe a c ror trunchiuri sunt scrise caractere reprezentând
litere sau cifre. Cuvântul magic este format din toate caracterele liter  în ordinea în care apar,
dar scrise toate cu majuscule. Num rul fermecat este cel mai mic num r cu cifre distincte care se
poate forma din caracterele cifr .

Cerinµe
Pentru a-i ajuta pe Hansel ³i Grettel s  intre în Castelul de Turt  Dulce, scrieµi un program
care cite³te un num r natural n, apoi n caractere ³i determin :
a) cuvântul magic;
b) num rul fermecat;

Date de intrare
Fi³ierul magic.in conµine pe prima linie un num r natural n, reprezentând num rul de ca-
ractere scrise pe copaci. Pe cea de a doua linie sunt n caractere separate prin câte un spaµiu,
reprezentând caracterele scrise pe copaci.

Date de ie³ire
Fi³ierul de ie³ire magic.out va conµine dou  linii:
a) pe prima linie se va scrie un ³ir de litere mari, reprezentând cuvântul magic;
b) pe a doua linie se va scrie un num r natural cu cifre distincte, reprezentând num rul
fermecat.

Restricµii ³i preciz ri
a 1 & n & 1000
a Caracterele sunt doar cifre sau litere mici ale alfabetului englez.
a Printre cele n caractere se a  întotdeauna cel puțin o liter  ³i cel puµin o cifr .
a Pe ecare copac este scris un singur caracter.
a Num rul magic începe întotdeauna cu o cifr  diferit  de zero.
Pentru rezolvarea cerinµei a) se acord  40% din punctaj, pentru cerinµa b) 60% din punctaj

Exemple
magic.in magic.out Explicaµii
6 CB Cel mai mic num r cu cifre distincte
c 2 5 5 b 2 25 ce se poate obµine este 25.
8 CABD 205 Cel mai mic num r cu cifre distincte
c a 5 0 b 2 5 d ce se poate obµine este 205.

Timp maxim de executare/test: 1.0 secunde


125
CAPITOLUL 10. OJI 2011 126

10.1.1 Indicaµii de rezolvare

Descriere solutie care utilizeaza vector caracteristic:


Se considera vectorul caracteristic c asociat cifrelor de pe a doua linie a sierului, vector
construit astfel:

1, daca cifra i se afla pe a doua linie a fisierului


c[i] =
0, altfel

Prin parcurgerea caracterelor de pe a doua linie a sierului, se determina si se aseaza ca


majuscule caracterele litera si se completeaza vectorul caracteristic.
Numarul cerut se aseaza prin parcurgerea vectorului caracteristic de la stanga la dreapta.
Se trateaza separat cazul in care exista cifra 0.
Daca nu exista cifre nenule, se va asa 0, altfel, aceasta va aparea imediat dupa cifra cea mai
mica, nenula, gasita pe a doua linie a sierului.

Descriere solutie care nu utilizeaza tablouri:

Fiecarei cifre i se asociaza o variabila care sa memoreze aparitia acesteia pe a doua linie a
sierului (0 daca nu apare si 1 daca apare).
Prin parcurgerea caracterelor de pe a doua linie a sierului, se determina si se aseaza ca
majuscule caracterele litera si se actualizeaza variabilele asociate caracterelor de tip cifra.
Numarul cerut se aseaza prin cercetarea continuturilor variabilelor asociate cifrelor.
Se trateaza separat cazul in care exista cifra 0.
Daca nu exista cifre nenule, se va asa 0, altfel, aceasta va aparea imediat dupa cifra cea mai
mica, nenula, gasita pe a doua linie a sierului.

10.1.2 Cod surs 

Listing 10.1.1: CARACTER.CPP

1 #include<iostream>
2 #include<fstream>
3 #include<ctype.h>
4
5 using namespace std;
6
7 char s[1001];
8 int c[10];
9 int n;
10
11 int main()
12 {
13 int i,ncifre=0,j;
14
15 ifstream f("magic.in");
16 ofstream g("magic.out");
17
18 f>>n;
19
20 for(i=1;i<=n;i++)
21 {
22 f>>s[i];
23 s[i]=toupper(s[i]);
24 if(isdigit(s[i]))
25 {
26 ncifre++;
27 c[s[i]-48]++;
28 }
29 }
30
31 for(i=1;i<=n;i++)
32 if(isalpha(s[i]))
33 g<<s[i];
34 g<<’\n’;
35
36 i=1;
CAPITOLUL 10. OJI 2011 127

37 while(c[i]==0) i++;
38
39 if(c[0])
40 g<<i<<0;
41 else
42 g<<i;
43
44 for(j=i+1;j<=9;j++)
45 if(c[j])
46 g<<j;
47
48 f.close();
49 g.close();
50
51 return 0;
52 }

Listing 10.1.2: magic_DM.cpp

1 #include<fstream>
2 #include<ctype.h>
3
4 using namespace std;
5
6 char s;
7 int n;
8 int c0,c1,c2,c3,c4,c5,c6,c7,c8,c9;
9
10 int main()
11 {
12 int i;
13 int nr;
14
15 ifstream f("magic.in");
16 ofstream g("magic.out");
17
18 f>>n;
19
20 for (i=1;i<=n;i++)
21 {
22 f>>s;
23 if(isalpha(s))
24 {
25 s=toupper(s);
26 g<<s;
27 }
28 else
29 {
30 nr=int(s)-48;
31 switch(nr)
32 {
33 case 0: c0++;break;
34 case 1: c1++;break;
35 case 2: c2++;break;
36 case 3: c3++;break;
37 case 4: c4++;break;
38 case 5: c5++;break;
39 case 6: c6++;break;
40 case 7: c7++;break;
41 case 8: c8++;break;
42 case 9: c9++;break;
43 }
44 }
45 }
46 g<<’\n’;
47
48 int t=0;
49
50 if(c1)
51 {
52 g<<1;
53 if(c0 && t==0)
54 {
55 t=1;
56 g<<0;
CAPITOLUL 10. OJI 2011 128

57 }
58 }
59
60 if(c2)
61 {
62 g<<2;
63 if(c0 && t==0)
64 {
65 t=1;
66 g<<0;
67 }
68 }
69
70 if(c3)
71 {
72 g<<3;
73 if(c0 && t==0)
74 {
75 t=1;
76 g<<0;
77 }
78 }
79
80 if(c4)
81 {
82 g<<4;
83 if(c0 && t==0)
84 {
85 t=1;
86 g<<0;
87 }
88 }
89
90 if(c5)
91 {
92 g<<5;
93 if(c0 && t==0)
94 {
95 t=1;
96 g<<0;
97 }
98 }
99
100 if(c6)
101 {
102 g<<6;
103 if(c0 && t==0)
104 {
105 t=1;
106 g<<0;
107 }
108 }
109
110 if(c7)
111 {
112 g<<7;
113 if(c0 && t==0)
114 {
115 t=1;
116 g<<0;
117 }
118 }
119
120 if(c8)
121 {
122 g<<8;
123 if(c0 && t==0)
124 {
125 t=1;
126 g<<0;
127 }
128 }
129
130 if(c9)
131 {
132 g<<9;
CAPITOLUL 10. OJI 2011 129

133 if(c0 && t==0)


134 {
135 t=1;
136 g<<0;
137 }
138 }
139
140 if(t==0 && c0)
141 g<<0;
142
143 f.close();
144 g.close();
145
146 return 0;
147 }

Listing 10.1.3: MAGIC_S.CPP

1 #include <fstream>
2
3 using namespace std;
4
5 int x[10];
6
7 int main()
8 {
9 ifstream fin("magic.in");
10 ofstream fout("magic.out");
11
12 int n, g = 0, i;
13 char c;
14
15 fin >> n;
16
17 for( i = 1; i <= n; i++)
18 {
19 fin >> c;
20 if(’a’<= c && c <= ’z’)
21 {
22 c = c - 32;
23
24 fout << c;
25 }
26 else
27 {
28 x[c-48]++;
29 g = 1;
30 }
31 }
32
33 fout<<’\n’;
34
35 i = 1;
36 while(x[i] == 0)i++;
37
38 if(i <= 9) fout <<i, x[i] = 0;
39
40 for(i = 0; i <= 9; i++)
41 if(x[i]) fout << i;
42 fout << ’\n’;
43
44 fin.close();
45 fout.close();
46
47 return 0;
48 }

Listing 10.1.4: magicAna.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("magic.in");
CAPITOLUL 10. OJI 2011 130

6 ofstream g("magic.out");
7
8 int n,i;
9 char c;
10 int x[10];
11
12 int main()
13 {
14 f>>n;
15 for(i=1;i<=n;i++)
16 {
17 f>>c;
18 if(c>=’a’ && c<=’z’) g<<(char)(c-32);
19 else x[c-48]=1;
20 }
21 g<<’\n’;
22
23 if(x[0]!=0)
24 {
25 i=1;
26 while(x[i]==0 && i<=9)i++;
27 }
28
29 if(i<=9){g<<i;x[i]=0;}
30
31 for(i=0;i<=9;i++)
32 if(x[i]) g<<i;
33
34 f.close();
35 g.close();
36
37 return 0;
38 }

Listing 10.1.5: MAGICDT3.CPP

1 #include<fstream>
2
3 using namespace std;
4
5 ifstream f("magic.in");
6 ofstream g("magic.out");
7
8 long nr,nr_fin,m; int x0,x1,x2,x3,x4,x5,x6,x7,x8,x9;
9
10 int main()
11 {
12 int n,i; char x;
13
14 f>>n;
15 for(i=1;i<=n;i++)
16 {
17 f>>x;
18 if (!(x>=’0’ && x<=’9’)) g<<(char)(x-32);
19 else
20 switch (x)
21 {
22 case ’0’:x0++; break;
23 case ’1’: x1++; break;
24 case ’2’: x2++; break;
25 case ’3’: x3++; break;
26 case ’4’: x4++; break;
27 case ’5’: x5++; break;
28 case ’6’: x6++; break;
29 case ’7’: x7++; break;
30 case ’8’: x8++; break;
31 case ’9’: x9++; break;
32 }
33 }
34
35 if(x1!=0 &&x0!=0) {nr=(nr*10+1)*10;x0=0;}
36 else if(x1!=0) nr=nr*10+1;
37
38 if(x2!=0 &&x0!=0) {nr=(nr*10+2)*10;x0=0;}
39 else if (x2!=0) nr=nr*10+2;
CAPITOLUL 10. OJI 2011 131

40
41 if(x3!=0 &&x0!=0) {nr=(nr*10+3)*10;x0=0;}
42 else if(x3!=0) nr=nr*10+3;
43
44 if(x4!=0 &&x0!=0) {nr=(nr*10+4)*10;x0=0;}
45 else if(x4!=0) nr=nr*10+4;
46
47 if(x5!=0 &&x0!=0) {nr=(nr*10+5)*10;x0=0;}
48 else if(x5!=0) nr=nr*10+5;
49
50 if(x6!=0 &&x0!=0) {nr=(nr*10+6)*10;x0=0;}
51 else if(x6!=0) nr=nr*10+6;
52
53 if(x7!=0 &&x0!=0) {nr=(nr*10+7)*10;x0=0;}
54 else if(x7!=0) nr=nr*10+7;
55
56 if(x8!=0 &&x0!=0) {nr=(nr*10+8)*10;x0=0;}
57 else if(x8!=0) nr=nr*10+8;
58
59 if(x9!=0 &&x0!=0) {nr=(nr*10+9)*10;x0=0;}
60 else if(x9!=0) nr=nr*10+9;
61
62 if(nr==0) g<<’\n’<<0<<’\n’;
63 else g<<’\n’<<nr<<’\n’;
64
65 f.close();
66 g.close();
67 return 0;
68 }

10.1.3 *Rezolvare detaliat 

10.2 numerus
Problema 2 - numerus 100 de puncte
La ora de matematic  distractiv , domnul profesor Numerus
propune elevilor s i s  completeze cu numere naturale o gril  cu 6
coloane numerotate cu literele A, B, C, D, E ³i F ³i cu un num r
innit de linii. Grila va  completat  cu numere naturale, înce-
pând cu num rul 1. Pe liniile impare completarea se va face de la
stânga la dreapta, iar pe cele pare de la dreapta la stânga. Ultimul
num r de pe o linie va  identic cu penultimul num r (în sensul
complet rii) de pe aceea³i linie. în gura al turat  aveµi comple-
tate primele 7 linii ale grilei. Deoarece pe tabl  sau pe o foaie
de hârtie num rul de linii este limitat, deci grila poate  efectiv
completat  doar pentru un num r mic de linii, domnul profesor
Figura 10.1: Numerus
Numerus dore³te ca elevii s i s  determine, cu ajutorul calcula-
torului, imaginea unei anumite linii a grilei ³i locul sau locurile pe care se poate aa un num r
natural dat

Cerinµe
Deduceµi regula dup  care se completeaz  linia k a grilei ³i scrieµi un program care s  citeasc 
numerele naturale k ³i n ³i care s  determine:
a) numerele naturale de pe linia k, vizualizate de la stânga la dreapta;
b) linia pe care se a  în gril  num rul natural n;
c) coloana sau coloanele pe care se a  în gril  num rul natural n.

Date de intrare
Fi³ierul numerus.in conµine o singur  linie pe care sunt scrise dou  numere naturale k ³i n,
separate pritr-un spaµiu.

Date de ie³ire
CAPITOLUL 10. OJI 2011 132

Fi³ierul de ie³ire numerus.out va conµine 3 linii:


a) pe prima linie, se vor scrie numerele de pe linia k a grilei;
b) pe a doua linie, se va scrie un num r natural reprezentând linia pe care se a  în gril 
num rul natural n;
c) pe a treia linie, se va scrie litera sau literele care reprezint  coloana, respectiv coloanele pe
care se a  în gril  num rul natural n; În situaµia în care avem de a³at dou  litere acestea se vor
a³a cu un spaµiu între ele.

Restricµii ³i preciz ri
a Numerele k ³i n sunt naturale nenule
a 5 & k $ 200000000
a 1 & n & 999999999
Pentru rezolvarea cerinµei a) se acord  40% din punctaj, pentru cerinµa b) 30% din punctaj ³i
pentru cerinµa c) 30% din punctaj.

Exemple

Figura 10.2: Numerus - exemple

Timp maxim de executare/test: 1.0 secunde

10.2.1 Indicaµii de rezolvare


a) Numerele de pe linia k sunt:

5* k-4, 5* k-3, 5* k-2, 5* k-1, 5* k, 5*k, daca linia k este impara si


5* k, 5*k, 5* k-1, 5* k-2, 5* k-3, 5* k-4, daca linia k este para

b) Linia pe care se afla numarul n este:

n/5, daca n este multiplu de 5 si


[n/5]+1, altfel

c) Coloana/coloanele pe care se afla numarul n este/sunt:

A B, daca ultima cifra a lui n este 0


A, daca ultima cifra a lui n este 1
B, daca ultima cifra a lui n este 2
C, daca ultima cifra a lui n este 3 sau 9
D, daca ultima cifra a lui n este 4 sau 8
E, daca ultima cifra a lui n este 7
F, daca ultima cifra a lui n este 6
E F, daca ultima cifra a lui n este 5

10.2.2 Cod surs 

Listing 10.2.1: A1_Numer.cpp

1 #include<fstream>
CAPITOLUL 10. OJI 2011 133

2
3 using namespace std;
4
5 ifstream f("numerus.in");
6 ofstream g("numerus.out");
7
8 long n,i,k,a,b,l,c;
9
10 int main()
11 {
12 f>>k>>n;
13 a=5*(k-1)+1;
14 b=5*k;
15 if(k%2==1)
16 {
17 for(i=a;i<=b;i++) g<<i<<’ ’;
18 g<<b;
19 }
20 else
21 {
22 g<<b<<’ ’;
23 for(i=b;i>=a;i--) g<<i<<’ ’;
24 }
25 g<<’\n’;
26
27 l=n/5;
28 if(n%5!=0)l++;
29 g<<l<<’\n’;
30
31 if(n%5==0)
32 if(l%2==0) g<<’A’<<’ ’<<’B’;
33 else g<<’E’<<’ ’<<’F’;
34 else if(l%2==1) {char c=’A’+n%5-1;g<<c;}
35 else{char c=’F’-n%5+1;g<<c;}
36 g<<’\n’;
37
38 f.close();
39 g.close();
40
41 return 0;
42 }

Listing 10.2.2: D_NUMERU.CPP

1 #include<fstream>
2
3 using namespace std;
4
5 ifstream f("numerus.in");
6 ofstream g("numerus.out");
7
8 long n,k;
9
10 int main()
11 {
12 long lin;
13 f>>k>>n;
14
15 lin=n/5;
16
17 //prima cerinta
18 if(k%2==0)
19 g<<5*k<<’ ’<<5*k<<’ ’<<5*k-1<<’ ’<<5*k-2<<’ ’<<5*k-3<<’ ’<<5*k-4<<’\n’;
20 else
21 g<<5*k-4<<’ ’<<5*k-3<<’ ’<<5*k-2<<’ ’<<5*k-1<<’ ’<<5*k<<’ ’<<5*k<<’\n’;
22
23 //a doua cerinta
24 if(n%5==0) g<<lin<<’\n’;
25 else {lin++;g<<lin<<’\n’;}
26
27 // a treia cerinta
28 if(lin%2==0)
29 if(n%5==0) g<<’A’<<’ ’<<’B’;
30 else g<<(char)(’B’+(5-n%5));
31 else if(n%5==0) g<<’E’<<’ ’<<’F’;
CAPITOLUL 10. OJI 2011 134

32 else g<<(char)(’E’-(5-n%5));
33 g<<’\n’;
34
35 f.close();
36 g.close();
37 return 0;
38 }

Listing 10.2.3: S_Numeru.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 int main()
6 {
7 long k, n;
8 long i, r, rd;
9
10 ifstream fin("numerus.in");
11 ofstream fout("numerus.out");
12
13 fin >> k >> n;
14
15 if(k % 2 == 1)
16 {
17 for(i = 1; i<= 5; i++)
18 fout << (k-1)*5 +i<< " ";
19 fout << k *5<<"\n";
20 }
21 else
22 {
23 fout << k*5<< " ";
24 for(i = 0; i< 5; i++)
25 fout << k * 5 - i<< " ";
26 fout << "\n";
27 }
28
29 if( n%5 == 0)
30 {
31 rd = n/5;
32 fout <<rd<<’\n’;
33 }
34 else
35 {
36 rd = (n/5 +1);
37 fout << rd<< "\n";
38 }
39
40 if(n%10 == 0 )
41 fout << ’A’<<" "<<’B’<<"\n";
42 else
43 if(n%5 == 0) fout << ’E’<<" "<<’F’<< "\n";
44
45 if(rd % 2 == 1)
46 {
47 r = n%5;
48 switch(r)
49 {
50 case 1: fout << ’A’<<"\n";break;
51 case 2: fout << ’B’<<"\n";break;
52 case 3: fout << ’C’<<"\n";break;
53 case 4: fout << ’D’<<"\n";break;
54 }
55 }
56 else
57 {
58 r = n%5;
59 switch(r)
60 {
61 case 1: fout << ’F’<<"\n";break;
62 case 2: fout << ’E’<<"\n";break;
63 case 3: fout << ’D’<<"\n";break;
64 case 4: fout << ’C’<<"\n";break;
65 }
CAPITOLUL 10. OJI 2011 135

66 }
67
68 fin.close();
69 fout.close();
70
71 return 0;
72 }

10.2.3 *Rezolvare detaliat 


Capitolul 11

OJI 2010

11.1 sir
Problema 1 - sir 100 de puncte
Se genereaz  un ³ir de numere naturale ai c rui primi termeni sunt, în ordine:

1, 12, 21, 123, 231, 312, 1234, 2341, 3412, 4123, 12345, 23451, ...

Cerinµe
Deduceµi regula dup  care sunt generaµi termenii ³irului ³i scrieµi un program care s  citeasc 
numerele naturale k , x, a ³i b ³i care s  determine:
a) ultima cifr  a sumei tuturor termenilor ³irului care sunt formaµi din cel mult k cifre;
b) succesorul termenului x în ³irul dat, x ind un termen al ³irului;
c) num rul de termeni ai ³irului care au cifra cea mai semnicativ  egal  cu a ³i nu conµin în
scrierea lor cifra b.

Date de intrare
Fi³ierul de intrare sir.in conµine o singur  linie pe care sunt scrise cele patru numere naturale k,
x, a ³i b, separate prin câte un spaµiu.

Date de ie³ire
Fi³ierul de ie³ire sir.out va conµine 3 linii:
- pe prima linie se va scrie un num r natural reprezentând ultima cifr  a sumei tuturor terme-
nilor ³irului care sunt formaµi din cel mult k cifre;
- pe a doua linie se va scrie un num r natural reprezentând succesorul termenului x în ³irul
dat;
- pe a treia linie se va scrie un num r natural reprezentând num rul de termeni ai ³irului care
au cifra cea mai semnicativ  egal  cu a ³i nu conµin în scrierea lor cifra b.

Restricµii ³i preciz ri
a Numerele k , x, a ³i b sunt naturale nenule
a 1&k&9
a x este un termen al ³irului din enunµ ³i are succesor în ³ir
a succesorul termenului x în ³ir este termenul care urmeaz  imediat dup  x (de exemplu, dac 
x 2341 atunci succesorului lui x în ³ir este 3412)
a 1 & x $ 900000000
a 1 & a & 9; 1 & b & 9; a j b
a cifra cea mai semnicativ  a unui num r natural este prima cifr  din scrierea sa, de la stânga
la dreapta (de exemplu cifra cea mai semnicativ  a num rului 32156 este 3)
a Pentru rezolvarea cerinµei a) se acord  30% din punctaj, pentru cerinµa b) 40% din punctaj
³i pentru cerinµa c) 30% din punctaj.

136
CAPITOLUL 11. OJI 2010 137

Exemple
sir.in sir.out Explicaµii
3 45123 3 6 0 Termenii ³irului formaµi ecare din cel mult k 3 cifre sunt:
51234 1, 12, 21, 123, 231, 312. Suma lor ind egal  cu 700, pe
3 prima linie a ³ierului sir.out se va scrie cifra 0 (ultima cifr 
a sumei).
Succesorul termenului 45123 este 51234, valoare care se va
scrie pe a doua linie a ³ierului sir.out.
Sunt 3 numere care încep cu cifra 3 ³i care nu conµin cifra 6
³i anume: 312, 3412, 34512. Astfel, num rul 3 se scrie pe a
treia linie a ³ierului sir.out.
Timp maxim de executare/test: 1.0 secunde

11.1.1 Indicaµii de rezolvare

Figura 11.1: sirir1

Figura 11.2: sirir2


CAPITOLUL 11. OJI 2010 138

Figura 11.3: sirir3

Figura 11.4: sirir4

Figura 11.5: sirir5


CAPITOLUL 11. OJI 2010 139

11.1.2 Cod surs 

Listing 11.1.1: sir.CPP

1 /* autor prof. Minca Carmen


2 Liceul Teoretic "Ion Neculce" Bucuresti */
3
4 #include<fstream>
5
6 using namespace std;
7
8 int main()
9 {ofstream g("sir.out");
10 long x,y,p=1,z;
11 int k,s=0,a,b,i,c,sa;
12 ifstream f("sir.in");
13
14 f>>k>>x>>a>>b;
15
16 s=1; sa=1;
17 for(i=2;i<=k;i++)
18 {
19 s=(s+sa+i)%10;
20 sa=(sa+i)%10;
21 }
22 g<<s<<endl;
23
24 //cerinta b)
25
26 y=x; k=1;
27 while(y>9)
28 { k++; y/=10; p=p*10; }
29
30 if(y==k)
31 { z=0;
32 for(i=1;i<=k+1; i++)
33 z=z*10+i;
34 }
35 else z=(x%p)*10+y;
36
37 g<<z<<endl;
38
39 //cerinta c)
40
41 if(a<b) g<<b-a;
42 else g<<0;
43
44 f.close();
45 g.close();
46
47 return 0;
48 }

Listing 11.1.2: sirana.cpp

1 //sursa 100p prof. Ana Intuneric


2 //CN Ferdinand Bacau
3
4 #include <fstream>
5
6 using namespace std;
7
8 unsigned long s[]={1,12,21,123,231,312,
9 1234,2341,3412,4123,12345,23451,34512,45123,51234,
10 123456,234561,345612,456123,561234,612345,
11 1234567,2345671,3456712,4567123,5671234,6712345,7123456,
12 12345678,23456781,34567812,45678123,56781234,67812345,78123456,81234567,
13 123456789,234567891,345678912,456789123,567891234,678912345,789123456,
14 891234567,912345678};
15
16 unsigned k,a,b,uc,i,nr;
17 unsigned long x;
18
CAPITOLUL 11. OJI 2010 140

19 ifstream f("sir.in");
20 ofstream g("sir.out");
21
22 int main()
23 {
24 f>>k>>x>>a>>b;
25
26 //a)
27 for(i=0;i<k*(k+1)/2;i++)
28 uc=(uc+s[i]%10)%10;
29 g<<uc<<’\n’;
30
31 //b)
32 i=0;
33 while(s[i]<=x) i++;
34 g<<s[i]<<’\n’;
35
36 //c)
37 if(a<b)g<<(9-a+1)-(9-b+1);
38 else g<<0;
39
40 f.close();
41 g.close();
42 return 0;
43 }

Listing 11.1.3: SIRcris.CPP

1 // prof.Cristina Sichim
2 // Colegiul National Ferdinand Bacau
3
4 # include <fstream>
5 # include <math.h>
6
7 using namespace std;
8
9 int k,a,b,u,i,c;
10 long x,y,p;
11
12 int main()
13 { ifstream f("sir.in");
14 ofstream g("sir.out");
15 f>>k>>x>>a>>b;
16
17 //a
18 u=0;
19 for(i=1;i<=k;i++) u=(u+i*(i+1)/2)%10;
20 g<<u<<endl;
21
22 //b
23 u=0;y=x;
24 while(y){u++;c=y%10; y=y/10;}
25
26 if(c==u)
27 for(i=1;i<=u+1;i++)y=y*10+i;
28 else
29 {
30 p=pow(10,u-1);
31 y=x%p*10+x/p;
32 }
33 g<<y<<endl;
34
35 //c
36 c=(b>a)?b-a:0;
37 g<<c;
38
39 f.close();
40 g.close();
41
42 return 0;
43 }

Listing 11.1.4: SIRcris2.CPP


CAPITOLUL 11. OJI 2010 141

1 #include <fstream>
2
3 using namespace std;
4
5 int k,a,b,u,i,n,v[11];
6 long x;
7
8 int main()
9 { ifstream f("sir.in");
10 ofstream g("sir.out");
11 f>>k>>x>>a>>b;
12
13 //a
14 u=0;
15 for(i=1;i<=k;i++) u=(u+i*(i+1)/2)%10;
16 g<<u<<endl;
17
18 //b
19 n=0;
20 while(x){n++;v[n]=x%10;x=x/10;}
21 if(v[n]==n)
22 for(i=1;i<=n+1;i++)g<<i;
23 else
24 {
25 for(i=n-1;i>=1;i--) g<<v[i];
26 g<<v[n];
27 }
28
29 g<<endl;
30
31 //c
32 u=(b>a)?b-a:0;
33 g<<u;
34
35 f.close();
36 g.close();
37
38 return 0;
39 }

Listing 11.1.5: SIRcris2.CPP

1 //prof Dana Marcu - Suceava


2
3 #include<fstream>
4
5 using namespace std;
6
7 ifstream f("sir.in");
8 ofstream g("sir.out");
9
10 int main()
11 {
12 int k,a,b;
13 long x;
14 f>>k>>x>>a>>b;
15
16 //punctul a)
17 int i,uc=0;
18 uc=(k*(k+1)*(k+2)/6)%10;
19 g<<uc<<"\n";
20
21 //punctul b)
22 long aux=x,p=1;
23 int nrcif=0,pc;
24 uc=x%10;
25 while(aux)
26 {
27 nrcif++;
28 p=p*10;
29 aux=aux/10;
30 }
31 p=p/10;
32 if(x>1)
33 {
CAPITOLUL 11. OJI 2010 142

34 if(nrcif-1==uc)
35 for(i=1;i<=nrcif+1;i++)
36 g<<i;
37 else
38 g<<(x%p)*10+x/p;
39 }
40 else
41 g<<"12";
42
43 g<<"\n";
44
45 //punctul c)
46
47 if(b<=a)
48 g<<"0";
49 else
50 g<<b-a;
51 return 0;
52 }

Listing 11.1.6: SIRVECT.CPP

1 //autor. prof Carmen Minca - Bucuresti


2
3 #include <fstream>
4
5 using namespace std;
6
7 int main()
8 { long x; int v[10];
9 int k,i,s=0,a,b;
10
11 ifstream f("sir.in");
12 ofstream g("sir.out");
13
14 f>>k>>x>>a>>b;
15
16 for(s=1,i=2;i<=k;i++)
17 s=(s+i*(i+1)/2)%10;
18 g<<s<<endl;
19
20 k=0;
21 while(x)
22 {
23 k++; v[k]=x%10; x=x/10;
24 }
25
26 if(v[k]==k)
27 for(i=1;i<=k+1;i++)
28 g<<i;
29 else
30 { v[0]=v[k];
31 for(i=k-1;i>=0;i--)
32 g<<v[i];
33 }
34
35 if(a<b)g<<endl<<b-a;
36 else g<<endl<<0;
37
38 g.close();
39
40 return 0;
41 }

11.1.3 *Rezolvare detaliat 

11.2 tren
Problema 2 - tren 100 de puncte
CAPITOLUL 11. OJI 2010 143

Un elev în clasa a V-a, Rare³, s-a gândit s  studieze mersul trenurilor ce trec prin gara din
ora³ul s u, într-o zi. Gara are 2 linii, numerotate cu 1 ³i 2, pe care sosesc ³i pleac  trenurile. În
acea zi, în gar  sosesc T trenuri. Pentru ecare tren din cele T, Rare³ cunoa³te linia L pe care
va sosi, momentul sosirii, adic  ora H ³i minutul M, precum ³i durata de timp S de staµionare
(exprimat  în minute). El a decis ca perioada de studiu a celor T trenuri s  înceap  cu momentul
sosirii primului tren în gar  din cele T ³i s  se încheie odat  cu momentul plec rii ultimului tren
din cele T.
Din sala de a³teptare Rare³ poate vedea cele 2 linii. Rare³ are îns  o problem : atunci când
un tren se a  în gar  pe linia 1, el nu poate vedea trenul staµionat în acela³i timp pe linia 2.
De exemplu, dac  un tren ajunge în gar  pe linia 1 la ora 14  21 ³i staµioneaz 5 minute atunci
trenul va pleca din gar  la ora 14  26. Astfel, în intervalul de timp 14  21  14  26, Rare³ nu
poate vedea ce se întâmpl  pe linia 2. Trenul de pe linia 2 va putea  vizibil începând cu minutul
urm tor, adic  de la 14  27.

Cerinµe
Scrieµi un program care s  determine pentru un num r T de trenuri care trec prin gar  în
perioada de studiu din acea zi:
a num rul maxim de trenuri Z care au staµionat pe aceea³i linie;
a num rul X de trenuri pe care Rare³ le vede;
a durata de timp maxim  Y (exprimat  în num r de minute consecutive), din perioada de
studiu, în care Rare³ nu a v zut niciun tren.

Date de intrare
Fi³ierul de intrare tren.in conµine pe prima linie num rul T de trenuri ³i pe ecare din ur-
m toarele T linii, în ordinea sosirii trenurilor în gar , câte patru numere naturale L, H , M ³i S,
separate prin câte un spaµiu, ce reprezint  linia L pe care sose³te trenul, momentul sosirii trenului
(ora H ³i minutul M) ³i durata de timp S de staµionare.

Date de ie³ire
Fi³ierul de ie³ire tren.out conµine pe prima linie, separate prin câte un spaµiu, valorile cerute
Z, X ³i Y (în aceast  ordine).

Restricµii ³i preciz ri
- 2&T & 100; 0 & H & 23; 0 & M & 59; 1 & S & 9; T , H , M , S sunt numere naturale;
- în acela³i moment de timp nu pot pleca/sosi mai multe trenuri;
- în acela³i moment de timp nu poate pleca un tren ³i altul s  soseasc ;
- pe aceea³i linie nu pot staµiona mai multe trenuri în acela³i moment de timp;
- pentru aarea corect  a num rului Z se acord  20% din punctajul pe test;
- pentru aarea corect  a num rului X se acord  40% din punctajul pe test;
- pentru aarea corect  a num rului Y se acord  40% din punctajul pe test.

Exemple
tren.in tren.out Explicaµii
8 5 5 11 Pe linia 1 3 trenuri, iar pe linia 2 au staµionat 5 trenuri,
au staµionat
1 14 20 3 astfel Z 5. 14  20 Rare³ vede trenul care ajunge pe linia 1
La ora
2 14 21 1 ³i va staµiona pân  la ora 14  23. El nu vede trenul care ajunge pe
2 14 24 4 linia 2 la ora 14  21 ³i pleac  la 14  22. El vede trenul care ajunge pe
1 14 40 8 linia 2 la 14  24 pentru c  în momentul sosirii nu se a  tren pe linia
2 14 41 1 1. De asemenea, el vede trenul care ajunge la 14  40 pe linia 1, dar
2 14 43 1 nu vede urm toarele 2 trenuri care ajung pe linia 2 întrucât trenul de
2 14 45 5 pe linia 1 pleac  la 14  48. Vede ³i ultimul tren de pe linia 2 pentru
1 14 56 1 c  el sose³te înainte de plecarea trenului de pe linia 1 ³i pleac  dup 
acesta. în total a v zut 5 trenuri.
în intervalele de timp 14  29  14  39 ³i 14  51  14  55,
Rare³ nu vede niciun tren, durata de timp maxim  ind de 11 minute
(determinat  de trenul care pleac  la 14  28 ³i urm torul tren care
sose³te la 14  40).
CAPITOLUL 11. OJI 2010 144

Timp maxim de executare/test: 1.0 secunde

11.2.1 Indicaµii de rezolvare


prof. Cristina Sichim, Colegiul National Ferdinand- Bacau

a) Solutia cu vectori retine in vectorul g starea ecarui minut de pe parcursul unei zile.
In ecare moment Rares vede cel mult un tren.
Vectorul v, retine starea ecarui tren care a trecut prin gara.

# include <fstream.h>
ifstream fi("tren.in"); ofstream fo("tren.out");
int x,t,y,z,u,t1,l,h,m,s,i,j,vine,pleaca,g[1441],v[101],inc=1441,sf;

void main()
{ fi>>t;
for(i=1;i<=t;i++)
{ fi>>l>>h>>m>>s;
vine=h*60+m;pleaca=vine+s;
if(i==1)inc=vine;
if(sf<pleaca) sf=pleaca;
if(l==1) { t1++; for(j=vine;j<=pleaca;j++)g[j]=i;}
else
for(j=vine;j<=pleaca;j++)if(g[j]==0)g[j]=i;
//trenul de pe linia 2 este vizibil numai daca nu avem tren pe linia 1
}

z=(t1>t-t1)?t1:t-t1; //numarul maxim de trenuri de pe o linie


y=0;
for(i=inc;i<=sf;i++)
{ v[g[i]]=1; //trenul care se afla in momentul i in gara este vizibil
if(g[i]==0) u++; //u=numarul de minute consecutive in care
//ambele linii sunt libere
else { if(u>y)y=u;
u=0;
}
}
x=0;
for(i=1;i<=t;i++) x=x+v[i];
fo<<z<<’ ’<<x<<’ ’<<y;
fi.close();fo.close();
}

b) Solutia fara vectori memoreaza in t1 numarul de trenuri care ajung pe linia 1 si actualizeaza
pentru ecare tren sosit valorile x, y si z. Un tren care ajunge pe linia 1 va  intotdeauna vizibil.
Un tren care ajunge pe linia 2 va  vizibil daca in timpul stationarii exista cel putin un minut in
care linia 1 nu este ocupata.
Pentru determinarea intervalului maxim in care ambele linii sunt libere trebuie sa calculam
cea mai mare diferenta dintre momentul in care a plecat un tren si a sosit altul si in tot acest timp
liniile au fost libere.

# include <fstream.h>

ifstream f("tren.in");
ofstream g("tren.out");

int x=1,t,y,z,t1,l,h,m,sta,s,p,am2,i,p1,p2,u;

void main()
{ f>>t;
f>>l>>h>>m>>sta;
u=h*60+m+sta;
CAPITOLUL 11. OJI 2010 145

if(l==1) t1++,p1=u;
else p2=u;
for(i=2;i<=t;i++)
{ f>>l>>h>>m>>sta;
s=h*60+m; p=s+sta; //s-momentul sosirii, p-momentul plecarii
if(s-u>y) y=s-u;
if(s>p1+1 && am2==1 && p2>p1) x++,am2=0;
// vad trenul care se afla acum pe linia 2
if(l==1) x++,t1++,p1=p;
else
if (s>p1) x++,am2=0,p2=p;
// vine un tren pe linia 2 si linia 1 este libera
else
if (p>p1) p2=p,am2=1;
// vine un tren pe linia 2 si linia 1 este ocupata
u=(p1>p2)?p1:p2;
}

if(am2)x++;

z = (t1>t-t1) ? t1 : t-t1;

if(y) y--;

g<<z<<’ ’<<x<<’ ’<<y;

f.close();
g.close();
}

11.2.2 Cod surs 

Listing 11.2.1: Ana.CPP

1 #include <fstream>
2 #include<math.h>
3
4 using namespace std;
5
6 int timp[1382];
7 int t,i,j,l,h,m,s,x,y,z,nrt1,nrt2,ts,tp,tmp;
8
9 ifstream f("tren.in");
10 ofstream g("tren.out");
11
12 int main()
13 {
14 f>>t;
15 for(i=1;i<=t;i++)
16 {
17 f>>l>>h>>m>>s;
18 if(l==1) nrt1++;
19 else nrt2++;
20 ts=h*60+m;tp=ts+s;
21 for(j=ts;j<=tp;j++)
22 if(l==1) timp[j]=i;
23 else if(l==2 && timp[j]==0) timp[j]=i;
24 }
25
26 //b)
27 for(i=1;i<=1381;i++)
28 if(timp[i]!=timp[i-1] && timp[i]!=0) x++;
29
30 //c)
31 i=0;while(timp[i]==0) i++;
CAPITOLUL 11. OJI 2010 146

32 for(;i<=1381;i++)
33 if(timp[i]==0) tmp++;
34 else
35 {
36 if(tmp>y) y=tmp; tmp=0;
37 }
38 z=(nrt1+nrt2+abs(nrt1-nrt2))/2;
39 g<<z<<" "<<x<<" "<<y;
40
41 f.close();
42 g.close();
43 return 0;
44 }

Listing 11.2.2: Carmen.CPP

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream fi("tren.in");
6 ofstream fo("tren.out");
7 long lin[1441];
8
9 int main()
10 { long t,z,x,y,h,m,s,i,os,op,l;
11 fi>>t;
12 long n1,n2,j,pi=1441,pf=0;
13 n1=0; n2=0;
14
15 for(i=1;i<=t;i++)
16 {
17 fi>>l>>h>>m>>s;
18 os=h*60+m;
19 op=os+s;
20 if(pi>os)pi=os;
21 if(pf<op)pf=op;
22 if(l==1)n1++; else n2++;
23
24 for(j=os;j<=op;j++)
25 { if(l==1) lin[j]=lin[j]+n1;
26 else lin[j]=n2*1000+lin[j];
27 }
28 }
29
30 z=n1;
31 if(z<n2) z=n2;
32 y=0;
33 x=0;
34 long val=lin[pi],t1,t2;
35 unsigned long d=0;
36 t1=t2=0;
37 i=pi;
38
39 while(i<=pf)
40 {
41 if(lin[i]==0){i++;d++;}
42 else
43 { val=lin[i];
44 if(val%1000)
45 { if(t1!=val%1000)
46 {
47 t1=val%1000;
48 x++;
49 }
50 if((lin[i]%1000==val%1000)&&(i<=pf))i++;
51 }
52 else
53 { if(t2!=val/1000)
54 {
55 t2=val/1000;
56 x++;
57 }
58 if((lin[i]/1000==val/1000)&&(val%1000==0)&&(i<=pf))i++;
59 }
CAPITOLUL 11. OJI 2010 147

60
61 if(d>y)y=d;
62 d=0;
63 }
64 }
65
66 fo<<z<<’ ’<<x<<’ ’<<y;
67
68 fo.close();
69 fi.close();
70
71 return 0;
72 }

Listing 11.2.3: Cris1.CPP

1 # include <fstream>
2
3 using namespace std;
4
5 ifstream f("tren.in");
6 ofstream g("tren.out");
7
8 int x=1,t,y,z,t1,l,h,m,sta,s,p,am2,i,p1,p2,u;
9 int main()
10 { f>>t;
11 f>>l>>h>>m>>sta;
12 u=h*60+m+sta;
13 if(l==1) t1++,p1=u;
14 else p2=u;
15
16 for(i=2;i<=t;i++)
17 {
18 f>>l>>h>>m>>sta;
19 s=h*60+m; p=s+sta;
20 if(s-u>y) y=s-u;
21 if(s>p1+1 && am2==1 && p2>p1) x++,am2=0;
22 if(l==1) x++,t1++,p1=p;
23 else if (s>p1) x++,am2=0,p2=p;
24 else if (p>p1) p2=p,am2=1;
25
26 u=(p1>p2)?p1:p2;
27 }
28
29 if(am2)x++;
30 z=(t1>t-t1)?t1:t-t1;
31 if(y)y--;
32
33 g<<z<<’ ’<<x<<’ ’<<y;
34
35 f.close();
36 g.close();
37 return 0;
38 }

Listing 11.2.4: Cris2.CPP

1 # include <fstream>
2
3 using namespace std;
4
5 ifstream fi("tren.in");
6 ofstream fo("tren.out");
7
8 int x,t,y,z,u,t1,l,h,m,s,i,j,vine,pleaca,g[1441],v[101],inc=1441,sf;
9
10 int main()
11 { fi>>t;
12
13 for(i=1;i<=t;i++)
14 { fi>>l>>h>>m>>s;
15 vine=h*60+m;pleaca=vine+s;
16 if(i==1)inc=vine;
17 if(sf<pleaca) sf=pleaca;
CAPITOLUL 11. OJI 2010 148

18 if(l==1) { t1++; for(j=vine;j<=pleaca;j++)g[j]=i;}


19 else for(j=vine;j<=pleaca;j++)if(g[j]==0)g[j]=i;
20 }
21
22 z=(t1>t-t1) ? t1:t-t1;
23
24 y=0;
25 for(i=inc;i<=sf;i++)
26 { v[g[i]]=1;
27 if(g[i]==0) u++;
28 else
29 {
30 if(u>y)y=u;
31 u=0;
32 }
33 }
34
35 x=0;
36 for(i=1;i<=t;i++) x=x+v[i];
37
38 fo<<z<<’ ’<<x<<’ ’<<y;
39
40 fi.close();
41 fo.close();
42 return 0;
43 }

Listing 11.2.5: Cris3.CPP

1 # include <fstream>
2
3 using namespace std;
4
5 ifstream f("tren.in");
6 ofstream g("tren.out");
7
8 int x,t,y,z,u,t1,l,h,m,s,i,j,vine,pleaca,l1[1441],l2[1441],v[101],inc=1441,sf;
9
10 int main()
11 { f>>t;
12
13 for(i=1;i<=t;i++)
14 { f>>l>>h>>m>>s;
15 vine=h*60+m;pleaca=vine+s;
16 if(inc>vine) inc=vine;
17 if(sf<pleaca) sf=pleaca;
18 if(l==1) { t1++; for(j=vine;j<=pleaca;j++)l1[j]=i;}
19 else for(j=vine;j<=pleaca;j++)l2[j]=i;
20 }
21
22 z=(t1>t-t1) ? t1 : t-t1;
23
24 y=0;
25 for(i=inc;i<=sf;i++)
26 { v[l1[i]]=1;
27 if(l1[i]==0)v[l2[i]]=1;
28 if(l1[i]+l2[i]==0) u++;
29 else
30 {
31 if(u>y)y=u;
32 u=0;
33 }
34 }
35
36 x=0;
37 for(i=1;i<=t;i++) x=x+v[i];
38 g<<z<<’ ’<<x<<’ ’<<y;
39
40 f.close();
41 g.close();
42 return 0;
43 }

Listing 11.2.6: Dana.cpp


CAPITOLUL 11. OJI 2010 149

1 #include<fstream>
2
3 using namespace std;
4
5 ifstream f("tren.in");
6 ofstream g("tren.out");
7
8 int t,l,h,m,s;
9 int nr1,nr2,z,gasit,ultim;
10 int tp,x;
11 int maxx,y,timpc,poz;
12
13 int main()
14 {
15 int i;
16 f>>t;
17 for(i=1;i<=t;i++)
18 {
19 f>>l>>h>>m>>s;
20 /*Daca exista un tren pe linia 2, iar pe linia 1 sosesc trenuri
21 la interval de o secunda unul de altul, trenul de pe linia 2 nu se vede
22 si deci va fi scazut din numaratoare (o singura data!: ultim=tp;)
23 ultim reprezinta timpul de plecare din statie al trenului de pe linia 2*/
24 if(gasit)
25 {
26 gasit=0;
27 x--;
28 ultim=tp;
29 }
30 if(l==1)
31 {
32 nr1++;
33 x++;
34 if(ultim>h*60+m && h*60+m-tp==1 && i>1)
35 gasit=1;
36 tp=h*60+m+s;
37 }
38 else
39 {
40 nr2++;
41 if(h*60+m>tp||h*60+m+s>tp)
42 {
43 x++;
44 ultim=h*60+m+s;
45 }
46
47 }
48 if(h*60+m>maxx)
49 {
50 timpc=h*60+m-maxx;
51 maxx=h*60+m+s+1;
52 if(timpc>y && i>1) y=timpc;
53 }
54 else
55 if(h*60+m+s>maxx)
56 maxx=h*60+m+s+1;
57 }
58
59 if(nr1>nr2) z=nr1; else z=nr2;
60
61 g<<z<<" "<<x<<" "<<y;
62
63 return 0;
64 }

11.2.3 *Rezolvare detaliat 


Partea II

ONI - Olimpiada naµional  de


informatic 

150
Capitolul 12

ONI 2020

12.1 ***
Problema 1 - ... 100 de puncte

Cerinµe
Date de intrare
Date de ie³ire
Restricµii ³i preciz ri

Exemple:

***.in ***.out Explicaµii

Timp maxim de executare/test: 0.5 secunde pe Windows, 0.5 secunde pe Linux


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 15 KB

12.1.1 *Indicaµii de rezolvare

12.1.2 *Cod surs 

12.1.3 *Rezolvare detaliat 

12.2 ***
Problema 2 - ... 100 de puncte

Cerinµe
Date de intrare
Date de ie³ire
Restricµii ³i preciz ri

151
CAPITOLUL 12. ONI 2020 152

Exemple:
CAPITOLUL 12. ONI 2020 153

***.in ***.out Explicaµii

Timp maxim de executare/test: 0.5 secunde pe Windows, 0.5 secunde pe Linux


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 15 KB

12.2.1 *Indicaµii de rezolvare

12.2.2 *Cod surs 

12.2.3 *Rezolvare detaliat 

12.3 ***
Problema 3 - ... 100 de puncte

Cerinµe
Date de intrare
Date de ie³ire
Restricµii ³i preciz ri

Exemple:

***.in ***.out Explicaµii

Timp maxim de executare/test: 0.5 secunde pe Windows, 0.5 secunde pe Linux


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 15 KB

12.3.1 *Indicaµii de rezolvare

12.3.2 *Cod surs 

12.3.3 *Rezolvare detaliat 


Capitolul 13

ONI 2019

13.1 Copii
Problema 1 - Copii 100 de puncte
Iliuµ  ³i Pandele au înv µat la ³coal  operaµii aritmetice cu numere naturale. Astfel cei doi
fraµi exerseaz  operaµiile folosindu-se de o tabl . Iliuµ  spune un num r natural X, iar Pandele
scrie pe tabl  rezultatul înmulµirii tututor numerelor naturale de la 1 la X. Glumeµ, Iliuµ  ³terge
cifrele egale cu 0 de la nalul num rului scris de Pandele.
Ca s  îl ierte, Pandele spune ³i el un num r natural Y ³i îi cere lui Iliuµ  s  determine un
num r natural Z care este cel mai mare divizor al lui Y având un num r impar de divizori.
Cerinµe
Cunoscându-se numerele spuse de copii, scrieµi un program care rezolv  urm toarele cerinµe:
1) a³eaz  ultimele K cifre ale produsului calculat de Pandele, dup  ³tergerea cifrelor egale cu
0 de la nalul acestuia;
2) a³eaz  num rul Z cu semnicaµia de mai sus ³i num rul de divizori ai acestuia.
Date de intrare
Fi³ierul copii.in conµine pe prima linie num rul C, care reprezint  num rul cerinµei ³i poate
avea doar valorile 1 sau 2. Pentru prima cerinµ  ³ierul conµine pe a doua linie num rulX, iar pe
cea de a treia linie num rul K. Pentru a doua cerinµ  ³ierul conµine pe a doua linie num rul Y.

Date de ie³ire
Pentru cerinµa 1), pe prima linie a ³ierului copii.out se vor a³a cele K cifre cerute, f r 
spaµii, în ordine de la stânga la dreapta.
Pentru cerinµa 2), pe prima linie se vor a³a, în aceast  ordine, num rul Z determinat ³i
num rul de divizori ai acestuia. Numerele vor  separate printr-un spaµiu.

Restricµii ³i preciz ri
1 & X & 10
6
a
1 & Y & 10
12
a
a 1&K&9
a Num rul r mas dup  ³tergerea zerourilor de la nalul produsului are cel puµin K cifre;
a Pentru rezolvarea primei cerinµe se acord  40 de puncte;
a Pentru rezolvarea celei de a doua cerinµe se acord  60 de puncte.

Exemple

154
CAPITOLUL 13. ONI 2019 155

copii.in copii.out Explicaµii


1 016 Produsul 1*2*3*4*5*6*7*8*9*10*11*12 = 4790 01600.
12 Dup  ³tergerea zerourilor de la nalul produsului,
3 ultimele 3 cifre sunt 016.
2 14641 5 Cel mai mare divizor al lui 14641 care are un num r
14641 impar de divizori este chiar 14641.
1 813433856 Produsul 1*2*3*4*5*6*7*8*9*10*11*12 = 4790 01600.
723432 Dup  ³tergerea zerourilor de la nalul produsului,
9 ultimele 9 cifre sunt 813433856
2 286597481104 105 Cel mai mare divizor cu un num r impar de divizori
573194962208 este 286597481104 care are 105 divizori

Tabela 13.1: copii

Timp maxim de executare/test: 0.2 secunde


Memorie: total 64MB din care pentru stiv  64MB
Dimensiune maxim  a sursei: 15KB
Sursa: copii.cpp, copii.c sau copii.pas va  salvat  în folderul care are drept nume ID-ul
t u.

13.1.1 Indicaµii de rezolvare

Prof. Lica Daniela, Centrul Judeµean de Excelenµ  Prahova - Ploie³ti

1) Pentru prima cerinµ  se vor contoriza factorii de 5 din descompunerea numerelor de la 1 la


N. Fie Nr5 acest num r. Se vor determina ultimele K cifre ale produsului numerelor, ignorând
factorii de 2 ³i de 5, în num r egal cu Nr5.
2) Num rul Z cerut este p trat perfect, deci toµi factorii primi ai acestuia apar la puteri pare.
Se va descompune Y în factori primi ³i se va calcul num rul Z, derminând produsul factorilor din
descompunerea lui Y la cea mai mare putere par  mai mic  sau egal  cu cea din descompunerea
lui Y.

13.1.2 Cod surs 


Listing 13.1.1: copii_cpp.cpp

1 #include <fstream>
2 #include <algorithm>
3 #include <cassert>
4
5 using namespace std;
6
7 long long prim[1000010];
8 int expp[1000010], p = 0;
9
10 int main ()
11 {
12 ifstream cin ("copii.in");
13 ofstream cout ("copii.out");
14
15 int c, k;
16 long long x;
17 cin >> c >> x;
18
19 assert (c == 1 || c == 2);
20
21 if (c == 1)
22 {
23 cin >> k;
24
25 assert (1LL <= x && x <= 1000000LL);
26 assert (1 <= k && k <= 9);
27
28 int m = 1;
29 for (int i = 1; i <= k; ++i)
CAPITOLUL 13. ONI 2019 156

30 m *= 10;
31
32 assert (m > 0);
33
34 int nr2 = 0, nr5 = 0;
35 for (int i = 1; i <= x; ++i)
36 {
37 int ci = i;
38
39 while (ci % 5 == 0)
40 {
41 ++nr5;
42 ci /= 5;
43 }
44 }
45
46 nr2 = nr5;
47
48 long long prod = 1LL;
49
50 for (int i = 1; i <= x; ++i)
51 {
52 int ci = i;
53 while (ci % 2 == 0 && nr2 > 0)
54 {
55 --nr2;
56 ci /= 2;
57 }
58
59 while (ci % 5 == 0 && nr5 > 0)
60 {
61 --nr5;
62 ci /= 5;
63 }
64
65 prod *= 1LL * ci;
66 prod %= 1LL * m;
67 }
68
69 int aux = prod, p = 0;
70 while (aux > 0)
71 {
72 ++p;
73 aux /= 10;
74 }
75
76 for (int i = p + 1; i <= k; ++i) cout << 0;
77
78 cout << prod << ’\n’;
79 }
80 else
81 {
82 assert (1LL <= x && x <= 1000000000000LL);
83
84 long long i = 2LL;
85 while (i * i <= x)
86 {
87 if (x % i == 0LL)
88 {
89 prim[++p] = i;
90
91 while (x % i == 0)
92 {
93 x /= i;
94 ++expp[p];
95 }
96 }
97
98 i += 1LL;
99 }
100
101 if (x > 1LL)
102 {
103 prim[++p] = x;
104 expp[p] = 1;
105 }
CAPITOLUL 13. ONI 2019 157

106
107 long long divizor = 1LL, numar = 1LL;
108 for (int i = 1; i <= p; ++i)
109 {
110 if (expp[i] % 2 == 1) --expp[i];
111
112 for (int j = 1; j <= expp[i]; ++j)
113 divizor *= prim[i];
114
115 numar *= 1LL * (1 + expp[i]);
116 }
117
118 cout << divizor << " " << numar << ’\n’;
119 }
120
121 return 0;
122 }

13.1.3 Rezolvare detaliat 

Listing 13.1.2: Copii - Etapa nr. 0

1 #include<iostream> // cout
2 #include<fstream> // fstream
3
4 using namespace std;
5
6 ifstream fin("copii.in");
7 ofstream fout("copii.out");
8
9 int C; // nr cerinta
10
11 void rezolva1()
12 {
13
14 }
15
16 void rezolva2()
17 {
18
19 }
20
21 int main()
22 {
23 fin>>C;
24 cout<<"C = "<<C<<"\n";
25
26 if(C==1) {rezolva1(); return 0;}
27 if(C==2) {rezolva2(); return 0;}
28
29 return 0;
30 }

Listing 13.1.3: Copii - Etapa nr. 1

1 #include<iostream> // cout
2 #include<fstream> // fstream
3
4 using namespace std;
5
6 ifstream fin("copii.in");
7 ofstream fout("copii.out");
8
9 int C; // nr cerinta
10 int X, K; // pentru C=1 ... (K cifre) <=9 ...10^9 ... incape pe int ...
11 long long Y; // pentru C=2 ... atentie ... Y <= 10^12 ... !!!
12
13 int k10; // k10 = 10^k ... pentru ultimele k cifre (fac modulo k10)
14
15 int nr5; // nr factorilor de 5 pe care ii scot din 1*2*3*...*X (10=2*5)
16 int nr2; // nr factorilor de 2 pe care ii scot din X (nr2 > nr5 ... sigur!)
CAPITOLUL 13. ONI 2019 158

17
18 long long p1x; // produs de la 1 la x ... pastrez numai (p1x % k10) ...X*10^k =
19 // = 10^6*10^9 = 10^15 = long long ... !!!
20
21 void rezolva1()
22 {
23 fin>>X;
24 fin>>K;
25 cout<<"X = "<<X<<"\n"; // atentie la X=1 sau X=2 sau X=3 ... !!!
26 cout<<"K = "<<K<<"\n";
27
28 k10=1;
29 for(int i=1; i<=K; i++) k10=k10*10; // k10 *= 10;
30 cout<<"\n k10 = "<<k10<<"\n\n";
31
32 nr5=0;
33 for(int i=1; i<=X; i++) // pentru 1*2*3*...*X (nu prea are rost de la 1 ...)
34 {
35 int ci=i; // copia lui i ... ca sa nu il stric pe i ...
36
37 while(ci%5==0) // atentrie la cele doua = uri !!!
38 {
39 nr5++;
40 ci=ci/5; // ci /= 5;
41 }
42 cout<<i<<" : nr5 = "<<nr5<<"\n";
43 }
44 cout<<"\n--- nr5 = "<<nr5<<" ---\n\n";
45
46 p1x=1LL; // atentie la 1 pentru long long ... !!!
47 nr2=nr5;
48 for(int i=2; i<=X; i++)
49 {
50 int ci=i; // copia lui i ... ca sa nu il stric pe i ...
51
52 while((nr2>0) && (ci%2==0)) // scot 2-urile
53 {
54 ci=ci/2; // scot un 2
55 nr2--;
56 }
57
58 while((nr5>0) && (ci%5==0)) // scot 5-urile
59 {
60 ci=ci/5; // scot un 2
61 nr5--;
62 }
63
64
65 p1x = p1x * ci;
66 cout<<i<<" : p1x = "<<p1x;
67 p1x = p1x % k10;
68 cout<<"\t = "<<p1x<<"\n";
69 }
70
71 cout<<"\n--- p1x = "<<p1x<<" ---\n\n";
72
73 // de pus 0-uri in stanga ... 16 --> 016 ... la test1
74
75 int ncp1x=0; // nr cifre p1x
76 int cp1x=p1x; // copie a lui p1x
77 while(cp1x>0)
78 {
79 ncp1x++;
80 cp1x=cp1x/10;
81 }
82
83 // scriu (K - ncp1x) zerouri la inceputul rezultatului afisat
84 for(int i=1; i<=(K-ncp1x); i++)
85 {
86 cout<<"0";
87 }
88 cout<<p1x<<’\n’;
89 }
90
91 void rezolva2()
92 {
CAPITOLUL 13. ONI 2019 159

93
94 }
95
96 int main()
97 {
98 fin>>C;
99 cout<<"C = "<<C<<"\n";
100
101 if(C==1) {rezolva1(); return 0;}
102 if(C==2) {rezolva2(); return 0;}
103
104 return 0;
105 }

Listing 13.1.4: Copii - Etapa nr. 2

1 #include<iostream> // cout
2 #include<fstream> // fstream
3 #include<stdio.h> // getchar(); // getc(stdin); // in while ... poate sa cicleze "la
infinit" ... !!!
4
5 using namespace std;
6
7 ifstream fin("copii.in");
8 ofstream fout("copii.out");
9
10 int C; // nr cerinta
11 int X, K; // pentru C=1 ... (K cifre) <=9 ...10^9 ... incape pe int ...
12
13 long long Y; // pentru C=2 ... atentie ... Y <= 10^12 ... !!!
14
15 long long Z; // Z divizor <= Y <= 10^12 ... ==> long long
16 long long ndivz;// nr divizori ai lui Z
17
18 int k10; // k10 = 10^k ... pentru ultimele k cifre (fac modulo k10)
19
20 int nr5; // nr factorilor de 5 pe care ii scot din 1*2*3*...*X (10=2*5)
21 int nr2; // nr factorilor de 2 pe care ii scot din X (nr2 > nr5 ... sigur!)
22
23 long long p1x; // produs de la 1 la x ... pastrez numai (p1x % k10) ...X*10^k =
24 // = 10^6*10^9 = 10^15 = long long ... !!!
25
26 void rezolva1()
27 {
28 fin>>X;
29 fin>>K;
30 cout<<"X = "<<X<<"\n"; // atentie la X=1 sau X=2 sau X=3 ... !!!
31 cout<<"K = "<<K<<"\n";
32
33 k10=1;
34 for(int i=1; i<=K; i++) k10=k10*10; // k10 *= 10;
35 cout<<"\n k10 = "<<k10<<"\n\n";
36
37 nr5=0;
38 for(int i=1; i<=X; i++) // pentru 1*2*3*...*X (nu prea are rost de la 1 ... dar...)
39 {
40 int ci=i; // copia lui i ... ca sa nu il stric pe i ...
41
42 while(ci%5==0) // atentrie la cele doua = uri !!!
43 {
44 nr5++;
45 ci=ci/5; // ci /= 5;
46 }
47 cout<<i<<" : nr5 = "<<nr5<<"\n";
48 }
49 cout<<"\n--- nr5 = "<<nr5<<" ---\n\n";
50
51 p1x=1LL; // atentie la 1 pentru long long ... !!!
52 nr2=nr5;
53 for(int i=2; i<=X; i++)
54 {
55 int ci=i; // copia lui i ... ca sa nu il stric pe i ...
56
57 while((nr2>0) && (ci%2==0)) // scot 2-urile
58 {
CAPITOLUL 13. ONI 2019 160

59 ci=ci/2; // scot un 2
60 nr2--;
61 }
62
63 while((nr5>0) && (ci%5==0)) // scot 5-urile
64 {
65 ci=ci/5; // scot un 2
66 nr5--;
67 }
68
69
70 p1x = p1x * ci;
71 cout<<i<<" : p1x = "<<p1x;
72 p1x = p1x % k10;
73 cout<<"\t = "<<p1x<<"\n";
74 }
75
76 cout<<"\n--- p1x = "<<p1x<<" ---\n\n";
77
78 // de pus 0-uri in stanga ... 16 --> 016 ... la test1
79
80 int ncp1x=0; // nr cifre p1x
81 int cp1x=p1x; // copie a lui p1x
82 while(cp1x>0)
83 {
84 ncp1x++;
85 cp1x=cp1x/10;
86 }
87
88 // scriu (K - ncp1x) zerouri la inceputul rezultatului afisat
89 for(int i=1; i<=(K-ncp1x); i++)
90 {
91 cout<<"0";
92 }
93 cout<<p1x<<’\n’;
94 }
95
96 void rezolva2()
97 {
98 fin>>Y;
99 //Y=1LL*2*2*3*3*3*3*5*7*7*7;
100 cout<<"Y = "<<Y<<"\n\n"; // atentie la Y=1 sau Y=2 sau Y=3 ... !!!
101 //getchar();
102
103 // Z = f1^e1 * f2^e2 * ... fn^en unde fi=factor_i si ei=exponent_i
104 // nr_divizori(Z) = (1+e1)*(1+e2)*...*(1+en) = impar
105 // ==> toate parantezele sunt impare
106 // ==> toti exponentii sunt pari
107 // ==> Z = patrat perfect
108
109 // Daca Y=patrat perfect ==> sa ia Z = Y
110 // Daca Y NU ESTE patrat perfect ==> se ia CEL MAI MARE patrat perfect
111 // adica, se ia fiecare factor fi la cea mai mare putere para la care apare
...
112
113 Z=1LL; // pentru produsul factorilor
114 ndivz=1LL; // nr divizorilor lui Z
115
116 int fp; // factor prim de incercat: 2, 3, 5, 7, 9(?), 11, 13, 15(?), 17, 19,
21(?), ...
117 int nfp; // de cate ori apare factorul prim fp
118 long long cy=Y; // copia lui Y ... atentie la ... long long ... !!!
119
120 fp=2;
121 nfp=0;
122 while((cy > 0) && (cy%fp == 0)) // 2-urile ...
123 {
124 nfp++;
125 cy=cy/fp;
126 //getchar();
127 }
128 if(nfp>0)
129 cout<<"fp = "<<fp<<" nfp = "<<nfp<<"\n";
130 //getchar();
131
132 if(nfp%2==1) nfp--; // sa apara de nr par de ori ...
CAPITOLUL 13. ONI 2019 161

133
134 for(int i=1; i<=nfp; i++) Z = Z*fp;
135 ndivz=ndivz*(1+nfp);
136
137 cout<<"fp = "<<fp<<" nfp = "<<nfp<<" Z = "<<Z<<
138 " ndivz = "<<ndivz<<" cy = "<<cy<<"\n\n";
139
140 fp=3;
141 while(fp*fp <= cy)
142 {
143 // fp=2; // scapa in bucla infinita ... !!!
144 nfp=0;
145
146 while((cy > 0) && (cy%fp == 0)) // fp-urile ...
147 {
148 nfp++;
149 cy=cy/fp;
150 //getchar();
151 }
152 if(nfp>0)
153 cout<<"fp = "<<fp<<" nfp = "<<nfp<<"\n";
154
155 if(nfp%2==1) nfp--; // sa apara de nr par de ori ...
156
157 for(int i=1; i<=nfp; i++) Z = Z*fp;
158
159 ndivz=ndivz*(1LL+nfp);
160
161 if(nfp>0)
162 cout<<"fp = "<<fp<<" nfp = "<<nfp<<" Z = "<<Z<<
163 " ndivz = "<<ndivz<<" cy = "<<cy<<"\n\n";
164
165 fp=fp+2;
166 //getchar();
167 }
168 cout<<"\n --- cy = "<<cy<<" --- \n\n"; // ce a ramas ...
169
170 cout<<Z<<’ ’<<ndivz<<’\n’;
171 }
172
173 int main()
174 {
175 fin>>C;
176 cout<<"C = "<<C<<"\n";
177
178 if(C==1) {rezolva1(); return 0;}
179 if(C==2) {rezolva2(); return 0;}
180
181 return 0;
182 }

13.2 Numere
Problema 2 - Numere 100 de puncte
Într-o zi, Ioana a scris toate numerele naturale de N cifre ecare îndeplinind, simultan, condiµiile:
- num rul format din primele dou  cifre este p trat perfect;
- a treia cifr  este obligatoriu num r prim;
- nu conµine dou  cifre pare al turate ³i nici dou  cifre impare al turate.
De exemplu, numerele de trei cifre, scrise de Ioana, sunt:
163, 165, 167, 252, 363, 365, 367, 492, 812.

Cerinµe
Cunoscându-se numerele N ³i X, scrieµi un program care determin :
1) câte numere de N cifre îndeplinesc cele trei condiµii din enunµ;
2) care este cel mai apropiat num r de X, diferit de X, care s  îndeplineasc  cele trei condiµii
din enunµ ³i care s  aib  acela³i num r de cifre ca X. Dac  exist  dou  astfel de numere, egal
dep rtate de X, se va a³a cel mai mic dintre ele.

Date de intrare
CAPITOLUL 13. ONI 2019 162

numere.in conµine pe prima linie un num r natural C. Num rul C poate


Fi³ierul de intrare
N, iar în cazul
avea doar valorile 1 sau 2. Pe a doua linie se a , în cazul primei cerinµe, num rul
celei de-a doua cerinµe, num rul X.

Date de ie³ire
Dac  valoarea lui C este 1, se va rezolva doar cerinµa 1). În acest caz, ³ierul de ie³ire
numere.out va conµine pe prima linie un num r natural, reprezentând rezultatul determinat
pentru prima cerinµ .
Dac  valoarea lui C este 2, se va rezolva doar cerinµa 2). În acest caz, ³ierul de ie³ire
numere.out va conµine pe prima linie un num r natural, reprezentând rezultatul determinat
pentru cea de a doua cerinµ .

Restricµii ³i preciz ri
a 3 & N & 29
a 100 & X & 20 000 000
a Pentru rezolvarea primei cerinµe se acord  30 de puncte, iar pentru rezolvarea celei de a doua
cerinµe se acord  70 de puncte.

Exemple
numere.in numere.out Explicaµii
1 45 Numerele de patru cifre, scrise de Ioana, sunt:
4 1630, 1632, 1634, 1636, 1638, 1650, 1652, 1654, 1656,
1658, 1670, 1672, 1674, 1676, 1678, 2521, 2523, 2525,
2527, 2529, 3630, 3632, 3634, 3636, 3638, 3650, 3652,
3654, 3656, 3658, 3670, 3672, 3674, 3676, 3678, 4921,
4923, 4925, 4927, 4929, 8121, 8123, 8125, 8127, 8129.
2 167 Cel mai apropiat num r de 200 este 167 (numerele de
200 trei cifre, scrise de Ioana, sunt: 163, 165, 167, 252, 363,
365, 367, 492, 812).

Timp maxim de executare/test: 0.5 secunde


Memorie: total 2MB din care pentru stiv  2MB
Dimensiune maxim  a sursei: 15KB
Sursa: numere.cpp, numere.c sau numere.pas va  salvat  în folderul care are drept nume ID-ul
t u.

13.2.1 Indicaµii de rezolvare

Prof. Ana-Maria Ari³anu, Colegiul Naµional Mircea cel B trân, Rm. Vâlcea

a) Numerele ce respect  condiµiile din enunµ pot începe cu 16, 25, 36, 49 sau 81
Caz 1. Dac  încep cu 16 sau 36 a treia cifra poate  3, 5 sau7.
Caz 2. Dac  încep cu 25, 49 sau 81 a treia cifra poate  doar 2
Începând cu a patra cifra avem câte 5 posibilit µi, respectiv 0, 2, 4, 6 sau 8 (pentru cazul 1) ³i
1, 3, 5, 7 sau 9 (pentru cazul 2)
Num rul de numere de N cifre care respect  condiµiile din enunµ este:
2 ˜ 3 ˜ 5 n  3  3 ˜ 5 n  3 9 ˜ 5 n  3
b) Fie k num rul de cifre ale num rului X.
Construim xmin ca ind cel mai mic num r
de k cifre ce respect  condiµiile din enunµ %
xmin = 163010101 ...
Construim xmax ca ind cel mai mare num r de k cifre ce respect  condiµiile din enunµ %
xmax = 812989898...
Determin m cel mai mic num r, mai mare decât x ce respect  condiµiile din enunµ (dac 
exist ). Acest num r nu poate  mai mare decât xmax.
Determin m cel mai mare num r, mai mic decât x ce respect  condiµiile din enunµ (dac 
exist ). Acest num r nu poate  mai mic decât xmin.
Dintre cele dou  numere determinate se a³eaz  cel mai aproape de X.
CAPITOLUL 13. ONI 2019 163

13.2.2 Cod surs 

Listing 13.2.1: numere_cpp.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("numere.in");
6 ofstream g ("numere.out");
7
8 int main()
9 {
10 int p,n,x,dif1=20000000,dif2=20000000,y,xx;
11 long long xmin,xmax,i, nr1,nr2;
12 unsigned long long nr;
13
14 f>>p;
15 if (p==1)
16 {
17 f>>n;
18 nr=9;
19 for (i=1; i<=n-3; i++)
20 nr=nr*5;
21 g<<nr<<’\n’;
22 }
23 else
24 {
25 f>>x;
26 y=x;
27 xmin=163;
28 xmax=812;
29 i=3;
30 while (y>999)
31 {
32 i++;
33 if (i%2==0)
34 {
35 xmin=xmin*10;
36 xmax=xmax*10+9;
37 }
38 else
39 {
40 xmin=xmin*10+1;
41 xmax=xmax*10+8;
42 }
43 y=y/10;
44 }
45
46 if (x<xmin) g<<xmin;
47 else
48 if (x>xmax) g<<xmax;
49 else
50 {
51 for (xx=x-1; xx>=xmin; xx--)
52 {
53 int v[11],k=0,n2,i,xxx=xx, bun=1;
54
55 while (xxx>99)
56 {
57 k++;
58 v[k]=xxx%10;
59 xxx=xxx/10;
60 }
61
62 if (xxx!=16 && xxx!=25 && xxx!=36 && xxx!=49 && xxx!=81) bun=0;
63 else if ((xxx==16|| xxx==36)&& (v[k]!=3 && v[k]!=5 && v[k]!=7))
64 bun=0;
65 else if ((xxx==25 || xxx==49 ||xxx==81) && v[k]!=2) bun=0;
66 else
67 for (i=k-1; i>=1; i--)
68 if (v[i]%2==v[i+1]%2) bun=0;
69 if (bun)
70 {
CAPITOLUL 13. ONI 2019 164

71 nr1=xx;
72 dif1=x-nr1;
73 break;
74 }
75 }
76
77 for (xx=x+1; xx<=xmax; xx++)
78 {
79 int v[11],k=0,n2,i,xxx=xx, bun=1;
80 while (xxx>99)
81 {
82 k++;
83 v[k]=xxx%10;
84 xxx=xxx/10;
85 }
86 if (xxx!=16 && xxx!=25 && xxx!=36 && xxx!=49 && xxx!=81) bun=0;
87 else if ((xxx==16|| xxx==36)&& (v[k]!=3 && v[k]!=5 && v[k]!=7))
88 bun=0;
89 else if ((xxx==25 || xxx==49 ||xxx==81) && v[k]!=2) bun=0;
90 else
91 for (i=k-1; i>=1; i--)
92 if (v[i]%2==v[i+1]%2) bun=0;
93 if (bun)
94 {
95 nr2=xx;
96 dif2=nr2-x;
97 break;
98 }
99 }
100
101 if (dif1<=dif2)
102 g<<nr1<<’\n’;
103 else
104 g<<nr2<<’\n’;
105 }
106 }
107 }

13.2.3 Rezolvare detaliat 

Atenµie la enunµ: ...  cel mai apropiat num r de X, diferit de X, ...
Exemplu pentru 3 cifre:

zona16 zona25 zona36 zona49 zona81

100 163 165 167 252 363 365 367 492 812 999
Figura 13.1: Numere cu 3 cifre

Dac  X este în stînga zonei zona16 (de exemplu X 150) atunci rezultatul este 163.
Dac  X este în dreapta zonei zona81 (de exemplu X 900) atunci rezultatul este 812.
Altfel, X are doi vecini, unul în stânga ³i unul în dreapta.
Dac , de exemplu, X 166, cei doi vecini sunt 165 ³i 167 din accela³i grup zona16.
Dac , de exemplu, X 444, cei doi vecini sunt 367 ³i 492 din grupuri diferite dar adiacente.
Mai precis, X 444 este între zonele zona36 ³i zona49 iar cei doi vecini sunt: cel mai mare din
zona zona36 ³i cel mai mic din zona zona49.
Exemplu pentru 4 cifre:

zona16 zona25 zona36 zona49 zona81

1000 1630 16.. 1678 252. 3630 36.. 3678 492. 812. 9999

Figura 13.2: Numere cu 4 cifre

Pentru nc 4 zona zona25 r2521, 2523, 2525, 2527, 2529x.


CAPITOLUL 13. ONI 2019 165

(celelalte zone sunt deja precizate în enunµul problemei).


Exemplu pentru 5 cifre:

zona16 zona25 zona36 zona49 zona81

10000 16301 16... 16789 252.. 36301 36... 36789 492.. 812.. 99999

Figura 13.3: Numere cu 5 cifre

Pentru nc 5 zona

zona25 r25210, 25212, 25214, 25216, 25218,


25230, 25232, 25234, 25236, 25238,
25250, 25252, 25254, 25256, 25258,
25270, 25272, 25274, 25276, 25278,
25290, 25292, 25294, 25296, 25298x. (13.2.1)

Celelalte zone NU mai sunt precizate în enunµul problemei dar sunt u³or de intuit! Pentru
nc 6, 7, 8 zonele sunt tot mai dep rtate (de 0) ³i conµin tot mai multe numere ecare!
Pentru nc 8 reprezentarea tabelar  ne va ajuta s  program m mai u³or!
Pentru 16:

1 2 3 4 5 6 7 8
p trat prim paritati diferite
1 6 3 0 1 0 1 0
1 6 3 ... ... ... ... ...
1 6 3 8 9 8 9 8
1 6 5 0 1 0 1 0
1 6 5 ... ... ... ... ...
1 6 5 8 9 8 9 8
1 6 7 0 1 0 1 0
1 6 7 ... ... ... ... ...
1 6 7 8 9 8 9 8

Pentru 25:

1 2 3 4 5 6 7 8
p trat prim paritati diferite
2 5 2 1 0 1 0 1
2 5 2 ... ... ... ... ...
2 5 2 9 8 9 8 9

Pentru 36:

1 2 3 4 5 6 7 8
p trat prim paritati diferite
3 6 3 0 1 0 1 0
3 6 3 ... ... ... ... ...
3 6 3 8 9 8 9 8
3 6 5 0 1 0 1 0
3 6 5 ... ... ... ... ...
3 6 5 8 9 8 9 8
3 6 7 0 1 0 1 0
3 6 7 ... ... ... ... ...
3 6 7 8 9 8 9 8

Pentru 49:
CAPITOLUL 13. ONI 2019 166

1 2 3 4 5 6 7 8
p trat prim paritati diferite
4 9 2 1 0 1 0 1
4 9 2 ... ... ... ... ...
4 9 2 9 8 9 8 9

Pentru 81:

1 2 3 4 5 6 7 8
p trat prim paritati diferite
8 1 2 1 0 1 0 1
8 1 2 ... ... ... ... ...
8 1 2 9 8 9 8 9

Pentru 81 puµin mai detaliat la mijlocul zonei:

1 2 3 4 5 6 7 8
p trat prim paritati diferite
8 1 2 1 0 1 0 1
8 1 2 ... ... ... ... ...
8 1 2 5 0 1 0 1
8 1 2 5 0 1 0 3
8 1 2 5 0 1 0 5
8 1 2 5 0 1 0 7
8 1 2 5 0 1 0 9
8 1 2 5 0 1 2 1
8 1 2 5 0 1 2 3
8 1 2 ... ... ... ... ...
8 1 2 5 8 9 6 7
8 1 2 5 8 9 6 9
8 1 2 5 8 9 8 1
8 1 2 5 8 9 8 3
8 1 2 5 8 9 8 5
8 1 2 5 8 9 8 7
8 1 2 5 8 9 8 9
8 1 2 ... ... ... ... ...
8 1 2 9 8 9 8 9

Mi³carea contorului electric sau a kilometrajului de la ma³in !


Când se m re³te valoarea cu o unitate:
1. Se m re³te cu o unitate ultima cifr  (cea din dreapta).
2. Dac  nu se poate (pentru c  este 9 = cea mai mare cifr  permis  pe poziµia vericat ),
se caut  spre stânga prima poziµie care se poate m ri ³i se pun pe 0 toate poziµiile prin care s-a
trecut. (0 este cea mai mic  cifr  permis  pe poziµia vericat ).
Când se mic³oreaz  valoarea cu o unitate:
1. Se mic³oreaz  cu o unitate ultima cifr  (cea din dreapta).
2. Dac  nu se poate (pentru c  este 0), se caut  spre stânga prima poziµie care se poate
mic³ora ³i se pun pe 9 toate poziµiile prin care s-a trecut. (9 este cea mai mare cifr  permis 
pe poziµia vericat ).
Un exemplu pentru nc 7 (num rul cifrelor):

1 2 3 4 5 6 7
p trat prim paritati diferite
1 5 2 7 0 7 0
... ... ... ... ... ... ...
1 6 3 0 0 9 9
... ... ... ... ... ... ...
1 6 3 0 1 0 1 min16 = min163
... ... ... ... ... ... ...
3 6 7 8 9 8 9 max36 = max367
CAPITOLUL 13. ONI 2019 167

... ... ... ... ... ... ...


4 4 4 4 4 4 4
... ... ... ... ... ... ...
4 9 2 1 0 1 0 min49 = min492
... ... ... ... ... ... ...
8 1 2 9 8 9 8 max81 = max812
... ... ... ... ... ... ...
8 1 2 9 9 0 0
... ... ... ... ... ... ...
8 2 0 0 0 0 0
Un exemplu pentru nc 7 (num rul cifrelor):

1 2 3 4 5 6 7
p trat prim paritati diferite
... ... ... ... ... ... ...
3 6 3 0 1 0 1 min363
... ... ... ... ... ... ...
3 6 3 8 9 8 9 max363
3 6 5 0 1 0 1 min365
... ... ... ... ... ... ...

3 6 5 4 0 0 0 err!
3 6 5 4 1 0 1
... ... ... ... ... ... ...
3 6 5 8 9 8 9 max365
3 6 7 0 1 0 1 min367
... ... ... ... ... ... ...

Celalalt vecin este:

1 2 3 4 5 6 7
p trat prim paritati diferite
3 6 5 2 9 8 9
3 6 5 4 1 0 1

Evident, num rul este între cei doi vecini:

1 2 3 4 5 6 7
p trat prim paritati diferite
... ... ... ... ... ... ...
3 6 5 2 9 8 9
3 6 5 4 0 0 0 err!
3 6 5 4 1 0 1
... ... ... ... ... ... ...

Un exemplu pentru nc 7 (num rul cifrelor):


CAPITOLUL 13. ONI 2019 168

1 2 3 4 5 6 7
p trat prim paritati diferite
... ... ... ... ... ... ...
3 6 3 0 1 0 1 min363
... ... ... ... ... ... ...
3 6 3 8 9 8 9 max363
3 6 5 0 1 0 1 min365
... ... ... ... ... ... ...
3 6 5 4 9 8 9
3 6 5 4 9 9 0 err!
... ... ... ... ... ... ...
3 6 5 8 9 8 9 max365
3 6 7 0 1 0 1 min367
... ... ... ... ... ... ...

Celalalt vecin este:

1 2 3 4 5 6 7
p trat prim paritati diferite
3 6 5 4 9 8 9
3 6 5 6 1 0 1

Evident, numarul este intre cei doi vecini.

1 2 3 4 5 6 7
p trat prim paritati diferite
... ... ... ... ... ... ...
3 6 5 4 9 8 9
3 6 5 4 9 9 0 err!
3 6 5 6 1 0 1
... ... ... ... ... ... ...

În nal se cristalizeaz  urm toarea idee de rezolvare:


1. dac  num rul este între grupuri se determin  ³i se a³eaz  soluµia, v1 sau v2, pentru care
se realizeaz  min(nr-v1, v2-nr) unde v1 = maxGrupStanga ³i v2 = minGrupDreapta
2. dac  num rul este într-un grup
2a. se determin  unul dintre cei mai apropiaµi vecini (v1 = mai mic sau v2 = mai mare, decât
num rul)
2b. se determin  cel lalt vecin al num rului (succesor sau predecesor, în secvenµa numerelor
valabile)
2c. se a³eaz  soluµia, v1 sau v2, pentru care se realizeaz  min(nr-v1, v2-nr)
Obs. Cei mai experimentaµi pot folosi aceste idei ³i pot obµine un algoritm apropiat de cei
prezentaµi ocial! Adic ,
1. se determin  poziµia eronat 
2. se construie³te elementul corect î n secvenµ  mai mic (dac  se poate mic³ora acea valoare
din poziµia eronat ) sau mai mare (dac  nu se poate ...)
3. se completeaz  cu ce trebuie ca s  e cât mai mare/mic ... în funcµie de alegerea facut  la
2.
4. se determin  succesorul/predecesorul
5. se determin  soluµia

Structura general  ³i rezolvarea primei cerinµe

Listing 13.2.2: Numere - Etapa nr. 0

1 #include<iostream> // cout ... afisari pe ecran ... !!!


2 #include<fstream> // fstream
3
4 using namespace std;
5
6 ifstream fin("numere.in");
CAPITOLUL 13. ONI 2019 169

7 ofstream fout("numere.out");
8
9 int C;
10 int N;
11 int X; // 20.000.000 incape pe "int"
12
13 int nr3c[9] = { 163, 165, 167, 252, 363, 365, 367, 492, 812 };
14
15 long long rez1=9; // unsigned long long ... este mai OK!
16
17 void rezolva1()
18 {
19 fin>>N;
20
21 rez1=9LL;
22 for(int i=1; i<=min(N-3,28-3); i++)// N=28 este ultimul care este ok
23 rez1=rez1*5;
24
25 if(N==29) // trebuie si ultima inmultire cu 5 ... !!!
26 {
27 int v[21]; // vector cu cifrele rezultatului
28 int i; // variabila de lucru ... trebuie si in afara for-ului
29
30 int poz=-1; // pozitia in vectorul cifrelor lui rez1
31 while(rez1>0L)
32 {
33 poz++;
34 v[poz]=rez1%10;
35 rez1=rez1/10;
36 }
37
38 // inmultirea rez*5
39 int t=0; // cifra de transport ... la inmultire
40 for(i=0; i<=poz; i++)
41 {
42 int cifra=v[i]*5+t;
43 v[i]=cifra%10;
44 t=cifra/10;
45 }
46 if(t>0) { v[i]=t; poz++; }
47 for(i=poz; i>=0; i--) fout<<v[i];
48 fout<<’\n’;
49 }
50 else
51 fout<<rez1<<’\n’;
52 }
53
54 void rezolva2()
55 {
56
57 }
58
59 int main()
60 {
61 fin>>C;
62
63 if(C==1) rezolva1();
64 if(C==2) rezolva2();
65
66 return 0;
67 }

Variabile globale pentru cerinµa 2

Listing 13.2.3: Numere - Etapa nr. 1

1 int C;
2 int N;
3 int X; // 20.000.000 incape pe "int"
4
5 int nr3c[9] = { 163, 165, 167, 252, 363, 365, 367, 492, 812 };
6
7 long long rez1=9; // unsigned long long ... este mai OK!
8 int rez2, rez2min, rez2max; // solutie pentru Cerinta 2
CAPITOLUL 13. ONI 2019 170

9
10 int vcifx[9]; // indici 0, 1, ..., 8 ... vcifx[8] EROARE la ncx=8 ...
11 int vcifxs[9]; // nr mai mic decat X (in stanga) ... predecesor
12 int vcifxd[9]; // nr mai mare decat X (in dreapta) ... succesor
13
14 int ncx; // nr cifre in X
15 int pozincorecta; // pozitia ... cu cifra incorecta
16
17 int x123; // primele 3 cifre
18 int x12; // primele 2 cifre
19 int x3; // cifra x3
20 int x2; // cifra x2

222

Listing 13.2.4: Numere - Etapa nr. 2

1 void rezolva2()
2 {
3 fin>>X;
4
5 nrcifrex(X);
6 vcifrex(X);
7
8 x123=X;
9 for(int i=ncx; i>=4; i--) x123=x123/10;
10 x12=x123/10;
11 x3=x123%10;
12
13 calcpozincorecta();
14
15 if(pozincorecta>ncx) // X este OK ...
16 {
17 rez2=X; // ... trebuie sa fie DIFERIT de X ... !!!
18
19 int x123min=f123min(x123);
20 int x123max=f123max(x123);
21
22 if(X < x123max) succesorX(); // vcifxd[]
23 if(X > x123min) predecesorX(); // vcifxs[]
24
25 rez2min=rez2max=0;
26 for(int i=1; i<=ncx; i++)
27 {
28 rez2min=rez2min*10+vcifxs[i];
29 rez2max=rez2max*10+vcifxd[i];
30 }
31
32 if(X == x123min) rez2 = rez2max;
33 else
34 if(X == x123max) rez2 = rez2min;
35 else
36 {
37 rez2=rez2min;
38 if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X
39 }
40 }
41 else
42 if(pozincorecta<=3) pozincorecta23();
43 else pozincorecta45678();
44
45 fout<<rez2<<’\n’;
46 }

333

Listing 13.2.5: Numere - Etapa nr. 3

1 void nrcifrex(int x)
2 {
3 ncx=0;
CAPITOLUL 13. ONI 2019 171

4 while(x>0) { ncx++; x=x/10; }


5 }
6
7 void vcifrex(int x)
8 {
9 for(int i=1; i<=ncx; i++)
10 {
11 vcifx[ncx-i+1]=x%10;
12 x=x/10;
13 }
14 }
15
16 void calcpozincorecta()
17 {
18 if(x12 != 16 && x12 != 25 && x12 != 36 && x12 != 49 && x12 != 81)
19 pozincorecta=2;
20 else
21 if(!(x3 == 2 || x3 == 3 || x3 == 5 || x3 == 7) && (x3+x2)%2==1)
22 pozincorecta=3;
23 else
24 {
25 int i=4;
26 while((i<=ncx) && (vcifx[i]+vcifx[i-1])%2==1) i++;
27 pozincorecta=i;
28 }
29 }
30
31 int f123min(int c123)
32 {
33 int c123min=c123;
34 for(int i=4; i<=ncx; i++)
35 if(c123min%2==0) c123min=c123min*10+1;
36 else c123min=c123min*10+0;
37
38 return c123min;
39 }
40
41 int f123max(int c123)
42 {
43 int c123max=c123;
44 for(int i=4; i<=ncx; i++)
45 if(c123max%2==0) c123max=c123max*10+9;
46 else c123max=c123max*10+8;
47
48 return c123max;
49 }
50
51 void succesorX() // dupa X = OK
52 {
53 for(int i=1; i <= ncx; i++) vcifxd[i]=vcifx[i];
54
55 int poz=ncx;
56 while(vcifxd[poz]>=8) // nu pot sa adun 2 (sa rapana paritatea ok!)
57 poz=poz-1;
58
59 vcifxd[poz]=vcifxd[poz]+2;
60
61 // completez spre dreapta cu 0, 1 ...
62 for(int i=poz+1; i<=ncx; i++)
63 if(vcifxd[i-1]%2==0) vcifxd[i]=1;
64 else vcifxd[i]=0;
65
66 }
67
68 void predecesorX() // inainte de X = OK
69 {
70 for(int i=1; i<=ncx; i++) vcifxs[i]=vcifx[i]; // copie
71
72 int poz=ncx;
73 while(vcifx[poz]<=1) // nu pot sa scad 2 (sa ramana paritatea ok!)
74 poz=poz-1;
75
76 vcifxs[poz]=vcifx[poz]-2;
77
78 // completez spre dreapta cu 8, 9 ...
79 for(int i=poz+1; i<=ncx; i++)
CAPITOLUL 13. ONI 2019 172

80 if(vcifxs[i-1]%2==0) vcifxs[i]=9;
81 else vcifxs[i]=8;
82 }

444

Listing 13.2.6: Numere - Etapa nr. 4

1 void pozincorecta23() // 163 165 167 252 363 365 367 492 812
2 {
3 if(x123<163) { rez2=f123min(163); return;}
4 if(x123>812) { rez2=f123max(812); return;}
5
6 if(x123<252) // 16 < x12 < 25
7 {
8 rez2min=f123max(167); // patrat, prim cel mai mare permis
9 rez2max=f123min(252); // patrat, prim cel mai mic permis
10 rez2=rez2min;
11 if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X
12 return;
13 }
14
15 if(x12<36) // 25 < x12 < 36
16 {
17 rez2min=f123max(252);
18 rez2max=f123min(361);
19 rez2=rez2min;
20 if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X
21 return;
22 }
23
24 if(x12<49) // 36 < x12 < 49
25 {
26 rez2min=f123max(367);
27 rez2max=f123min(492);
28 rez2=rez2min;
29 if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X
30 return;
31 }
32
33 if(x12<81) // 49 < x12 < 81
34 {
35 rez2min=f123max(492);
36 rez2max=f123min(812);
37 rez2=rez2min;
38 if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X
39 return;
40 }
41 }
42
43 void pozincorecta45678()
44 {
45 if(vcifx[pozincorecta]>=1) // pot sa scad 1 ... corectez paritatea !!!
46 {
47 calcvcifxs();
48 succesor();
49 }
50 else // sigur pot sa adun 1 ... corectez paritatea !!!
51 {
52 calcvcifxd();
53 predecesor();
54 }
55
56 rez2min=rez2max=0;
57 for(int i=1; i<=ncx; i++)
58 {
59 rez2min=rez2min*10+vcifxs[i];
60 rez2max=rez2max*10+vcifxd[i];
61 }
62
63 rez2=rez2min;
64 if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X
65 }
CAPITOLUL 13. ONI 2019 173

555
Listing 13.2.7: Numere - Etapa nr. 5

1 #include<iostream> // cout ... afisari pe ecran ... !!!


2 #include<fstream> // fstream
3
4 using namespace std;
5
6 ifstream fin("numere.in");
7 ofstream fout("numere.out");
8
9 int C;
10 int N;
11 int X; // 20.000.000 incape pe "int"
12
13 int nr3c[9] = { 163, 165, 167, 252, 363, 365, 367, 492, 812 };
14
15 long long rez1=9; // unsigned long long ... este mai OK!
16 int rez2, rez2min, rez2max; // solutie pentru Cerinta 2
17
18 int vcifx[9]; // indici 0, 1, ..., 8 ... vcifx[8] EROARE la ncx=8 ...
19 int vcifxs[9]; // nr mai mic decat X (in stanga) ... predecesor
20 int vcifxd[9]; // nr mai mare decat X (in dreapta) ... succesor
21
22 int ncx; // nr cifre in X
23 int pozincorecta; // pozitia ... cu cifra incorecta
24
25 int x123; // primele 3 cifre
26 int x12; // primele 2 cifre
27 int x3; // cifra x3
28 int x2; // cifra x2
29
30 void rezolva1()
31 {
32 fin>>N;
33
34 rez1=9LL;
35 for(int i=1; i<=min(N-3,28-3); i++)// N=28 este ultimul care este ok
36 rez1=rez1*5;
37
38 if(N==29) // trebuie si ultima inmultire cu 5 ... !!!
39 {
40 int v[21]; // vector cu cifrele rezultatului
41 int i; // variabila de lucru ... trebuie si in afara for-ului
42
43 int poz=-1; // pozitia in vectorul cifrelor lui rez1
44 while(rez1>0L)
45 {
46 poz++;
47 v[poz]=rez1%10;
48 rez1=rez1/10;
49 }
50
51 // inmultirea rez*5
52 int t=0; // cifra de transport ... la inmultire
53 for(i=0; i<=poz; i++)
54 {
55 int cifra=v[i]*5+t;
56 v[i]=cifra%10;
57 t=cifra/10;
58 }
59 if(t>0) { v[i]=t; poz++; }
60 for(i=poz; i>=0; i--) fout<<v[i];
61 fout<<’\n’;
62 }
63 else
64 fout<<rez1<<’\n’;
65 }
66
67 void nrcifrex(int x)
68 {
69 ncx=0;
70 while(x>0) { ncx++; x=x/10; }
71 }
72
CAPITOLUL 13. ONI 2019 174

73 void vcifrex(int x)
74 {
75 for(int i=1; i<=ncx; i++)
76 {
77 vcifx[ncx-i+1]=x%10;
78 x=x/10;
79 }
80 }
81
82 void predecesorX() // inainte de X = OK
83 {
84 for(int i=1; i<=ncx; i++) vcifxs[i]=vcifx[i]; // copie
85
86 int poz=ncx;
87 while(vcifx[poz]<=1) // nu pot sa scad 2 (sa ramana paritatea ok!)
88 poz=poz-1;
89
90 vcifxs[poz]=vcifx[poz]-2;
91
92 // completez spre dreapta cu 8, 9 ...
93 for(int i=poz+1; i<=ncx; i++)
94 if(vcifxs[i-1]%2==0) vcifxs[i]=9;
95 else vcifxs[i]=8;
96 }
97
98 void predecesor() // inainte de vcifxd[] = existent deja
99 {
100 for(int i=1; i<=ncx; i++) vcifxs[i]=vcifxd[i]; // copie
101
102 int poz=ncx;
103 while(vcifxd[poz]<=1) // nu pot sa scad 2 (sa ramana paritatea ok!)
104 poz=poz-1;
105
106 vcifxs[poz]=vcifxd[poz]-2;
107
108 // completez spre dreapta cu 8, 9 ...
109 for(int i=poz+1; i<=ncx; i++)
110 if(vcifxs[i-1]%2==0) vcifxs[i]=9;
111 else vcifxs[i]=8;
112
113 }
114
115 void succesorX() // dupa X = OK
116 {
117 for(int i=1; i <= ncx; i++) vcifxd[i]=vcifx[i];
118
119 int poz=ncx;
120 while(vcifxd[poz]>=8) // nu pot sa adun 2 (sa ramana paritatea ok!)
121 poz=poz-1;
122
123 vcifxd[poz]=vcifxd[poz]+2;
124
125 // completez spre dreapta cu 0, 1 ...
126 for(int i=poz+1; i<=ncx; i++)
127 if(vcifxd[i-1]%2==0) vcifxd[i]=1;
128 else vcifxd[i]=0;
129
130 }
131
132 void succesor() // dupa vcifxs[] = existent deja ... !!!
133 {
134 for(int i=1; i<=ncx; i++) vcifxd[i]=vcifxs[i]; // copie
135
136 int poz=ncx;
137 while(vcifxd[poz]>=8) // nu pot sa adun 2 (sa ramana paritatea ok!)
138 poz=poz-1;
139
140 vcifxd[poz]=vcifxd[poz]+2;
141
142 // completez spre dreapta cu 0, 1 ...
143 for(int i=poz+1; i<=ncx; i++)
144 if(vcifxd[i-1]%2==0) vcifxd[i]=1;
145 else vcifxd[i]=0;
146
147 }
148
CAPITOLUL 13. ONI 2019 175

149 int f123min(int c123)


150 {
151 int c123min=c123;
152 for(int i=4; i<=ncx; i++)
153 if(c123min%2==0) c123min=c123min*10+1;
154 else c123min=c123min*10+0;
155
156 return c123min;
157 }
158
159 int f123max(int c123)
160 {
161 int c123max=c123;
162 for(int i=4; i<=ncx; i++)
163 if(c123max%2==0) c123max=c123max*10+9;
164 else c123max=c123max*10+8;
165
166 return c123max;
167 }
168
169 calcvcifxs() // pot sa scad ... construiesc vcifxs[] cat mai mare
170 {
171 for(int i=1; i<=pozincorecta; i++) vcifxs[i]=vcifx[i]; // copie ...
172 vcifxs[pozincorecta]-=1; // scad 1 ==> se repara paritatea
173
174 for(int i=pozincorecta+1; i<=ncx; i++)
175 if(vcifxs[i-1]%2==0) vcifxs[i]=9;
176 else vcifxs[i]=8;
177
178 }
179
180 calcvcifxd() // pot sa adun 1 ... construiesc vcifxd[] cat mai mic
181 {
182 for(int i=1; i<=pozincorecta; i++) vcifxs[i]=vcifx[i]; // copie ...
183 vcifxd[pozincorecta]+=1; // adun 1 ==> se repara paritatea
184
185 for(int i=pozincorecta+1; i<=ncx; i++)
186 if(vcifxd[i-1]%2==0) vcifxd[i]=1;
187 else vcifxd[i]=0;
188
189 }
190
191 void calcpozincorecta()
192 {
193 if(x12 != 16 && x12 != 25 && x12 != 36 && x12 != 49 && x12 != 81)
194 pozincorecta=2;
195 else
196 if(!(x3 == 2 || x3 == 3 || x3 == 5 || x3 == 7) && (x3+x2)%2==1)
197 pozincorecta=3;
198 else
199 {
200 int i=4;
201 while((i<=ncx) && (vcifx[i]+vcifx[i-1])%2==1) i++;
202 pozincorecta=i;
203 }
204 }
205
206 void pozincorecta23() // 163 165 167 252 363 365 367 492 812
207 {
208 if(x123<163) { rez2=f123min(163); return;}
209 if(x123>812) { rez2=f123max(812); return;}
210
211 if(x123<252) // 16 < x12 < 25
212 {
213 rez2min=f123max(167); // patrat, prim cel mai mare permis
214 rez2max=f123min(252); // patrat, prim cel mai mic permis
215 rez2=rez2min;
216 if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X
217 return;
218 }
219
220 if(x12<36) // 25 < x12 < 36
221 {
222 rez2min=f123max(252);
223 rez2max=f123min(361);
224 rez2=rez2min;
CAPITOLUL 13. ONI 2019 176

225 if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X


226 return;
227 }
228
229 if(x12<49) // 36 < x12 < 49
230 {
231 rez2min=f123max(367);
232 rez2max=f123min(492);
233 rez2=rez2min;
234 if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X
235 return;
236 }
237
238 if(x12<81) // 49 < x12 < 81
239 {
240 rez2min=f123max(492);
241 rez2max=f123min(812);
242 rez2=rez2min;
243 if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X
244 return;
245 }
246 }
247
248 void pozincorecta45678()
249 {
250 if(vcifx[pozincorecta]>=1) // pot sa scad 1 ... corectez paritatea !!!
251 {
252 calcvcifxs();
253 succesor();
254 }
255 else // pot sa adun 1 ... corectez paritatea !!!
256 {
257 calcvcifxd();
258 predecesor();
259 }
260
261 rez2min=rez2max=0;
262 for(int i=1; i<=ncx; i++)
263 {
264 rez2min=rez2min*10+vcifxs[i];
265 rez2max=rez2max*10+vcifxd[i];
266 }
267
268 rez2=rez2min;
269 if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X
270 }
271
272 void rezolva2()
273 {
274 fin>>X;
275
276 nrcifrex(X);
277 vcifrex(X);
278
279 x123=X;
280 for(int i=ncx; i>=4; i--) x123=x123/10;
281 x12=x123/10;
282 x3=x123%10;
283
284 calcpozincorecta();
285
286 if(pozincorecta>ncx) // X este OK ...
287 {
288 rez2=X; // ... trebuie sa fie DIFERIT de X ... !!!
289
290 int x123min=f123min(x123);
291 int x123max=f123max(x123);
292
293 if(X < x123max) succesorX(); // vcifxd[]
294 if(X > x123min) predecesorX(); // vcifxs[]
295
296 rez2min=rez2max=0;
297 for(int i=1; i<=ncx; i++)
298 {
299 rez2min=rez2min*10+vcifxs[i];
300 rez2max=rez2max*10+vcifxd[i];
CAPITOLUL 13. ONI 2019 177

301 }
302
303 if(X == x123min) rez2 = rez2max;
304 else
305 if(X == x123max) rez2 = rez2min;
306 else
307 {
308 rez2=rez2min;
309 if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X
310 }
311 }
312 else
313 if(pozincorecta<=3) pozincorecta23();
314 else pozincorecta45678();
315
316 fout<<rez2<<’\n’;
317 }
318
319 int main()
320 {
321 fin>>C;
322
323 if(C==1) rezolva1();
324 if(C==2) rezolva2();
325
326 return 0;
327 }

13.3 Trio
Problema 3 - Trio 100 de puncte
Trio este un joc ce conµine N piese de aceea³i form , a³ezate una lâng  alta pe o tabl  de joc
³i numerotate de la stânga la dreapta cu valori de la 1 la N. Fiecare pies  are marcate pe ea trei
zone, iar în ecare dintre ele este scris  câte o cifr . Se consider  c  o pies  pe care sunt scrise în
ordine, de la stânga la dreapta, cifrele C1,C2 ³i C3 are urm toarele propriet µi:
identic  cu o alt  pies , dac  aceast  pies  conµine exact acelea³i cifre, în aceea³i ordine
este
cu ale ei sau în ordine invers . Astfel, piesa C1 C2 C3 este identic  cu o alt  pies  de
forma C1 C2 C3 ³i cu o pies  de forma C3 C2 C1 .
este prieten  cu o alt  pies  dac  aceasta conµine exact acelea³i cifre ca piesa dat ,
dar nu neap rat în aceea³i ordine. Astfel, piesa C1 C2 C3 este prieten  cu piesele:
C1 C2 C3 , C1 C3 C2 , C2 C1 C3 , C2 C3 C1 , C3 C1 C2
³i C3 C2 C1 . Se observ  c  dou  piese identice sunt ³i prietene!
Un grup de piese prietene este format din TOATE piesele prietene între ele, aate pe tabla
de joc.

Cerinµe
1) Alegeµi o pies  de pe tabla de joc, astfel încât num rul M al pieselor identice cu ea s  e
cel mai mare posibil ³i a³aµi num rul M determinat;
2) A³aµi num rul grupurilor de piese prietene existente pe tabla de joc;
3) A³aµi num rul maxim de piese dintr-o secvenµ  ce conµine piese a³ezate una lâng  alta pe
tabla de joc, pentru care prima pies  ³i ultima pies  din secvenµ  sunt prietene.

Date de intrare
- pe prima linie un num r natural C care reprezint  num rul cerinµei ³i poate avea valorile 1,
2 sau 3.
- pe cea de-a doua linie un num r natural N ce reprezint  num rul pieselor de joc;
- pe urm toarele N linii, câte trei cifre, desp rµite prin câte un spaµiu, ce reprezint , în ordine,
cifrele scrise pe câte o pies  de joc. Piesele sunt date în ordinea numerot rii acestora pe tabla de
joc.

Date de ie³ire
CAPITOLUL 13. ONI 2019 178

Fi³ierul trio.out va conµine pe prima linie un singur num r natural ce reprezint  rezultatul
determinat conform ec rei cerinµe.

Restricµii ³i preciz ri
2&N & 100 000
Exist  cel puµin dou  piese identice pe tabla de joc;
O pies  ce nu e prieten  cu nicio alt  pies  de pe tabla de joc formeaz  singur  un grup;
Pentru rezolvarea cerinµei 1) se acord  20 de puncte, pentru rezolvarea cerinµei 2) se acord 
30 de puncte iar pentru rezolvarea cerinµei 3) se acord  50 de puncte.

Exemple
trio.in trio.out Explicaµii
1 2 .
6
1 3 3
4 5 9
1 3 3
Se rezolv  cerinµa 1. Alegând oricare din piesele 1, 3 sau 5 exist 
9 5 4
pe tabl  două piese identice cu piesa aleas . Alegând oricare din piesele
3 3 1
2 sau 4 exist  doar o pies  ce este identic  cu piesa aleas .
9 4 5
Dac  alegem piesa 6 nu exist  pe tabl  piese identice cu ea.
1 2 .
6
1 3 3
4 5 9
1 3 3
Se rezolv  cerinµa 2. Piesele 1 ³i 5 formez  un grup de piese prietene.
9 5 4
Piesele 2, 4 ³i 6 formeaz  alt grup. Piesa 3 formează singur  un grup.
3 3 1
În total, pe tabl , sunt 3 grupuri de piese prietene.
9 4 5
1 2 Se rezolv  cerința 3. Identic m dou  secvenµe de lungime ma-
6 xim , egal  cu 5, pentru care prima ³i ultima pies  sunt prietene:
1 3 3
4 5 9
1 3 3
9 5 4
3 3 1
9 4 5

Timp maxim de executare/test: 0.2 secunde


Memorie: total 2MB din care pentru stiv  2MB
Dimensiune maxim  a sursei: 15KB
Sursa: trio.cpp, trio.c sau trio.pas va  salvat  în folderul care are drept nume ID-ul t u.

13.3.1 Indicaµii de rezolvare

Prof. Cristina Iordaiche, Liceul Teoretic Grigore Moisil Timi³oara

Cerinµa 1
- pentru determinarea num rului M ce reprezint  cel mai mare num r de piese de pe tabla de
joc, identice cu o pies  aleas , se construie³te un vector de frecvenµ  V cu ajutorul c ruia se va
contoriza num rul pieselor identice;
- ec rei piese C1 C2 C3 îi vom asocia o valoare numeric  C1*100+C2*10+C3, aceast 
valoare este un num r natural din intervalul [0,999];
C1 C2 C3 ³i
- se va µine cont de faptul c  pentru oricare dou  piese identice

C3 C2 C1 vor avea asociat  aceea³i valoare numeric ;


- V[C1*100+C2*10+C3] se va incrementa de ecare dat  când este întâlnit  pe tabla de joc o
pies  ce are asociat  valoarea numeric  prezizat  mai sus;
CAPITOLUL 13. ONI 2019 179

- se va determina valoarea maxim  memorat  în vectorul V.


Cerinµa 2
- pentru determinarea num rului de grupe de piese prietene de pe tabla de joc, se vor identica
toate piesele prietene de pe tabla de joc ce aparµin aceluia³i grup.
- deoarece C1 C2 C3 ,
piesele C1 C3 C2 , C2 C1 C3 ,

C2 C3 C1 , C3 C1 C2 ³i C3 C2 C1 aparµin aceluia³i grup de piese


prietene, toate vor avea asociat  aceea³i valoare numeric  egal  cu C1*100+C2*10+C3. Aceast 
valoare se poate obµine prin ordonarea cresc toare a celor trei cifre C1,C2 ³i C3
- se va memora cu ajutorul unui vector de frecvenµ  num rul de apariµii al ec rei valori
numerice din intervalul [0,999]
- se va utiliza o variabil  de tip contor pentru num rarea tuturor grupurilor de piese prietene

Cerinµa 3
- Pentru determinarea celei mai lungi secvenµe de piese a³ezate una lâng  alta pe tabla de
joc, în care prima ³i ultima pies  sunt prietene, vom memora pentru ecare valoare din intervalul
[0,999] indicele primei piese ³i indicele ultimei piese de pe table joc, ce are asociat  acea valoare.

13.3.2 Cod surs 

Listing 13.3.1: trio_cpp.cpp

1 #include <fstream>
2 #include <iostream>
3 #include <algorithm> // sort
4
5 using namespace std;
6
7 ifstream f("trio.in");
8 ofstream g("trio.out");
9
10 int N,C,nr,ap[1000],c[4],max_identice,nr_ord,nr_grupuri;
11
12 bool grup[1000]= {0}; //cerinta2
13
14 int ultima_poz[1000], prima_poz[1000]={0}, max_echivalente; //cerinta3
15
16 int main()
17 {
18 int i;
19 f>>C>>N;
20
21 for(int i=1; i<=N; i++)
22 {
23 f>>c[1]>>c[2]>>c[3];
24 if(c[3]>c[1])
25 swap(c[1],c[3]);
26
27 nr=(c[1]*100+c[2]*10+c[3]);
28 ap[nr]++;
29
30 if(ap[nr]>max_identice)
31 max_identice=ap[nr];
32
33 // ordonez cifrele de pe o piesa pentru a determina
34 // cele ce aprtin aceluiasi grup
35 sort(c+1,c+4);
36
37 nr_ord=c[1]*100+c[2]*10+c[3];
38 grup[nr_ord]=1;// vector de aparitii ptr grup
39
40 if(prima_poz[nr_ord]==0)
41 //memorez primul nr de ordine al unei piese din grup
42 prima_poz[nr_ord]=i;
43 else
44 //memorez ultimul numar de ordine al unei piese din acelasi grup
45 ultima_poz[nr_ord]=i;
46 }
47
48 if (C==1)
CAPITOLUL 13. ONI 2019 180

49 g<<max_identice-1<<’\n’;
50 else
51 if (C==2)
52 {
53 for(i=0; i<=999; i++)
54 if(grup[i]) nr_grupuri++;
55 g<<nr_grupuri<<’\n’;
56 }
57 else
58 {
59 for(i=0; i<=999; i++)
60 if(ultima_poz[i]-prima_poz[i]>max_echivalente)
61 max_echivalente=ultima_poz[i]-prima_poz[i];
62 g<<max_echivalente+1<<’\n’;
63 }
64 return 0;
65 }

13.3.3 Rezolvare detaliat 

Listing 13.3.2: Trio - Etapa nr. 0

1 #include<iostream> // cout
2 #include<fstream> // fstream
3
4 using namespace std;
5
6 ifstream fin("trio.in");
7 ofstream fout("trio.out");
8
9 int C; // nr cerinta
10 int N;
11
12 int c1, c2, c3;
13
14 void rezolva1()
15 {
16 for(int i=1; i<=N; i++)
17 {
18 fin>>c1>>c2>>c3;
19
20 }
21 }
22
23 void rezolva2()
24 {
25 for(int i=1; i<=N; i++)
26 {
27 fin>>c1>>c2>>c3;
28
29 }
30 }
31
32 void rezolva3()
33 {
34 for(int i=1; i<=N; i++)
35 {
36 fin>>c1>>c2>>c3;
37
38 }
39 }
40
41 int main()
42 {
43 fin>>C;
44 fin>>N;
45
46 if(C==1) rezolva1();
47 else
48 if(C==2) rezolva2();
49 else
50 if(C==3) rezolva3();
CAPITOLUL 13. ONI 2019 181

51
52 return 0;
53 }

Listing 13.3.3: Trio - Etapa nr. 1

1 void rezolva1()
2 {
3 int nraparitii[1000]={0}; // nu N ... !!!
4 int p123; // "prieteni": 123 cu 321
5 int maxp; // raspuns la cerinta 1
6 int aux; // variabila auxiliara pentru interschimbare
7
8 for(int i=1; i<=N; i++)
9 {
10 fin>>c1>>c2>>c3;
11 if(c1>c3) {aux=c1; c1=c3; c3=aux;} // c1 <= c3 "identice" (1,2,3)=(3,2,1)
12 p123=c1*100+c2*10+c3;
13 nraparitii[p123]++;
14 }
15
16 maxp=0;
17 for(int i=0; i<=999; i++)
18 if(nraparitii[i] > maxp)
19 maxp=nraparitii[i];
20
21 cout<<"maxp-1 = "<<maxp-1<<"\n";
22 fout<<maxp-1<<’\n’; // Atentie la textul cerintei si exemplul 1
23 }

Listing 13.3.4: Trio - Etapa nr. 2

1 void rezolva2()
2 {
3 int nraparitii[1000]={0}; // nu N ... !!!
4 int p123; // "prieteni": 123 cu 321
5 int nrgp; // nr grupuri de prieteni - raspuns la cerinta 2
6 int aux; // variabila auxiliara pentru interschimbare
7
8 for(int i=1; i<=N; i++)
9 {
10 fin>>c1>>c2>>c3;
11 if(c1>c2) {aux=c1; c1=c2; c2=aux;} // c1 <= c2
12 if(c1>c3) {aux=c1; c1=c3; c3=aux;} // c1 <= c3 deci c1=min
13 if(c2>c3) {aux=c2; c2=c3; c3=aux;} // c2 <= c3 deci c3=max
14
15 p123=c1*100+c2*10+c3; // c1 <= c2 <= c3
16 nraparitii[p123]++;
17 }
18
19 nrgp=0;
20 for(int i=0; i<=999; i++)
21 if(nraparitii[i] > 0)
22 nrgp+=1;
23
24 cout<<"nrgp = "<<nrgp<<"\n";
25 fout<<nrgp<<’\n’; // Atentie la textul cerintei si exemplul 2
26 }

Listing 13.3.5: Trio - Etapa nr. 3

1 void rezolva3()
2 {
3 int primaaparitie[1000]={0}; // nu N ... !!!
4 int ultimaaparitie[1000]={0}; // nu N ... !!!
5
6 int p123; // "prieteni": 123 cu 321
7 int maxpiese; // nr max piese - raspuns la cerinta 3
8 int aux; // variabila auxiliara pentru interschimbare
9
10 for(int i=1; i<=N; i++)
11 {
12 fin>>c1>>c2>>c3;
CAPITOLUL 13. ONI 2019 182

13 if(c1>c2) {aux=c1; c1=c2; c2=aux;} // c1 <= c2


14 if(c1>c3) {aux=c1; c1=c3; c3=aux;} // c1 <= c3 deci c1=min
15 if(c2>c3) {aux=c2; c2=c3; c3=aux;} // c2 <= c3 deci c3=max
16
17 p123=c1*100+c2*10+c3; // c1 <= c2 <= c3
18
19 if(primaaparitie[p123]==0)
20 primaaparitie[p123]=i;
21 else
22 ultimaaparitie[p123]=i;
23 }
24
25 maxpiese=0;
26 for(int i=0; i<=999; i++)
27 if(ultimaaparitie[i] - primaaparitie[i] > maxpiese)
28 maxpiese=ultimaaparitie[i] - primaaparitie[i];
29
30 cout<<"maxpiese = "<<maxpiese+1<<"\n";
31 fout<<maxpiese+1<<’\n’; // Atentie la textul cerintei si exemplul 3
32 }
Capitolul 14

ONI 2018

14.1 desen
Problema 1 - desen 100 de puncte
La ora de desen, Gigel a primit ca tem  un desen care s 
e realizat dup  urm torul algoritm:

Pas 1: se deseneaz  un triunghi, numerotat cu 1, ca în


Figura 1;
Pas 2: se împarte triunghiul 1 în trei poligoane (un drept-
unghi ³i dou  triunghiuri numerotate cu 2 ³i 3) trasând dou 
segmente ca în Figura 2 ;
Pas 3: ecare triunghi dintre cele dou  obµinute la Pas
2, se împarte în câte un dreptunghi ³i câte dou  triunghiuri
(numerotate cu 4, 5, 6, 7) trasând câte dou  segmente ca în
Figura 3 ;
Pas 4: ecare triunghi dintre cele patru obµinute la Pas
3, se împarte în câte un dreptunghi ³i câte dou  triunghiuri
(numerotate cu 8, 9,10, 11, 12, 13, 14, 15) trasând câte dou 
segmente ca în Figura 4 ;

.......

Pas N: ecare triunghi dintre triunghiurile obµinute la


Pas N  1, se împarte în câte un dreptunghi ³i câte dou 
triunghiuri trasând câte dou  segmente.

Dac  valoarea lui K este ultimul num r folosit pentru nu-


merotarea triunghiurilor obµinute la Pas N  1, atunci tri-
unghiurile rezultate la Pas N vor  numerotate cu numerele
naturale distincte consecutive K  1, K  2, K  3, ..., etc.

Cerinµe
Scrieµi un program care s  citeasc  num rul natural K ³i
s  determine:

1. cel mai mic num r X ³i cel mai mare num r Y dintre


numerele folosite pentru numerotarea triunghiurilor obµinute
la pasul în care este obµinut ³i triunghiul numerotat cu K;
2. numerele triunghiurilor care au fost împ rµite conform
algoritmului din enunµ astfel încât s  e obµinut triunghiul
numerotat cu K.

Date de intrare Figura 14.1: desen

Fi³ierul de intrare desen.in conµine pe prima linie un num r natural C reprezentând cerinµa
din problem  care trebuie rezolvat  (1 sau 2).
Fi³ierul conµine pe a doua linie num rul natural K.

183
CAPITOLUL 14. ONI 2018 184

Date de ie³ire
Dac  C 1, atunci prima linie a ³ierului de ie³ire desen.out conµine cele dou  numere
naturale X ³i Y , separate printr-un singur spaµiu, reprezentând r spunsul la cerinµa 1 a problemei.
Dac  C 2, atunci prima linie a ³ierului de ie³ire desen.out conµine un ³ir de numere
naturale ordonate cresc tor, separate prin câte un spaµiu, reprezentând r spunsul la cerinµa 2 a
problemei.

Restricµii ³i preciz ri
2&K & 9223372036854775807 63
a 2  1
a doar triunghiurile sunt numerotate
a pentru rezolvarea corect  a cerinµei 1 se acord  40 de puncte
a pentru rezolvarea corect  a cerinµei 2 se acord  60 de puncte.

Exemple
desen.in desen.out Explicaµii
1 13 8 15 Cerinµa este 1, K 13. A³a cum arat  în Figura 4, la Pas 4
se obµin triunghiurile numerotate cu X 8, 9, 10, 11, 12, 13, 14,
Y 15.
2 13 1 3 6 Cerinµa este 2, K 13. A³a cum arat  Figura 4, triunghiul
numerotat cu K 13 se obµine din triunghiul 6. Triunghiul 6
este obµinut din triunghiul 3 care este obµinut din triunghiul 1.

Timp maxim de executare/test: 0.3 secunde


Memorie: total 8 MB din care pentru stiv  8 MB
Dimensiune maxim  a sursei: 5 KB

14.1.1 Indicaµii de rezolvare


prof. Daniela T taru, Colegiul Naµional Al. D. Ghica, Alexandria

Observ m c :

Exemple
Pas Cel mai mic num r folosit Cel mai mare num r folosit Num r triunghiuri
la numerotarea triunghiurilor la numerotarea triunghiurilor obµinute la acest
obµinute la acest pas obµinute la acest pas pas
0
Pas 1: 1 1 2
1
Pas 2: 2 3 2
2
Pas 3: 4 7 2
3
Pas 4: 8 15 2
Pas ...: ... ... ...
N 1 N N 1
Pas N: 2 2  1 2

Cerinµa 1.
Se determin  valorile X ³i Y cu proprietatea c :
N 1 N 1
X 2&K&Y N
2 1 2˜2  1 2˜X  1
Cerinµa 2.
Se a³eaz  în ordine invers  valorile:
x1 K ©2, x2 x1 ©2, x3 x2 ©2, ..., xN 1

14.1.2 *Cod surs 

14.1.3 *Rezolvare detaliat 


CAPITOLUL 14. ONI 2018 185

14.2 mostenire
Problema 2 - mostenire 100 de puncte
Regele Rufus dore³te s  stabileasc  mo³tenitorul averii sale, adic  s  ofere parola de la seif
celui mai de³tept dintre ii s i. Iniµial, regele a avut parola X format  din N cifre nenule ³i un
cod cheie Q (num r natural cu exact 9 cifre, distincte, toate nenule). În ecare an din cei K ani
de domnie, folosind codul cheie Q, Rufus a modicat câte o secvenµ  de cifre din parol  ajungând
la parola nal  P.
Pentru ecare secvenµ  se cunoa³te poziµia S a primei cifre din secvenµ  ³i poziµia D a ultimei
cifre din secvenµ . Astfel, secvenµa este format  din cifrele situate pe poziµiile S , S  1, S  2, ...,
D în parola X.
Modicarea unei secvenµe din X const  în înlocuirea ec rei apariµii a cifrei 1 cu prima cifr 
a lui Q, apoi a ec rei apariµii a cifrei 2 cu a doua cifr  a lui Q, ..., a ec rei apariµii a cifrei 9 cu
ultima cifr  a lui Q.
Pentru a decide mo³tenitorul, regele le d  ilor parola nal  P, codul cheie Q, num rul K
de ani de domnie si cele K secvenµe de cifre care au fost modicate ³i le cere s  g sesc : parola
iniµial  X, poziµia minim  Z din parola X care a ap rut în cele mai multe secvenµe dintre cele
modicate de rege de-a lungul celor K ani de domnie ³i cifrele distincte care au ocupat poziµia Z
în cei K ani.

Cerinµe
Scrieµi un program care cite³te numerele Q, N , K , cele N cifre ale parolei nale P ³i cele K
perechi de poziµii S ³i D, ³i care rezolv  urm toarele dou  cerinµe:

1. determin  parola iniµial  X;


2. determin  poziµia minim  Z ³i cifrele distincte care au ocupat aceast  poziµie în cei K ani
de domnie.

Date de intrare
Fi³ierul de intrare mostenire.in conµine pe prima linie un num r natural C reprezentând
cerinµa din problem  care trebuie rezolvat  (1 sau 2). A doua linie din ³ier conµine cele trei
numere naturale Q, N ³i K , separate prin câte un spaµiu. A treia linie din sier conµine cele N
cifre ale parolei nale P , separate prin câte un spaµiu. Fiecare linie dintre urm toarele K , conµine
câte dou  numere naturale S ³i D , separate printr-un singur spaµiu, reprezentând câte o pereche
de poziµii.

Date de ie³ire
Dac  C 1, ³ierul de ie³ire mostenire.out va conµine pe prima linie cele N cifre ale parolei
initiale X , separate prin câte un spaµiu, în ordinea în care apar în X, reprezentând r spunsul la
cerinµa 1.
Dac  C 2, ³ierul de ie³ire mostenire.out va conµine pe prima linie num rul natural Z , iar
pe a doua linie cifrele distincte care au ap rut pe poziµia minim  Z, reprezentând r spunsul la
cerinµa 2. Acestea vor  a³ate în ordine cresc toare, separate prin câte un spaµiu.

Restricµii ³i preciz ri
a 1&N & 10000
a num rul natural Q este format din exact 9 cifre, distincte ³i nenule
a poziµiile cifrelor din parola X sunt numerotate cu numerele distincte consecutive 1, 2, ..., N
a 1&K & 100
a pentru toate perechile de poziµii modicate de rege: S &D
a cel puµin o cifr  din parola X va  înlocuit 
a pentru rezolvarea corect  a cerinµei 1 se acord  50 de puncte
a pentru rezolvarea corect  a cerinµei 2 se acord  50 de puncte.
CAPITOLUL 14. ONI 2018 186

Exemple:
mostenire.in mostenire.out Explicaµii
1 2 7 3 5 4 1 3 3 7 9 2 8 Cerinµa este 1, N=12, K=4.
712534698 12 4
1 4 7 1 3 4 7 1 4 8 1 8
2 4
6 11
3 9
1 7

2 3 Cerinµa este 2, N=12, K=4.


712534698 12 4 1 2 3 7 P=(1 4 7 1 3 4 7 1 4 8 1 8)
1 4 7 1 3 4 7 1 4 8 1 8 Poziµiile care au ap rut în cele mai multe secvenµe
2 4 sunt: 3,4,6,7 => Z=3, iar cifrele distincte care au
6 11 ocupat succesiv aceast  pozitie sunt 3,2,1,7. Aceste
3 9 cifre se vor scrie în ³ier în ordine cresc toare
1 7

Timp maxim de executare/test: 0.3 secunde


Memorie: total 8 MB din care pentru stiv  8 MB
Dimensiune maxim  a sursei: 10 KB

14.2.1 Indicaµii de rezolvare


prof. Flavius Boian, Colegiul Naµional Spiru Haret, Târgu Jiu

Cerinta 1
Se citesc succesiv intervalele S, D pe care s-au aplicat modic ri.
Pentru secvenµa curent , ecare cifr  poziµionat  în secvenµ  se înlocuie³te cu poziµia acestei
cifre în codul Q realizându-se astfel transformarea în sens invers.

Cerinta 2
Se poate utiliza un vector de frecvenµ  cu N elemente. Pentru ecare poziµie i din vector se
determin  num rul secvenµelor în care a ap rut acest  poziµie. Apoi, se stabileste pozitia minim 
Z cu num r maxim de apariµii.

Dup  ce s-a stabilit pozitia Z, se determin  cifrele ce au ocupat acest  poziµie, realizând de K
ori transformarea în sens invers. Se poate utiliza un vector de frecvenµ  pentru a marca apariµia
acestor cifre ³i pentru a le a³a în ordine strict cresc toare.

14.2.2 *Cod surs 

14.2.3 *Rezolvare detaliat 

14.3 pyk
Problema 3 - pyk 100 de puncte
Fie k , n ³i y trei numere naturale.
Fie X un ³ir format din n numere naturale: x1 , x2 , x3 , ..., xn .
Fie P produsul numerelor y , x1 , x2 , x3 , ..., xn , adic : P y ˜ x1 ˜ x2 ˜ x3 ˜ ... ˜ xn .
k
Num rul P este o  k -putere dac  exist  un num r natural z astfel încât P z .

Cerinµe
Scrieµi un program care s  citeasc  numerele k , n, x1 , x2 , x3 , ..., xn ³i care s  determine:
1. cel mai mic num r ³i cel mai mare num r din ³irul X , formate doar din cifre identice;
2. descompunerea în factori primi a celui mai mic num r natural y (y ' 2) cu proprietatea c 
num rul P y ˜ x1 ˜ x2 ˜ x3 ˜ ... ˜ xn este o  k -putere.
CAPITOLUL 14. ONI 2018 187

Date de intrare
Fi³ierul de intrare pyk.in conµine:
a pe prima linie, un num r natural C reprezentând cerinµa din problem  care trebuie rezolvat 
(1 sau 2);
a pe a doua linie, numerele naturale k ³i n, separate printr-un singur spaµiu;
a pe a treia linie, cele n numere naturale x1 , x2 , x3 , ..., xn , separate prin câte un singur spaµiu.

Date de ie³ire
Dac  C 1, atunci prima linie a ³ierului de ie³ire pyk.out conµine dou  numere naturale,
separate printr-un singur spaµiu, reprezentând r spunsul la cerinµa 1 a problemei. Dac  nu exist 
astfel de numere, prima linie a ³ierului va conµine valoarea 1.
Dac  C 2, atunci ³ierul de ie³ire pyk.out conµine:
a pe prima linie, un num r natural m reprezentând num rul de factori primi distincµi din
descompunerea în factori primi a num rului y , determinat la rezolvarea cerinµei 2;
a pe ecare dintre urm toarele m linii (câte o linie pentru ecare factor prim din descompunerea
în factori primi a lui y ), câte dou  valori F ³i E , separate printr-un singur spaµiu, reprezentând
factorul prim F ³i exponentul E al acestui factor din descompunerea în factori primi a lui y .

Scrierea în ³ier a acestor factori primi se va face în ordinea cresc toare a valorii lor.

Restricµii ³i preciz ri
a 2 & n & 50000
a 2 & k & 100
a 2 & x1 , x2 , x3 , ..., xn & 10000
a 2&y
a pentru rezolvarea corect  a cerinµei 1 se acord  10 puncte
a pentru rezolvarea corect  a cerinµei 2 se acord  90 de puncte.

Exemple
pyk.in pyk.out Explicaµii
1 4 1111 Cerinµa este 1, k 2, n 7.
2 7 Numerele din ³irul X formate doar din cifre identice sunt:
122 1111 5 4 88 123 999 1111, 5, 4, 88, 999. Cel mai mic num r dintre acestea este
4, iar cel mai mare este 1111.
2 3 Cerinµa este 2, k 3, n 6. Produsul celor 6 numere din
3 6 2 1 ³ir este: 12*5*60*125*4*36=64800000
12 5 60 125 4 36 3 2 y 90 este cea mai mic  valoare pentru care P 90 ˜
3
5 1 64800000 1800 devine o k-putere.
Descompunerea în factori primi a lui y conµine m 3
1 2 1
factori primi : 2 ˜ 3 ˜ 5

Timp maxim de executare/test: 0.3 secunde


Memorie: total 8 MB din care pentru stiv  8 MB
Dimensiune maxim  a sursei: 5 KB

14.3.1 Indicaµii de rezolvare


prof. Carmen Minc , Colegiul Naµional de Informatic  Tudor Vianu, Bucure³ti

Cerinta 1.
Se pot folosi dou  variabile xmin ³i xmax pentru a memora valorile cerute. Se citesc succesiv
numerele din ³ier. Se compar  cifrele ec rui num r. Dac  cifrele sunt identice, atunci num rul
curent se compar  cu xmax ³i xmin curent, actualizându-se valorile acestora.

Cerinµa 2.
O soluµie se poate obµine f r  a calcula produsul numerelor astfel:
a Se determin  numerele prime & 10000 folosind eventual Ciurul lui Eratostene (se vor memora
într-un vector v)
a Se cite³te din ³ier ecare num r din ³irul X. Se poate determina frecvenµa de apariµie
pentru ecare num r din ³ir cu ajutorul unui vector de frecvenµ  (vectorul f r).
CAPITOLUL 14. ONI 2018 188

a Se parcurge vectorul f r. Pentru ecare num r cu frecvenµa nenul  se veric  dac  este prim
(adic  dac  apare în vectorul v ).
În caz contrar se descompune în factori primi. Se contorizeaz  ecare apariµie a ec rui factor
prim luând în calcul ³i frecvenµa de apariµie a num rului descompus (se utilizeaz  un vector w
în care elementul wj  memoreaz  produsul dintre frecvenµa de apariµie a factorului prim j ³i
exponentul acestuia). Elementele wj  % 0 au semnicaµia: factorul prim j are exponentul wj 
în descompunerea în factori primi a lui y.
a Dac  factorii primi din produsul numerelor x1 , x2 , ..., xn au toµi exponenµii multiplu de k,
k
atunci produsul numerelor din ³ir este o k -putere ³i y este 2
În caz contrar, num rul factorilor primi din descompunerea lui y este egal cu num rul valorilor
j din vectorul w, cu proprietatea c  wj %k % 0. În y, exponentii acestor factori primi j vor 
egali cu k  wj %k (se incrementeaz  exponentul pân  la primul multiplu de k ).

14.3.2 *Cod surs 

14.3.3 *Rezolvare detaliat 


Capitolul 15

ONI 2017

15.1 prime
Problema 1 - prime 100 de puncte
Eu sunt fascinat  de numerele prime. Consider c  numerele prime sunt "scheletul" tuturor
numerelor sau "atomii" acestora, pentru c  orice num r natural mai mare decât 1 poate  scris
ca un produs de numere prime. Recent am aat ³i alte propriet µi interesante legate de numerele
prime, de exemplu:

1. În ³irul Fibonacci exist  o innitate de numere prime. V  mai amintiµi ³irul Fibonacci? 0,
1, 1, 2, 3, 5, 8, 13, ... Este ³irul în care ecare termen, exceptând primii doi, se obµine ca suma
celor doi termeni care îl preced .

2. Exist  numere naturale denumite economice . Un num r natural este economic dac 
num rul de cifre necesare pentru scrierea sa este mai mare decât num rul de cifre necesare pentru
scrierea descompunerii sale în factori primi (adic  decât num rul de cifre necesare pentru scrierea
factorilor primi ³i a puterilor acestora). De exemplu 128 este economic pentru c  128 se scrie cu 3
7
cifre, iar descompunerea sa în factori primi se scrie cu dou  cifre (2 ); 4374 este economic pentru
7
c  se scrie cu 4 cifre, în timp ce descompunerea sa în factori primi se scrie cu 3 cifre (2 ˜ 3 )
Observaµi c  atunci când un factor prim apare la puterea 1, aceasta nu este necesar s  e scris .

3. Multe numere naturale pot  scrise ca sum  de dou  numere prime. Dar nu toate. De
exemplu, 121 nu poate  scris ca sum  de dou  numere prime.

Cerinµe
Scrieµi un program care cite³te num rul natural n ³i o secvenµ  de n numere naturale, apoi
rezolv  urm toarele cerinµe:
1. determin  ³i a³eaz  câte dintre numerele din secvenµa dat  sunt numere prime din ³irul
Fibonacci;
2. determin  ³i a³eaz  câte dintre numerele din secvenµa dat  sunt numere economice;
3. determin  ³i a³eaz  câte dintre numerele din secvenµa dat  nu pot  scrise ca sum  de
dou  numere prime.

Date de intrare
Fi³ierul de intrare prime.in conµine pe prima linie un num r natural c care reprezint  cerinµa
(1, 2 sau 3). Pe a doua linie se a  num rul natural n. Pe a treia linie se a  o secvenµ  de n
numere naturale separate prin spaµii.

Date de ie³ire
Fi³ierul de ie³ire prime.out va conµine o singur  linie pe care va  scris r spunsul la cerinµa
din ³ierul de intrare.

Restricµii ³i preciz ri

189
CAPITOLUL 15. ONI 2017 190

a 1 $ n & 50
7
a Dac  c 1 sau c 3 numerele naturale din ³ir sunt mai mari decât 1 ³i mai mici decât 10 .
14
a Dac  c 2 numerele naturale din ³ir sunt mai mari decât 1 ³i mai mici decât 10 .
a Pentru rezolvarea corect  a cerinµei 1 se acord  20 de puncte; pentru rezolvarea corect  a
cerinµei 2 se acord  50 de puncte, iar pentru rezolvarea corect  a cerinµei 3 se acord  30 de puncte.

Exemple
prime.in prime.out Explicaµii
1 3 Cerinµa este 1. Cele 3 numere prime din ³irul Fibonacci existente
5 în secvenµ  sunt 2, 13 ³i 233.
2 10 13 997 233
2 2 Cerinµa este 2. Succesiunea conµine dou  numere economice
4 (128 ³i 4374).
128 25 4374 720
3 4 Cerinµa este 3. Sunt 4 numere naturale din secvenµ  care nu pot
5  scrise ca sum  de dou  numere prime: 57, 121, 11, 3.
57 30 121 11 3

Timp maxim de executare/test: 1.2 secunde


Memorie: total 24 MB din care pentru stiv  1 MB
Dimensiune maxim  a sursei: 15 KB

15.1.1 Indicaµii de rezolvare


prof. Emanuela Cerchez, Colegiul Naµional "Emil Racoviµ " Ia³i

Vom citi într-un vector a cele n valori ³i vom determina vmax cea mai mare valoare din vector.
Pentru o abordare ecient , pentru toate cele 3 cerinµe, pregener m numerele prime & 10
7

(sau & vmax pentru cerinµele 1 ³i 3, respectiv sqrt vmax pentru cerinµa 2). Pentru aceasta vom
utiliza ciurul lui Eratostene, apoi vom transfera numerele prime într-un vector denumit prim, care
va avea nrprim elemente. Pentru cerinµa 2 poate  util s  precalcul m ³i s  reµinem într-un vector
³i lungimea ec rui num r prim.
Pentru cerinµa 1 este sucient s  gener m termenii ³irului Fibonacci & vmax ³i s  memor m
într-un vector acei termeni care sunt numere prime. Fiindc  num rul de termeni primi din ³irul
Fibonacci & 7
10 este foarte mic, putem s  c ut m secvenµial în acest ³ir ecare element din
vectorul a ³i s -l num r m în cazul în care îl g sim.

Pentru cerinµa 2 vom descompune ecare num r din vectorul a în factori primi (ecient!!!
folosiµi numerele prime memorate în vectorul prim). Dac  num rul de cifre necesare pentru
scrierea factorilor primi ³i a puterilor acestora este $ lungimea num rului curent din a, deducem
c  este un num r economic ³i îl contoriz m.

Pentru cerinµa 3 vom parcurge vectorul a ³i pentru ecare element ai din vector veric m
dac  poate  scris ca sum  de dou  numere prime. Pentru aceasta parcurg vectorul de numere
prime pân  când se termin  (sau, mai ecient, pân  când num rul prim curent p este mai mare
decât complementarul s u ai  p) sau pân  când g sesc un num r prim p pentru care ai  p
este deasemenea prim. Dac  un astfel de num r prim nu a fost g sit, contorizez pe ai.

Soluµie alternativ  (100 puncte)


prof. “andor Nicoleta, Colegiul Naµional Mihai Eminescu Satu Mare

Pentru ecare cerinµ  se vor prelucra numerele la citire.

Cerinµa 1:
Veric m dac  num rul citit este termen al ³irului lui Fibonacci. În caz armativ, veric m
dac  num rul citit este prim. Dac  este îndeplinit  ³i aceast  condiµie contoriz m num rul citit.

Cerinµa 2:
Calcul m num rul de cifre ale valorii citite. Descompunem num rul în factori primi (ecient)
³i calcul m num rul de cifre ale divizorilor primi ³i ale exponenµilor mai mari decât 1 ai acestora.
CAPITOLUL 15. ONI 2017 191

Dac  valoarea citit  are num rul de cifre % num rul de cifre necesare pentru scrierea factorilor
primi ³i a puterilor acestora, deducem c  este un num r economic ³i îl contoriz m.

Cerinµa 3:
A m numerele care pot  scrise ca sum  de dou  numere prime. Din num rul total de numere
citite vom sc dea num rul de numere care pot  scrise ca sum  de dou  numere prime. Veric m
doar numerele mai mari decât 3.

Orice num r par mai mare decât 3 poate  scris ca sum  de dou  numere prime, prin
urmare pentru orice num r par mai mare decât 3 decrement m contorul.

Pentru a g si numerele impare care veric  aceast  condiµie folosim proprietatea c  suma dintre
dou  numere este impar  doar dac  unul dintre cele dou  numere este par. Singurul num r prim
par este 2. Prin urmare este sucient s  veric m dac  diferenµa dintre num rul citit ³i 2 este
num r prim. în caz armativ decrement m contorul.

15.1.2 Cod surs 

Listing 15.1.1: prime_cp.cpp

1 //Carmen Popescu
2 #include <iostream>
3 #include <fstream>
4 #include <cmath>
5
6 using namespace std;
7
8 ifstream f("prime.in");
9 ofstream g("prime.out");
10
11 bool ciur[10000001];
12 int prim[665000],lg[665000];
13
14 int main()
15 {
16 int i,j,n,c,np,nf,f1,f2,f3;
17 long long a[51],mx;
18 int fib[26];
19 f>>c>>n;
20 for (i=0;i<n;i++)
21 {
22 f>>a[i];
23 if (a[i]>mx) mx=a[i];
24 }
25
26 if (c==2)
27 mx=sqrt(mx);
28 // nr prime cu ciur
29 ciur[0]=ciur[1]=1;
30 for (i=2;i*i<=mx;i++)
31 if (ciur[i]==0)
32 for (j=i*i;j<=mx;j=j+i)
33 ciur[j]=1;
34
35 np=0;
36 int p=9,k=1;
37 for (i=2;i<=mx;i++)
38 if (ciur[i]==0)
39 {
40 prim[np]=i;
41 while (i>p)
42 {
43 p=(p+1)*10-1;
44 k++;
45 }
46 lg[np++]=k;
47 }
48
49 // fibonacci prime
50 nf=0;
51 f1=0; f2=1; f3=1;
CAPITOLUL 15. ONI 2017 192

52 while (f3<=mx)
53 {
54 if (ciur[f3]==0)
55 fib[nf++]=f3;
56 f1=f2; f2=f3; f3=f1+f2;
57 }
58
59 if (c==1)
60 {
61 int k=0;
62 for (i=0;i<n;i++)
63 for (j=0;j<nf;j++)
64 if (a[i]==fib[j])
65 {
66 k++;
67 break;
68 }
69 g<<k<<"\n";
70 }
71 else
72 if (c==2)
73 {
74 int k=0;
75 for (i=0;i<n;i++)
76 {
77 long long y=a[i],w=a[i];
78 f1=0;
79 f2=0;
80 while (y>0) { f1++; y/=10; }
81
82 for(j=0; j<np && prim[j]*prim[j]<=a[i] && f2<f1; j++)
83 {
84 p=0;
85 while (a[i]%prim[j]==0)
86 {
87 p++;
88 a[i]/=prim[j];
89 }
90 if (p)
91 {
92 f2 += lg[j];
93 if (p>1)
94 {
95 y=p;
96 while (y>0)
97 {
98 f2++; y/=10;
99 }
100 }
101 }
102 }
103 if (a[i]>1)
104 {
105 y=a[i];
106 while (y>0)
107 {
108 f2++; y/=10;
109 }
110 }
111 if (f2<f1)
112 k++;
113 }
114 g<<k<<"\n";
115 }
116 else
117 {
118 int k=0;
119 for (i=0;i<n;i++)
120 {
121 if (a[i]%2==1)
122 {
123 if (ciur[a[i]-2]==0)
124 k++;
125 }
126 else
127 {
CAPITOLUL 15. ONI 2017 193

128 for (j=0;prim[j]<a[i];j++)


129 if (ciur[a[i]-prim[j]]==0)
130 {
131 k++;
132 break;
133 }
134 }
135 }
136 g<<n-k<<"\n";
137 }
138
139 return 0;
140 }

Listing 15.1.2: prime_em.cpp

1 //Emanuela Cerchez
2 #include <fstream>
3 #include <cmath>
4
5 #define VMAX 10000001
6 #define PMAX 1000000
7 #define NMAX 50
8
9 using namespace std;
10
11 ifstream fin("prime.in");
12 ofstream fout("prime.out");
13
14 bool ciur[VMAX];
15 int nrprim, nr, n;
16 int prim[PMAX];
17 int lgprim[PMAX];
18 long long int a[NMAX], vmax;
19 int fib[NMAX];
20 int nrfib;
21
22 int main()
23 {int cerinta, i, j, d, lg, lgx, f1, f2, f3, p, gasit;
24 long long int cx;
25
26 fin>>cerinta>>n;
27 for (i=0; i<n; i++)
28 {
29 fin>>a[i];
30 if (a[i]>vmax) vmax=a[i];
31 }
32
33 //ciur
34 if (cerinta==2) vmax=sqrt((double)vmax);
35 ciur[0]=ciur[1]=1;
36 for (d=2; d*d<=vmax; d++)
37 if (!ciur[d])
38 for (j=d*d; j<=vmax; j+=d)
39 ciur[j]=1;
40
41 //transfer intr-un vector numerele prime <=vmax
42 prim[0]=2; nrprim=1; lgprim[0]=1;
43 for (d=3; d<=vmax; d+=2)
44 if (!ciur[d])
45 {prim[nrprim]=d;
46 cx=d;
47 do
48 {
49 cx/=10;
50 lgprim[nrprim]++;
51 } while (cx);
52 nrprim++;
53 }
54 if (cerinta==1)
55 {
56 for (f1=f2=1; f1+f2<=vmax; )
57 {
58 f3=f1+f2; f1=f2; f2=f3;
59 if (!ciur[f3]) fib[nrfib++]=f3;
CAPITOLUL 15. ONI 2017 194

60 }
61 nr=0;
62 for (i=0; i<n; i++)
63 {
64 for (j=0; j<nrfib && a[i]!=fib[j]; j++);
65 if (j<nrfib) nr++;
66 }
67
68 fout<<nr<<’\n’;
69 fout.close();
70 return 0;
71 }
72
73 if (cerinta==2)
74 {
75 nr=0;
76 //descompunere in factori primi eficient
77 for (i=0; i<n; i++)
78 {
79 cx=a[i]; lgx=0; do {lgx++; cx/=10;} while (cx);
80 lg=0;
81 for (j=0; j<nrprim && prim[j]*prim[j]<=a[i] && lg<lgx; j++)
82 {
83 for (p=0; a[i]%prim[j]==0; p++,a[i]/=prim[j]);
84 if (p)
85 {
86 lg+=lgprim[j];
87 if (p>1)
88 {
89 cx=p;
90 do {lg++; cx/=10;} while(cx);
91 }
92 }
93 }
94 if (a[i]>1)
95 {cx=a[i]; do {lg++; cx/=10;} while (cx);}
96 if (lg<lgx)
97 nr++;
98 }
99
100 fout<<nr<<’\n’;
101 fout.close();
102 return 0;
103 }
104
105 //cerinta 3
106 nr=0;
107 for (i=0; i<n; i++)
108 {
109 for (gasit=j=0; j<nrprim && a[i]>prim[j]; j++)
110 if (!ciur[a[i]-prim[j]]) {gasit=1; break;}
111 if (!gasit) nr++;
112 }
113
114 fout<<nr<<’\n’;
115
116 fout.close();
117 return 0;
118 }

Listing 15.1.3: prime_fara_ciur_sn.cpp

1 //prof. Sandor Nicoleta


2 #include <fstream>
3 #include<iostream>
4
5 using namespace std;
6
7 ifstream fin("prime.in");
8 ofstream fout("prime.out");
9
10 bool prim(int n)
11 {
12 if (n<2) return 0;
13 if(n==2) return 1;
CAPITOLUL 15. ONI 2017 195

14 if(n%2==0) return 0;
15 for(int d=3; d*d<=n; d=d+2)
16 if(n%d==0)
17 return 0;
18 return 1;
19 }
20
21 bool fibo(int n)
22 {
23 int a,b,c;
24 a=b=c=1;
25 while(c<n)
26 {
27 c=a+b;
28 a=b;
29 b=c;
30 }
31 return c==n;
32 }
33
34 int nrcif(long long n)
35 {
36 int c=0;
37 while(n)
38 {
39 n/=10;
40 c++;
41 }
42 return c;
43 }
44
45 int descompun(long long x)
46 {
47 int c,s=0;
48 long long d=2;
49 while(x > 1)
50 {
51 if(x % d == 0)
52 {
53 s+=nrcif(d);
54 c=0;
55 while(x % d == 0)
56 x /= d,c++;
57 if(c>1) s+=nrcif(c);
58 }
59 d ++;
60 // daca x este numar prim ne oprim
61 if(x > 1 && d * d > x)
62 {
63 s+=nrcif(x);
64 x = 1;
65 }
66 }
67 return s;
68 }
69
70 int main()
71 {
72 int i,n,c,v[50],x=0, a;
73 long long a1,j;
74 fin>>c>>n;
75 if(c==1)
76 {
77 for(i=0; i<n; i++)
78 {
79 fin>>a;
80 if (fibo(a)&&prim(a))
81 x++;
82 }
83 fout<<x;
84 }
85 else if(c==2)
86 {
87 for(i=0; i<n; i++)
88 {
89 fin>>a1;
CAPITOLUL 15. ONI 2017 196

90 if (descompun(a1)<nrcif(a1))
91 {
92 x++;
93 cout<<a1<<"\n";
94 }
95 }
96 fout<<x;
97 }
98 else
99 {
100 x=n;
101 for(i=0; i<n; i++)
102 {
103 fin>>a;
104 if(n>3)
105 {
106 //orice numar par mai mare dcat 4 se poate scrie
107 // ca suma a doua numere prime
108 if(a%2==0) x--;
109 else if (prim(a-2))
110 {
111 x--;
112 }
113 }
114 }
115 fout<<x;
116 }
117 return 0;
118 }

15.1.3 *Rezolvare detaliat 

15.2 robot
Problema 2 - robot 100 de puncte
Vlad a inventat un nou joc. Jocul conµine N standuri a³ezate în linie dreapt . Fiecare stand
are o etichet  pe care este scris un num r natural. Eticheta este considerat  corect  dac  num rul
îndepline³te urm toarele dou  condiµii:
- conµine atât cifre pare, cât ³i cifre impare;
- începe cu cifrele impare a³ezate în ordine cresc toare, urmate de cifrele pare în ordine des-
cresc toare.
De exemplu, eticheta 137860 este corect , dar etichetele 23541, 135, 64 ³i 3146 nu sunt corecte.
Pentru jocul s u, Vlad a construit robotul reparator care ³tie s  verice numere ³i s  le repare,
dac  este necesar. Robotul reparator se deplaseaz  în linie dreapt  ³i se opre³te pe rând la ecare
dintre cele N standuri. La ecare stand, robotul veric  eticheta ³i dac  nu este corect , o repar .
Pentru a repara eticheta, robotul aranjeaz  cifrele impare în ordine cresc toare, apoi, în conti-
nuare, aranjeaz  cifrele pare în ordine descresc toare; dac  eticheta nu conµine nicio cifr  impar ,
cea mai mare cifr  par  o înlocuie³te cu 9; dac  eticheta nu conµine nicio cifr  par , cea mai mic 
cifr  impar  o înlocuie³te cu 0.
Deplasarea de la un stand la altul dureaz  t secunde, vericarea etichetei unui stand dureaz 
v secunde, iar repararea acesteia dureaz  r secunde. Cursa robotului se încheie dup  ce robotul a
vericat toate cele N standuri ³i a reparat etichetele incorecte.

Cerinµe
Scrieµi un program care cite³te num rul N de standuri, timpul (ora h, minutul m, secunda
s) când robotul ajunge la primul stand, timpii t, v ³i r cu semnicaµia din enunµ ³i etichetele
standurilor ³i care rezolv  urm toarele cerinµe:
1. calculeaz  ³i a³eaz  timpul (ora, minutul ³i secunda) când robotul a încheiat vericarea
tuturor celor N standuri ³i repararea etichetelor incorecte;
2. repar  (unde este necesar) etichetele standurilor ³i a³eaz  etichetele celor N standuri la
nal.
CAPITOLUL 15. ONI 2017 197

Date de intrare
Fi³ierul de intrare robot.in conµine pe prima linie un num r natural C , reprezentând cerinµa
care urmeaz  s  e rezolvat  (1 sau 2).
Pe linia a doua se a  numerele naturale N , h, m, s, iar pe linia a treia numerele naturale t,
v, r, cu semnicaµia din enunµ. Numerele aate pe aceea³i linie sunt separate prin câte un spaµiu.
Pe urm toarele N linii se a  etichetele standurilor, în ordinea a³ez rii acestora, câte o etichet 
pe o linie.

Date de ie³ire
Dac  C 1, ³ierul de ie³ire robot.out va conµine o singur  linie pe care vor  scrise 3 numere
naturale separate prin câte un spaµiu hf mf sf , reprezentând ora, minutul ³i respectiv secunda
la care robotul termin  repararea.

Dac  C 2, ³ierul de ie³ire robot.out va conµine N linii pe care vor  scrise etichetele
standurilor, în ordinea a³ez rii acestora, dup  ce robotul a încheiat vericarea ³i repararea, câte
o etichet  pe o linie.

Restricµii ³i preciz ri
a 2&N & 500
a Etichetele standurilor au cel puµin dou  ³i cel mult nou  cifre.
a Robotul începe ³i încheie repararea în aceea³i zi; 0 & h, hf $ 24; 0 & m, mf, s, sf $ 60
a Pentru rezolvarea corect  a cerinµei 1 se acord  40 de puncte; pentru rezolvarea corect  a
cerinµei 2 se acord  60 de puncte.

Exemple
robot.in robot.out Explicaµii
1 11 21 49 Cerinµa este 1. Exist  3 standuri.
3 11 20 50 Pentru simplitate not m cu h:m:s ora h, m minute ³i s secunde.
7 5 15 La primul stand robotul ajunge la ora 11:20:50. Primul stand
376572 are eticheta 376572, care este incorect , deci robotul o repar .
3564 Aici va petrece 5 secunde pentru veri-care ³i 15 secunde pentru
123 reparare, deci va pleca de aici la ora 11: 21:10.
La al doilea stand va ajunge la ora 11:21:17; eticheta sa 3564
este corect  deci robotul nu o va mo-dica; aici va petrece 5
secunde pentru vericare ³i pleac  la ora 11:21:22.
La al treilea stand va ajunge la ora 11:21:29. Al treilea stand
are eticheta incorect  123, robotul o repar , deci aici va petrece
5+15=20 secunde ³i ora la care încheie cursa este 11:21:49.
2 357762 Cerinµa este 2. Exist  3 standuri.
3 11 20 50 3564 Primul stand are eticheta 376572, care este incorect , robotul o
7 5 15 130 repar  ³i aceasta devine 357762.
376572 La al doilea stand eticheta 3564 este corect . deci robotul nu o
3564 va modica.
113 Al treilea stand are eticheta incorect  113, robotul o repar  ³i
devine 130.

Timp maxim de executare/test: 0.1 secunde


Memorie: total 2 MB din care pentru stiv  1 MB
Dimensiune maxim  a sursei: 15 KB

15.2.1 Indicaµii de rezolvare


prof. Adriana Simulescu, Liceul Teoretic GRIGORE MOISIL Timi³oara

Vom citi pe rând câte un num r.


Pentru ecare num r citit, pentru a verica corectitudinea sa, vom construi num rul corect
format din cifrele num rului citit astfel:
- a³ez m cifrele impare ce apar în num r în ordine cresc toare ³i contoriz m concomitent
num rul lor
CAPITOLUL 15. ONI 2017 198

- a³ez m în continuare cifrele pare ce apar în num r în ordine descresc toare ³i contoriz m


concomitent num rul lor
Num rul citit este corect dac  îndepline³te simultan condiµiile:
- num rul citit este egal cu num rul construit
- num rul este format atât din cifre pare cât ³i din cifre impare

Pentru rezolvarea cerinµei 1)


- contoriz m numerele corecte în variabila ncorecte
- la nal, calcul m timpul astfel:
s=s+(N-1)*(t+v)+(N-ncorecte)*r+v;
m=m+s/60;
s=s%60;
h=h+m/60;
m=m%60;
- scriem în ³ier timpul calculat

Pentru rezolvarea cerinµei 2)


Dup  construirea num rului prin a³ezarea cifrelor pare ³i impare, dac  acesta conµine:
a) doar cifre pare, înlocuie³te prima cifr  a num rului construit cu cifra 9
b) doar cifre impare, ³terge prima cifr  a num rului construit ³i adaug  0 la sfâr³it
Scriem în ³ier num rul calculat

15.2.2 Cod surs 

Listing 15.2.1: robot_adriana.cpp

1 //Adriana Simulescu
2 #include <fstream>
3 #include <iostream>
4 #include <cmath>
5
6 using namespace std;
7
8 int main()
9 { int N,i,cod,h,m,s,ok,cod1,cod2,ap[10],c,c1,j,T,t,v,r,
10 ncorecte=0,cif,ci,cp,pp,p2,pi;
11 ifstream in("robot.in");
12 ofstream out("robot.out");
13
14 in>>T;
15 in>>N>>h>>m>>s;
16 in>>t>>v>>r;
17
18 if(T==2)
19 for(i=1;i<=N;i++)
20 {
21 in>>cod;
22 cod2=0;
23 ci=0;cp=0;pp=1;pi=1;
24 for(cif=1;cif<=9;cif=cif+2)
25 {
26 cod1=cod;
27 while(cod1>0)
28 { if(cod1%10==cif)
29 {
30 cod2=cod2*10+cif;ci++; pi*=10;
31 }
32 cod1/=10;
33
34 }
35 }
36 for(cif=8;cif>=0;cif=cif-2)
37 {
38 cod1=cod;
39 while(cod1>0)
40 { if(cod1%10==cif)
41 {
42 cod2=cod2*10+cif;
43 cp++;
CAPITOLUL 15. ONI 2017 199

44 pp*=10;
45 }
46 cod1/=10;
47 }
48 }
49
50 if(cod==cod2&&ci*cp!=0)
51 out<<cod<<’\n’;
52 else
53 {
54 if(ci*cp!=0)
55 out<<cod2<<’\n’;
56 else
57 {
58 if(ci==0)
59 cod2=cod2%(pp/10)+9*(pp/10);
60 else
61 cod2=cod2%(pi/10)*10;
62 out<<cod2<<’\n’;
63 }
64 }
65 }
66 else
67 {
68 for(i=1;i<=N;i++)
69 {
70 in>>cod;
71 cod2=0;
72 ci=0;cp=0;pp=1;pi=1;
73
74 for(cif=1;cif<=9;cif=cif+2)
75 {
76 cod1=cod;
77 while(cod1>0)
78 { if(cod1%10==cif)
79 {
80 cod2=cod2*10+cif;ci++;
81 pi*=10;
82 }
83 cod1/=10;
84 }
85 }
86
87 for(cif=8;cif>=0;cif=cif-2)
88 {
89 cod1=cod;
90 while(cod1>0)
91 {
92 if(cod1%10==cif)
93 {
94 cod2=cod2*10+cif;cp++;
95 pp*=10;
96 }
97 cod1/=10;
98 }
99 }
100
101 if(cod==cod2&&ci*cp!=0)
102 {
103 ncorecte++;
104 }
105 }
106
107 s=s+(N-1)*(t+v)+(N-ncorecte)*r+v;
108 m=m+s/60;
109 s=s%60;
110 h=h+m/60;
111 m=m%60;
112 out<<h<<" "<<m<<" "<<s<<"\n";
113 }
114
115 in.close();
116 out.close();
117 return 0;
118 }
CAPITOLUL 15. ONI 2017 200

Listing 15.2.2: robot_cp.cpp

1 //Carmen Popescu
2 #include <fstream>
3
4 using namespace std;
5
6 ifstream f("robot.in");
7 ofstream g("robot.out");
8
9 long long verif(long long x)
10 {
11 int cif[10]={0};
12 long long y=0;
13 int np=0,ni=0,i,j;
14
15 while (x>0)
16 {
17 cif[x%10]++;
18 if (x%2==0) np++;
19 else
20 ni++;
21 x=x/10;
22 }
23
24 if (np==0)
25 {
26 for (i=1;i<=9;i+=2)
27 if (cif[i]>0)
28 {
29 cif[i]--;
30 cif[0]=1;
31 break;
32 }
33 }
34 else
35 if (ni==0)
36 {
37 for (i=8;i>=0;i-=2)
38 if (cif[i]>0)
39 {
40 cif[i]--;
41 cif[9]=1;
42 break;
43 }
44 }
45
46 y=0;
47 for (i=1;i<=9;i+=2)
48 for (j=0;j<cif[i];j++)
49 y=y*10+i;
50
51 for (i=8;i>=0;i-=2)
52 for (j=0;j<cif[i];j++)
53 y=y*10+i;
54
55 return y;
56 }
57
58 int main()
59 {
60 int c,n,h,m,s,t,v,r,i;
61 long long u,x,y;
62
63 f>>c;
64 f>>n>>h>>m>>s>>t>>v>>r;
65
66 for (i=0;i<n;i++)
67 {
68 f>>x;
69 y=verif(x);
70 if (x!=y)
71 {
72 s=s+r;
73 if (s>60)
74 {
CAPITOLUL 15. ONI 2017 201

75 s-=60; m++;
76 if (m>60)
77 {
78 m-=60; h++;
79 }
80 }
81 }
82 if (c==2)
83 g<<y<<’\n’;
84 }
85
86 if (c==1)
87 {
88 s=s+t*(n-1)+v*n;
89 m=m+s/60;
90 s=s%60;
91 h=h+m/60;
92 m=m%60;
93 g<<h<<" "<<m<<" "<<s<<"\n";
94 }
95
96 return 0;
97 }

Listing 15.2.3: robot_ema.cpp

1 //Emanuela Cerchez
2 #include <fstream>
3
4 using namespace std;
5
6 ifstream fin("robot.in");
7 ofstream fout("robot.out");
8
9 int cerinta, n, h,m,s, v, r,t, nr;
10
11 int main()
12 {int i, rez, cx, x, cate, maxpar, minimpar, p10, corect, c, uc, j, timp, hf, mf, sf;
13 fin>>cerinta;
14 fin>>n>>h>>m>>s>>t>>v>>r;
15
16 if (cerinta ==1)
17 {
18 for (i=1; i<=n; i++)
19 {
20 fin>>x;
21 corect=1;
22 cx=x;
23 if (x%2==1) corect=0;
24 else
25 { c=x%10; x/=10;
26 while (x>0 && x%2==0)
27 {
28 uc=x%10;
29 if (uc<c) corect=0;
30 c=uc;
31 x=x/10;
32 }
33 if (x==0) corect=0;
34 else
35 {c=x%10; x/=10;
36 while (x>0)
37 {
38 uc=x%10;
39 if (uc%2==0) corect=0;
40 if (uc>c) corect=0;
41 c=uc;
42 x/=10;
43 }
44 }
45 }
46 if (corect) nr++;
47 }
48 timp=h*3600+m*60+s+(n-nr)*r+t*(n-1)+v*n;
49 hf=timp/3600; timp=timp%3600; mf=timp/60; sf=timp%60;
CAPITOLUL 15. ONI 2017 202

50 fout<<hf<<’ ’<<mf<<’ ’<<sf<<’\n’;


51 }
52 else
53 {
54 for (i=1; i<=n; i++)
55 {
56 fin>>x;
57 corect=1; cx=x;
58 if (x%2==1) corect=0;
59 else
60 { c=x%10; x/=10;
61 while (x>0 && x%2==0)
62 {uc=x%10;
63 if (uc<c) corect=0;
64 c=uc; x=x/10;
65 }
66 if (x==0) corect=0;
67 else
68 {c=x%10; x/=10;
69 while (x>0)
70 { uc=x%10;
71 if (uc%2==0) corect=0;
72 if (uc>c) corect=0;
73 c=uc; x/=10;
74 }
75 }
76 }
77
78 if (corect) {nr++; rez=cx;}
79 else
80 {
81 rez=0; minimpar=10; maxpar=-1; p10=1;
82
83 for (c=1; c<10; c+=2)
84 {
85 x=cx; cate=0;
86 while (x)
87 {if (x%10==c) cate++; x/=10; }
88 for (j=0; j<cate; j++)
89 {rez=rez*10+c; p10*=10;}
90 if (cate && minimpar==10) minimpar=c;
91 }
92
93 for (c=8; c>=0; c-=2)
94 {
95 x=cx; cate=0;
96 while (x)
97 {if (x%10==c) cate++; x/=10;}
98 for (j=0; j<cate; j++)
99 {rez=rez*10+c; p10*=10;}
100 if (cate && maxpar==-1) maxpar=c;
101 }
102
103 p10/=10;
104 if (maxpar==-1) rez=(rez%p10)*10;
105 if (minimpar==10) rez=9*p10+rez%p10;
106 }
107
108 fout<<rez<<’\n’;
109 }
110 }
111 fout.close();
112 return 0;
113 }

Listing 15.2.4: robot-JT.cpp

1 //Jakab Tunde
2 #include <iostream>
3 #include <fstream>
4
5 using namespace std;
6
7 ifstream f("robot.in");
8 ofstream g("robot.out");
CAPITOLUL 15. ONI 2017 203

9
10 int main()
11 {int n,p,h,m,s,t,v,r,ok,a,b,c,i,d;
12 unsigned long long T=0;
13
14 f>>p;
15
16 if(p==1)
17 {
18 f>>n>>h>>m>>s;
19 f>>t>>v>>r;
20 b=0;
21 for(i=1;i<=n;i++)
22 {
23 f>>a;
24 T=T+t+v;
25 d=a;
26 ok=1;
27 if(a%2!=0)ok=0;
28 else
29 {
30 c=a%10;
31 a=a/10;
32 while(c<=a%10 and a%2!=1)
33 {
34 c=a%10;
35 a=a/10;
36 }
37 c=a%10;
38 a=a/10;
39 if(c%2==0)ok=0;
40 else
41 {
42 while(c>=a%10 and a%2==1)
43 {
44 c=a%10;
45 a=a/10;
46 }
47
48 if(a!=0) ok=0;
49 }
50 }
51
52 if(!ok)
53 {
54 T=T+r;
55 int x=0,y=0,z1=1,z2=1,j,v;
56
57 for(j=1;j<=9;j=j+2)
58 {
59 a=d;
60 while(a!=0)
61 {
62 if(a%10==j){x=x*10+j;z1=z1*10;}
63 a=a/10;
64 }
65 }
66
67 for(j=8;j>=0;j=j-2)
68 {
69 a=d;
70 while(a!=0)
71 {
72 if(a%10==j){y=y*10+j;z2=z2*10;}
73 a=a/10;
74 }
75 }
76
77 if(x==0)
78 {
79 z2=z2/10;
80 v=9*z2+y%z2;
81 }
82 else
83 if(y==0)
84 if(z2>1)v=x*z2;
CAPITOLUL 15. ONI 2017 204

85 else
86 {
87 z1=z1/10;
88 v=(x%z1)*10;
89 }
90 else v=x*z2+y;
91 }
92 }
93
94 T=T-t;
95 h=h+T/3600;
96 T=T%3600;
97 m=m+T/60;
98 T=T%60;
99 s=s+T;
100
101 if(s>=60)
102 {
103 m=m+s/60;
104 s=s%60;
105 }
106
107 if(m>=60)
108 {
109 h=h+m/60;
110 m=m%60;
111 }
112
113 g<<h<<’ ’<<m<<’ ’<<s;
114 }
115
116 if(p==2)
117 {
118 f>>n>>h>>m>>s;
119 f>>t>>v>>r;
120 b=0;
121
122 for(i=1;i<=n;i++)
123 {
124 f>>a;
125 T=T+t+v;
126 d=a;
127 ok=1;
128
129 if(a%2!=0)ok=0;
130 else
131 {
132 c=a%10;
133 a=a/10;
134 while(c<=a%10 and a%2!=1)
135 {
136 c=a%10;
137 a=a/10;
138 }
139
140 c=a%10;
141 a=a/10;
142 if(c%2==0)ok=0;
143 else
144 {
145 while(c>=a%10 and a%2==1)
146 {
147 c=a%10;
148 a=a/10;
149 }
150
151 if(a!=0)ok=0;
152 }
153 }
154
155 if(!ok)
156 {
157 T=T+r;
158 int x=0,y=0,z1=1,z2=1,j,v;
159
160 for(j=1;j<=9;j=j+2)
CAPITOLUL 15. ONI 2017 205

161 {
162 a=d;
163 while(a!=0)
164 {
165 if(a%10==j){x=x*10+j;z1=z1*10;}
166 a=a/10;
167 }
168 }
169
170 for(j=8;j>=0;j=j-2)
171 {
172 a=d;
173 while(a!=0)
174 {
175 if(a%10==j){y=y*10+j;z2=z2*10;}
176 a=a/10;
177 }
178 }
179
180 if(x==0)
181 {
182 z2=z2/10;
183 v=9*z2+y%z2;
184 }
185 else
186 if(y==0)
187 if(z2>1)v=x*z2;
188 else
189 {
190 z1=z1/10;
191 v=(x%z1)*10;
192 }
193 else v=x*z2+y;
194
195 g<<v<<endl;
196 }
197 else g<<d<<endl;
198 }
199 }
200 }

15.2.3 *Rezolvare detaliat 

15.3 roua
Problema 3 - roua 100 de puncte
Un copil dore³te s  vopseasc  ou le de Pa³te, având la dispoziµie vopsele de culoare ro³ie,
galben , verde ³i albastr . Fiecare culoare va  reprezentat  printr-un singur caracter astfel: 'r'
pentru culoarea ro³ie, 'g' pentru galben, 'v' pentru verde, 'a' pentru albastru.
Pentru a vopsi ou le, le a³az  în rând, unul dup  altul. Astfel, o colorare va  o succesiune de
N caractere din mulµimea {'r','g','v','a'}, reprezentând, în ordinea a³ez rii, culorile celorN ou .
Numim roua o secvenµ  de R caractere cu proprietatea c  dintre acestea exact R  1 caractere
reprezint  culoarea ro³ie, iar un caracter reprezint  una dintre celelalte 3 culori. De exemplu
secvenµele roua de lungime 3 sunt "grr", "rgr", "rrg", "vrr", "rvr", "rrv","arr", "rar", "rra".
Copilul consider  c  o colorare este R-frumoas , dac  oricare R caractere consecutive din
colorare formeaz  o secvenµ  roua. De exemplu, pentru N 11 ou , ³irul "arrrvrrrarr" reprezint 
o colorare 4-frumoas .

Cerinµe
Cunoscând N , num rul de ou  vopsite, ³i num rul natural R, scrieµi un program care determin 
³i a³eaz :
1. num rul de secvenµe roua de lungime R existente în colorarea celor N ou ;
2. num rul total al color rilor R-frumoase pentru cele N ou .

Date de intrare
CAPITOLUL 15. ONI 2017 206

Fi³ierul de intrare roua.in conµine pe prima linie un num r natural C reprezentând cerinµa
din problem  care trebuie rezolvat  (1 sau 2). A doua linie din ³ier conµine numerele naturale N
R, separate prin spaµiu, reprezentând num rul de ou  ³i lungimea unei
³i secvenµe roua . Dac 
C 1, ³ierul va conµine ³i o a treia linie pe care se a  colorarea celor N ou .

Date de ie³ire
Fi³ierul de ie³ire roua.out va conµine o singur  linie pe care va  scris un num r natural,
reprezentând r spunsul la cerinµa specicat  în ³ierul de intrare.

Restricµii ³i preciz ri
a 3 & N & 10000
a 2&R$N
a Pentru rezolvarea corect  a cerinµei 1 se acord  40 puncte, pentru rezolvarea corect  a cerinµei
2 se acord  60 de puncte.
a Pentru 60% dintre testele pentru cerinµa 2, 3 & N & 70
a Pentru 40% dintre testele pentru cerinµa 2, N % 70
a Rezultatul la cerinµa 2 poate avea cel mult 2400 de cifre.

Exemple
roua.in roua.out Explicaµii
1 4 Cerinµa este 1. Exist  N=7 ou .
7 3 vrrrgrr Secvenµele roua de lungime 3 existente în colorare sunt "vrr",
"rrg", "rgr", "grr".
2 15 Cerinµa este 2. Exist  4 ou .
4 3 Color rile 3-frumoase ale celor 4 ou  sunt "grrg", "grrv", "grra",
"vrrg", "vrrv", "vrra", "arrg", "arrv", "arra", "rgrr", "rvrr",
"rarr", "rrgr", "rrvr", "rrar".

Timp maxim de executare/test: 0.25 secunde


Memorie: total 2 MB din care pentru stiv  1 MB
Dimensiune maxim  a sursei: 15 KB

15.3.1 Indicaµii de rezolvare


Autor prof. Carda³ Cerasela-Daniela, Colegiul National A.T.Laurian Boto³ani

Variabilele N ³i R memoreaz  num rul de caractere, respectiv lungimea unei secvenµe roua.

1. În variabilele p1 ³i p2 memor m penultima, respectiv ultima poziµie a unui caracter diferit


de 'r'.

Pentru ecare caracter c citit din ³ier avem cazurile:


a) c='r', increment m nr de secvenµe roua dac  p1 < poziµia_curent  - R ³i p2 > pozi-
µia_curent  - R
b) c j 'r', increment m nr de secvenµe roua dac  poziµia_curent  - p2 ' R, actualiz m valorile
lui p1 ³i p2.

2. O secvenµ  roua este format  din R caractere ³i este de forma "rrr..rX r...r", unde X este
oricare dintre caracterele 'a','g' sau 'v' ³i ocup  orice poziµie de la 1 la R, în cadrul unei secvenµe.

Calcul m a N %R, b N ©R.


Pentru deducerea formulei, analiz m mai întai cazul a 0.
a) Dac  a 0, exist  în ³ir b grupe de c te R valori consecutive.

Pentru o colorare R-frumoas , caracterul X poate avea o valoare din 3 valori posibile ³i ocup 
aceea³i poziµie în cadrul ec rei grupe.

Poziµia caracterului X este o valoare de la 1 la R => putem forma


b
3 color ri R-frumoase în care X ocup  poziµia 1,
b
3 color ri R-frumoase în care X ocup  poziµia 2,
...,
b
3 color ri R-frumoase în care X ocup  poziµia R .
CAPITOLUL 15. ONI 2017 207

b
In total avem R˜ 3  color ri posibile.

b) Dac  a j 0, exist  în ³ir b grupe de c te R valori ³i o grup  cu ultimele a valori din ³ir .

Pentru o colorare R-frumoas , caracterul X va ocupa


b1
- e o poziµie între 1 ³i a în b  1 grupe, caz în care se formeaz  a ˜ 3 color ri
b
- e o poziµie între a  1 ³i R în primele b grupe => se formeaz  R  a ˜ 3 color ri.
In total, num rul de color ri va 

b1 b b b b b
a˜3  R  a ˜ 3 = a˜3 ˜ 3  R  a ˜ 3 = 3 ˜ a ˜ 3  R  a = 3 ˜ 2 ˜ a  R.
Pentru N & 70 num rul de color ri se poate calcula direct în long long, iar pentru N % 70 se
va realiza înmulµirea dintre un num r mare ³i un num r de o cifr .

15.3.2 Cod surs 

Listing 15.3.1: roua_cardas.cpp

1 //Cardas Daniela
2 #include <fstream>
3
4 using namespace std;
5 ifstream in("roua.in");
6 ofstream out("roua.out");
7 int N,P,R,i,nroua,p1,p2,a,b,v[2500],x,p,j,ct;
8 char c;
9
10 int main()
11 {
12 in>>P;
13 if(P==1)
14 {
15 in>>N>>R>>c;i=1;
16 while(c==’r’&&i<N)in>>c,i++;
17 if(c!=’r’){p2=i;if(p2>=R)nroua=1;}
18 if(c==’r’&&i==N){out<<0<<’\n’;return 0;}
19
20 for(i=p2+1; i<=N; i++)
21 {
22 in>>c;
23 if(c!=’r’)
24 {
25 if(i-p2+1>R){nroua++;}
26 p1=p2;p2=i;
27 }
28 else
29 if(p1<=i-R&&i>=R&&p2>i-R){nroua++;}
30
31 }
32
33 out<<nroua<<’\n’;
34 }
35 else
36 {
37 ///P=2
38 in>>N>>R;
39 a=N%R;b=N/R;
40
41 if(N<=70)
42 {
43 long long p=1;
44 for(i=1;i<=b;i++,p*=3);
45 p=p*(2*a+R);
46 out<<p<<’\n’;
47 return 0;
48 }
49
50 ///initializam vectorul de cifre cu numarul 2a+R
51 x=2*a+R;i=0;
52 while(x)v[++i]=x%10,x/=10;
53 v[0]=i;
54
CAPITOLUL 15. ONI 2017 208

55 ///inmultim vectorul de cifre v cu 3 de b ori


56 for(i=1;i<=b;i++)
57 {
58 for(ct=0,j=1;j<=v[0];j++)
59 {
60 v[j]*=3;
61 x=v[j]+ct;v[j]=x%10;ct=x/10;
62 }
63 if(ct)
64 {
65 v[0]++;v[v[0]]=ct;
66 }
67 }
68
69 for(i=v[0];i>=1;i--)
70 out<<v[i];
71 out<<’\n’;
72 }
73 }

Listing 15.3.2: roua_cp.cpp

1 //Carmen Popescu
2 #include <fstream>
3 #include <iostream>
4
5 using namespace std;
6
7 ifstream f("roua.in");
8 ofstream g("roua.out");
9
10 int main()
11 {
12 int c,n,r,x,ct,i,j;
13 char ch[10001];
14 long long v,p;
15
16 f>>c;
17 f>>n>>r;
18
19 if (c==1)
20 {
21 x=0;
22 ct=0;
23 for (i=0;i<r;i++)
24 {
25 f>>ch[i];
26 if (ch[i]==’r’) x++;
27 }
28 if (x==r-1) ct++;
29 for (i=r;i<n;i++)
30 {
31 f>>ch[i];
32 if (ch[i-r]==’r’) x--;
33 if (ch[i]==’r’) x++;
34 if (x==r-1) ct++;
35 }
36 g<<ct<<"\n";
37 }
38 else
39 {
40 // 3^(n/r)*(2*(n%r)+r)
41 int c[10001],nc=0;
42 x=n/r;
43
44 // 3^(n/r)
45 nc=1; c[0]=1;
46 for (i=1;i<=n/r;i++)
47 {
48 c[0]=3*c[0];
49 p=c[0]/10;
50 c[0]=c[0]%10;
51 for (j=1;j<nc;j++)
52 {
53 c[j]=3*c[j]+p;
CAPITOLUL 15. ONI 2017 209

54 p=c[j]/10;
55 c[j]=c[j]%10;
56 }
57 while (p>0)
58 {
59 c[nc++]=p%10;
60 p=p/10;
61 }
62 }
63
64 v=2*(n%r)+r;
65 if (v>1)
66 {
67 p=0;
68 for (i=0;i<nc;i++)
69 {
70 c[i]=v*c[i]+p;
71 p=c[i]/10;
72 c[i]=c[i]%10;
73 }
74 while (p>0)
75 {
76 c[nc]=p%10; nc++;
77 p=p/10;
78 }
79 }
80
81 for (i=nc-1;i>=0;i--)
82 g<<c[i];
83 g<<"\n";
84 }
85 return 0;
86 }

Listing 15.3.3: roua_jt.cpp

1 //Jakab Tunde
2 #include <fstream>
3 using namespace std;
4
5 ifstream f("roua.in");
6 ofstream g("roua.out");
7 int t[10001];
8
9 int main()
10 {int p,r,n;
11 f>>p>>n>>r;
12
13 if(p==1)
14 {
15 int a=1,b=0,h;
16 char c;
17 f>>c;
18 while(c==’r’ and a<=n)
19 {
20 f>>c;
21 a++;
22 }
23
24 if(c==’r’)g<<0;
25 else
26 {
27 if(a>=r)b++;
28 h=a-1;
29
30 for(int i=a+1;i<=n;i++)
31 {
32 f>>c;
33 if(c==’r’)
34 {
35 if(i-a<r and i-a+h+1>=r)b++;
36 }
37 else
38 {
39 h=i-a-1;
CAPITOLUL 15. ONI 2017 210

40 a=i;
41 if (h>=r-1)b++;
42 }
43 }
44 }
45 g<<b;
46 }
47 else
48 {
49 int a,j,k,b=0,c;
50 a=2*(n%r)+r;
51 k=0;
52
53 while(a>0)
54 {
55 t[++k]=a%10;
56 a=a/10;
57 }
58
59 b=0;
60 for(int i=1;i<=n/r;i++)
61 {
62 for(j=1;j<=k;j++)
63 {
64 c=t[j]*3+b;
65 t[j]=c%10;
66 b=c/10;
67 }
68 if(c>9)t[++k]=c/10;
69 b=0;
70 }
71
72 for(int i=k;i>=1;i--)
73 g<<t[i];
74 }
75
76 f.close();
77 g.close();
78 return 0;
79 }

15.3.3 *Rezolvare detaliat 


Capitolul 16

ONI 2016

16.1 Norocos
Problema 1 - Norocos 100 de puncte
Un num r natural nenul m se nume³te norocos dac  p tratul lui se poate scrie ca sum  de
m numere naturale consecutive. Un num r natural m se nume³te k -norocos, dac  este egal cu
produsul a exact k numere prime distincte. Observaµi c  între cele dou  propriet µi denite nu
exist  nicio leg tur .

Cerinµe
Dându-se k ³i N numere naturale, scrieµi un program care s  determine:
a) Cel mai mic ³i cel mai mare num r norocos dintre cele N numere citite
b) Câte numere k -norocoase sunt în ³irul de N numere citite

Date de intrare
Fi³ierul de intrare norocos.in conµine pe prima linie un num r natural C . Pentru toate testele
de intrare, num rul C are una din valorile 1 sau 2. Pe linia a doua a ³ierului se g sesc numerele
naturale N ³i k, cu semnicaµia din enunµ, iar pe a treia linie se g sesc N numere naturale,
separate prin câte un spaµiu.

Date de ie³ire
Fi³ierul de ie³ire este norocos.out.
Dac  C 1, se va rezolva numai punctul a). În acest caz, în ³ierul de ie³ire se vor scrie,
separate printr-un spaµiu, în aceast  ordine, cel mai mic ³i cel mai mare num r norocos dintre
cele N numere citite. Dac  nu exist  niciun num r norocos se va a³a valoarea 0. Dac  exist  un
singur num r norocos, acesta se va a³a de dou  ori.
Dac  C 2, se va rezolva numai punctul b). În acest caz, în ³ierul de ie³ire se va scrie un
singur num r reprezentând num rul de numere k -norocoase citite.

Restricµii ³i preciz ri
a 1 & N & 1000
a 2 & k & 30
a 1 & numerele citite de pe a treia linie a ³ierului & 2000000000
a Pentru rezolvarea corect  a primei cerinµe se acord  40 de puncte, pentru rezolvarea corect 
a celei de-a doua cerinµe se acord  60 de puncte.

Exemple

211
CAPITOLUL 16. ONI 2016 212

norocos.in norocos.out Explicaµii


1 5 165 Atenµie, C 1, deci se va rezolva doar prima
9 3 cerinµ .
165 12 33 30 5 18 105 15 4 Cel mai mic num r norocos este 5
2
5 =25=3+4+5+6+7
Cel mai mare num r norocos este 165
2
165 =27225=83+84+85+...+246+247 Ob-
servaµi faptul c , de³i se cite³te valoarea lui k,
aceasta nu este folosit  în rezolvarea cerinµei 1.
2 3 Atenµie, C 2, deci se va rezolva doar a doua
5 3 cerinµ .
165 31 165 105 44 Cele trei numere k -norocoase sunt 165, 165, 105

Timp maxim de executare/test: 0.5 secunde


Memorie: total 16 MB
Dimensiune maxim  a sursei: 15 KB

16.1.1 Indicaµii de rezolvare

Ana-Maria Ari³anu ³i Cristian Frâncu

a)
m este norocos m 2
a  a  1  a  2  ...  a  m  1 m 2
ma  m  1m©2 
2m
2
2ma  m  1m  2m 2a  m  1  m 2a  1 m  num r impar, a m  1©2
Prin urmare problema se reduce la a determina cel mai mare ³i cel mai mic num r impar
dintr-un ³ir de n numere.

b)
Pentru rezolvarea acestei cerinµe trebuie s  descompunem ecare num r x în factori primi.
Trebuie s  avem grij  de urm toarele aspecte:
- S  ne oprim din algoritmul de descompunere imediat ce detect m c  num rul nu poate 
k -norocos, de exemplu dac  am g sit un factor prim la putere mai mare decât unu, sau dac  am
descoperit mai mult de k factori primi.
- Optimizarea descompunerii în factori primi a num rului x prin împ rµire doar la divizorii d
cu proprietatea d ˜ d & x. Dac  am ajuns cu bine la nalul descompunerii ³i dac  x este mai mare
decât 1 înseamn  c  el este un num r prim la puterea 1, deci vom incrementa num rul de divizori
g siµi.

16.1.2 Cod surs 

Listing 16.1.1: norocos.cpp

1 #include <fstream>
2 #include <cmath>
3
4 using namespace std;
5
6 int t, n, k, a, sol, d, e, nr, i, x, ok, r, amax = 0, amin = 2000000000;
7
8 int main ()
9 {
10 ifstream fin ("norocos.in");
11 ofstream fout("norocos.out");
12
13 fin>>t>>n>>k;
14 for (i=1;i<=n;i++)
15 {
16 fin>>x;
17
18 if (t == 1 && x%2 == 1)
19 {
20 a++;
21 if (x < amin) { amin = x; }
CAPITOLUL 16. ONI 2016 213

22 if (x > amax) { amax = x; }


23 }
24
25 if (x == 1) continue;
26
27 if (t == 2)
28 {
29 ok = 1;
30 r = (int)sqrt(x);
31 d = 2;
32 nr = 0;
33
34 while (x != 1 && d <= r)
35 {
36 if (x%d == 0)
37 {
38 e = 0;
39 while (x%d == 0)
40 {
41 x /= d;
42 e++;
43 }
44
45 if (e != 1)
46 {
47 ok = 0;
48 break;
49 }
50
51 nr++;
52 if (nr > k)
53 {
54 ok = 0;
55 break;
56 }
57 }
58
59 d++;
60 }
61
62 if (x!=1) nr++;
63 if (nr != k) ok = 0;
64 if (ok) sol++;
65 }
66 }
67
68 if (t == 1)
69 {
70 if (a == 0) { fout<<a<<"\n"; }
71 else { fout<<amin<<" "<<amax<<"\n"; }
72 }
73 else fout<<sol<<"\n";
74
75 return 0;
76 }

16.1.3 *Rezolvare detaliat 

16.2 Oglinda
Problema 2 - Oglinda 100 de puncte
Pentru un num r natural N se consider  ³irul a 1, 2, 3..., N , deci ai i pentru orice i,
1 & i & N.
Asupra acestui ³ir se pot aplica operaµii de dou  tipuri:
a) la operaµia de tipul 1 se specic  dou  valori i ³i j, cu 1 &i&j& N. Efectul acestei
operaµii asupra ³irului este de oglindire a secvenµei din ³ir care începe cu elementul de pe poziµia
i ³i se termin  cu cel de pe poziµia j. De exemplu, dac  în ³irul a 1, 2, 3, 4, 5, 6, 7 se aplic 
CAPITOLUL 16. ONI 2016 214

operaµia 3 6, atunci ³irul devine a 1, 2, 6, 5, 4, 3, 7. Iar în ³irul a 1, 4, 3, 2, 5, 6, 7, dac  se


aplic  operaµia 4 6, atunci a1, 4, 3, 6, 5, 2, 7.
b) Operaµia de tipul 2 conµine un indice i, 1 & i & N , ³i cere s  a³ m valoarea elementului
care se a  în acel moment pe poziµia i în ³ir.
Se consider  M astfel de operaµii într-o ordine dat .

Cerinµe
Scrieµi un program care s  determine ³i s  a³eze rezultatul pentru ecare operaµie de tipul 2.

Date de intrare
Fi³ierul de intrare oglinda.in conµine pe prima linie dou  numere naturale N ³i M, separate
printr-un spaµiu. Pe ecare dintre urm toarele M linii este specicat  câte o operaµie de tipul 1
sau 2. O linie poate s  conµin  dou  sau trei numere, astfel: 1ij (indicând o operaµie de tipul
1) respectiv 2i (indicând o operaµie de tip 2). Valorile de pe aceea³i linie sunt separate prin câte
un spaµiu.

Date de ie³ire
Fi³ierul de ie³ire oglinda.out conµine un num r de linii egal cu num rul de operaµii de tipul 2
care sunt denite în ³ierul de intrare. Pe ecare linie este a³at câte un num r natural reprezin-
tând rezultatul pentru o operaµie de tip 2 prezent  în ³ierul de intrare, în ordinea în care acestea
sunt denite.

Restricµii ³i preciz ri
a 1 & N & 1000000
a 1 & M & 2000
a Pentru teste în valoare de 40 de puncte, vom avea 1 & N & 2000.
a Se garanteaz  c  1&i&j & N la operaµiile de tipul 1 ³i c  1 & i & N la operaµiile de tip 2.
a Se garanteaz  c  exist  cel puµin o operaµie de tipul 2.

Exemple
oglinda.in oglinda.out Explicaµii
10 4 3 “irul iniµial este: 1 2 3 4 5 6 7 8 9 10
2 3 6 Rezultatul operaµiei 2 3 are ca efect a³area elementului de pe
1 2 7 1 poziµia 3 (care este chiar 3).
2 3 Rezultatul operaµiei 1 2 7 are ca efect transformarea ³irului în:
2 1 1 7 6 5 4 3 2 8 9 10.
Rezultatul operaµiei 2 3 are ca efect a³area elementului de pe
poziµia 3 (care acum este 6).
Rezultatul operaµiei 2 1 are ca efect a³area elementului de pe
poziµia 1 (care acum are valoarea 1).

Timp maxim de executare/test: 0.3 secunde


Memorie: total 16 MB
Dimensiune maxim  a sursei: 15 KB

16.2.1 Indicaµii de rezolvare

prof. Marius Nicoli, C.N. Fraµii Buze³ti, Craiova

O prim  abordare a problemei se face prin simularea operaµiilor date pe un vector cu N


componente. Aceast  soluµie nu se încadreaz  în timp pe toate testele.
Pentru punctaj maxim se poate proceda astfel: se reµin operaµiile de tip 1 în doi vectori unul
pentru capetele stânga ale intervalelor de indici date ³i altul pentru capetele din dreapta.
La întâlnirea unei operaµii de tip 2 se determin  valoarea iniµial  de pe poziµia a, actualizând
pe a current prin aplicarea în ordine invers  a operaµiilor de tip 1 întâlnite pân  atunci. Informaµii
despre aceste operaµii le g sim în cei doi vectori.
La o operaµie de tip 1 s, d (memorat  în vector în momentul apariµiei sale), aceasta afecteaz 
pe a doar dac  a este cuprins între s ³i d (inclusiv). Timpul de executare este de ordinul m ˜ m
(m este num rul de operaµii).
CAPITOLUL 16. ONI 2016 215

16.2.2 Cod surs 

Listing 16.2.1: oglinda.cpp

1 #include <fstream>
2 #define DIMM 2010
3
4 using namespace std;
5
6 int S[DIMM], D[DIMM];
7 int n, m, i, j, a, b, t, k, x;
8
9 int main ()
10 {
11 ifstream fin ("oglinda.in");
12 ofstream fout("oglinda.out");
13
14 fin>>n>>m;
15 for (i=1;i<=m;i++)
16 {
17 fin>>t;
18 if (t == 1)
19 {
20 k++;
21 fin>>S[k]>>D[k];
22 }
23 else
24 {
25 fin>>a;
26 for (j=k; j>=1; j--)
27 {
28 if (S[j] <= a && a <= D[j])
29 {
30 x = a - S[j];
31 a = D[j] - x;
32 }
33 }
34
35 fout<<a<<"\n";
36 }
37 }
38 return 0;
39 }

16.2.3 *Rezolvare detaliat 

16.3 Perechi
Problema 3 - Perechi 100 de puncte
Fie un ³ir a1 , a2 , ..., an de numere naturale, unde n este impar. Avem la dispoziµie o singur 
operaµie admis  ³i anume: putem aduna la dou  poziµii diferite din ³ir o aceea³i valoare natural 
nenul .

Cerinµe
1. S  se verice dac  ³irul poate s  aib  toate elementele egale dup  aplicarea unei singure
operaµii.
2. Folosind de mai multe ori operaµia admis , s  se obµin  ³irul cu toate elementele egale, dar
valoarea egal  obµinut  s  nu dep ³easc  dublul valorii maxime din ³irul iniµial.

Date de intrare
Fi³ierul perechi.in conµine pe prima linie un num r natural C , pe a doua linie num rul n, iar
pe linia a treia, separate prin câte un spaµiu, valorile a1 , a2 , ..., an .
CAPITOLUL 16. ONI 2016 216

Date de ie³ire
Fi³ierul perechi.out va conµine
1. Dac  C 1, atunci se va rezolva doar prima cerinµ , deci se va a³a pe prima linie valoarea
0 dac  nu se pot obµine în ³ir toate elementele egale, sau se vor a³a trei numere naturale ij v
cu semnicaµia: la poziµiile i ³i j din ³ir se adaug  valoarea v ³i astfel toate elementele vectorului
vor deveni egale.
2. Dac  C 2, atunci se va rezolva doar a doua cerinµ . Pe ecare linie a ³ierului de ie³ire
se vor a³a exact trei valori ij v cu semnicaµia: se adun  valoarea v la ai ³i la aj (unde i ³i j
sunt distincte ³i sunt cuprinse între 1 ³i n).

Restricµii ³i preciz ri
a 5 & n $ 2000, n este impar
a 0 & ai & 100000000 pentru orice i 1, ..., n
a Elementele ³irului iniµial nu sunt neap rat distincte, dar nu sunt nici toate egale
a Dac  exist  mai multe soluµii, puteµi a³a oricare dintre ele
a Dac  num rul operaµiilor aplicate este mai mic sau egal decât n iar valoarea nal  este de
cel mult dou  ori cât maximul iniµial ³i rezultatul aplic rii operaµiilor furnizeaz  în ³ir aceea³i
valoare, atunci veµi primi 100% din punctaj
a Dac  num rul ope raµiilor este cuprins între n1 ³i 2n iar valoarea nal  este de cel mult
dou  ori cât maximul iniµial ³i rezultatul aplic rii operaµiilor furnizeaz  în ³ir aceea³i valoare,
atunci veµi primi 70% din punctaj
a Dac  num rul operaµiilor este mai mare de 2n sau dac  valoarea nal  dep ³e³te dublul valorii
maxime iniµiale, atunci veµi primi 0 puncte . De asemenea, dac  în urma operaµiilor aplicate nu
se obµine un ³ir cu aceea³i valoare peste tot, sau dac  aplicaµi o operaµie în care poziµiile i ³i j nu
sunt din intervalul 1...n, atunci deasemenea veµi primi 0 puncte
a Pentru teste valorând 20 de puncte vom avea C 1. Pentru restul testelor vom avea C 2,
din care pentru 30 de puncte ³irul va  format din numere distincte cuprinse între 1 ³i n

Exemple
perechi.in perechi.out Explicaµii
1 5 8 2 8 8 2 2 5 6 C 1, deci se va rezolva doar prima cerinµ ! Adunând valoarea
6 la poziµiile 2 ³i 5 se va obµine ³irul constant 8 8 8 8 8
2 1 2 2 C 2, deci se va rezolva doar a doua cerinµ ! Valoarea maxim 
5 3 4 4 din ³ir este 10, deci valoarea nal  trebuie s  e maximum 20.
8 5 6 3 10 2 4 3 Trebuie efectuate cel mult 5 operaµii pentru 100 puncte.
Aplicând operaµia 1 2 2, obµinem ³irul 10 7 6 3 10
Aplicând operaµia 3 4 4, obµinem ³irul 10 7 10 7 10
Aplicând operaµia 2 4 3, obµinem ³irul 10 10 10 10 10
1 0 C 1, deci se va rezolva doar prima cerinµ ! Nu se poate efectua
5 o singur  operaµie astfel încât toate elementele ³irului s  devin 
8 2 7 8 2 egale.
2 1 3 1 C 2, deci se va rezolva doar a doua cerinµ ! Valoarea maxim 
3 1 2 2 din ³ir este 3, deci valoarea nal  trebuie s  e maximum 6.
1 2 3 Trebuie efectuate cel mult 3 operaµii pentru 100 puncte.
Aplicând operaµia 1 3 1, obµinem ³irul 2 2 4
Aplicând operaµia 1 2 2, obµinem ³irul 4 4 4

Timp maxim de executare/test: 0.5 secunde


Memorie: total 16 MB
Dimensiune maxim  a sursei: 15 KB

16.3.1 Indicaµii de rezolvare

prof. Dan Pracsiu, Liceul Teoretic Emil Racoviµ  Vaslui

Cerinµa 1
CAPITOLUL 16. ONI 2016 217

Se veric  dac  în ³ir sunt doar dou  valori distincte, una care apare de 2 ori, cealalt  care
apare de n2 ori. În caz armativ, se veric  dac  valoarea care apare de dou  ori este mai mic 
decât cealalt  valoare.

Cerinµa 2
Ordon m cresc tor ³irul. Deoarece trebuie s  r mân  ordinea iniµial , p str m indicii elemen-
telor ordonate.

Dup  sortare pornim de la stânga la dreapta ³i lu m iniµial primele dou  elemente ale ³irului
sortat (cele mai mici).
Fie acestea a ³i b cu a & b. Adun m la cele dou  componente valoarea dat  de diferenµa dintre
cel mai mare din elementele ³irului (acesta se g se³te pe ultima poziµie în ³irul sortat ³i îl not m
cu max) ³i a.
Dup  aceast  operaµie, pe primele dou  poziµii vom avea valorile max ³i b  max  a (& max).
Deci acum valoarea maxim  în ³ir, max, se a  sigur pe a doua poziµie.
Proced m analog cu componentele de pe poziµiile 3 ³i 4 (notate la fel cu a ³i b), adunând la
acestea valoarea max  a, obµinând valorile max
b  max  a.
³i
Similar se procedeaz  cu toate perechile de pe poziµiile 2p  1, 2p.
Ultima de acest fel este n  2, n  1 (nu uit m c  n este impar).
În acest moment am efectuat (n-1) div 2 operaµii de adunare, iar valoarea de pe prima
poziµie este egal  cu cea de pe ultima poziµie, iar în rest, valorile de pe poziµiile 2p sunt egale cu
valorile de pe poziµiile 2p  1.
Maximul în ³ir este pe penultima poziµie n  1.
Vom aduna la toate cuplurile egale atât cât este necesar s  ajungem la valoarea maxim  (deci
înc  (n-1) div 2 operaµii).
În total am efectuat n1 operaµii, deci ne încadr m în limita de n operaµii efectuate.

16.3.2 Cod surs 

Listing 16.3.1: perechi.cpp

1 #include <fstream>
2
3 #define inFile "perechi.in"
4 #define outFile "perechi.out"
5 #define Dim 10005
6
7 using namespace std;
8
9 int a[Dim];
10 int P[Dim];
11 int n;
12
13 void Cerinta1()
14 {
15 int i, cnt;
16 ofstream fout(outFile);
17
18 /// verifica nr de numere diferite
19 cnt = 1;
20 for (i = 2; i <= n; ++i)
21 if (a[i] != a[i - 1]) cnt++;
22
23 if (cnt != 2 || a[2] == a[3])
24 {
25 fout << "0\n";
26 fout.close();
27 return ;
28 }
29
30 cnt = a[3] - a[2];
31 fout<<P[1]<<" "<<P[2]<<" "<<cnt<<"\n";
32 fout.close();
33 }
34
35 void Cerinta2()
36 {
37 int i, ultim, v;
CAPITOLUL 16. ONI 2016 218

38 ofstream fout(outFile);
39
40 ultim = n;
41 for (i = 1; i < n; i += 2)
42 {
43 v = a[ultim] - a[i];
44 if (v > 0)
45 {
46 a[i] += v;
47 a[i + 1] += v;
48 fout << P[i] << " " << P[i + 1] << " " << v << "\n";
49 a[++ultim] = a[i];
50 P[ultim] = P[i];
51 a[++ultim] = a[i + 1];
52 P[ultim] = P[i + 1];
53 }
54 }
55
56 for ( ; i < ultim; i += 2)
57 {
58 v = a[ultim] - a[i];
59 if (v > 0)
60 {
61 a[i] += v;
62 a[i + 1] += v;
63 fout << P[i] << " " << P[i + 1] << " " << v << "\n";
64 }
65 }
66 fout.close();
67 }
68
69 int main()
70 {
71 int i, j, C;
72 int aux;
73
74 //citire
75 ifstream fin(inFile);
76 fin >> C;
77 fin >> n;
78 for (i = 1; i <= n; ++i)
79 {
80 fin >> a[i];
81 P[i] = i;
82 }
83 fin.close();
84
85 //sortare
86 for (i = 1; i < n; ++i)
87 for (j = i + 1; j <= n; ++j)
88 if (a[i] > a[j])
89 {
90 aux = a[i];
91 a[i] = a[j];
92 a[j] = aux;
93 aux = P[i];
94 P[i] = P[j];
95 P[j] = aux;
96 }
97
98 if (C == 1) Cerinta1();
99 else Cerinta2();
100 return 0;
101 }

16.3.3 *Rezolvare detaliat 


Capitolul 17

ONI 2015

17.1 iepuras
Problema 1 - iepuras 100 de puncte
Iepura³ul Cocona³ vrea s  ajung  la gr dina cu morcovi. Pentru aceasta el trebuie s  traverseze
prin salturi o zon  cu propriet µi speciale. Zona este format  dinN c suµe numerotate de la 1 la
N , dispuse una dup  cealalt , iar ecare c suµ  conµine un num r natural ce reprezint  cantitatea
de energie necesar  iepura³ului pentru a s ri într-o alt  c suµ . Iepura³ul pleac  dintr-o anumit 
c suµ  ³i se deplaseaz , de la stânga la dreapta, spre gr dina cu morcovi dup  urm toarele reguli:
a num rul înscris în c suµa în care se a  iepura³ul reprezint  num rul de c suµe peste care el
va s ri;
a dac  num rul înscris în c suµa în care se a  iepura³ul este num r prim, atunci energia lui
se dubleaz  ³i va s ri peste un num r dublu de c suµe;
a num rarea c suµelor peste care va s ri se face de la stânga la dreapta ³i începe cu c suµa
imediat urm toare.
Astfel, dac  iepura³ul se a  în c suµa a treia ³i num rul înscris în aceast  c suµ  este 5,
iepura³ul va ajunge în c suµa cu num rul de ordine 13 (13 3  2 ˜ 5).
a dac  iepura³ul ajunge într-o c suµ  care conµine num rul 0, el r mâne acolo pentru c  nu
mai are energie s  sar  mai departe, altfel el continu  s  sar  dup  regulile descrise mai sus;
a iepura³ul ajunge la gr dina cu morcovi dac  ultimul salt pe care îl face dep ³e³te c suµa N.

Cerinµe
Scrieµi un program care cite³te trei numere naturale P, N ³i K iar apoi N numere naturale ³i
determin :
1) dac  iepura³ul poate ajunge sau nu, la gr dina cu morcovi pornind din c suµa K ³i num rul
de salturi pe care le face iepura³ul pornind din c suµa K;
2) c suµa de pornire a iepura³ului, astfel încât drumul parcurs de el s  traverseze un num r
maxim de c suµe. Pentru a determina num rul de c suµe se vor lua în calcul: c suµa de pornire,
toate c suµele peste care iepura³ul a s rit ³i toate c suµele în care a ajuns în urma salturilor.
Iepura³ul poate porni din oricare c suµ . În cazul în care exist  dou  sau mai multe c suµe de
pornire care conduc la acela³i num r maxim de c suµe traversate se va lua în considerare c suµa
cu num rul de ordine cel mai mic.

Date de intrare
Fi³ierul de intrare iepuras.in conµine pe prima linie un num r natural P . Pentru toate testele
de intrare, num rul P poate avea doar valoarea 1 sau valoarea 2.
Pe a doua linie a ³ierului iepuras.in se g sesc, în aceast  ordine, numerele naturale N ³i K,
separate prin câte un spaµiu.
Pe a treia linie se g sesc N numere naturale separate prin câte un spaµiu, reprezentând valorile
din ecare c suµ  în ordine de la 1 la N.

Date de ie³ire
Dac  valoarea lui P este 1, se va rezolva numai punctul 1) din cerinµe. În acest caz, ³ierul
de ie³ire iepuras.out va conµine pe prima linie cuvântul DA în cazul în care iepura³ul a ajuns în

219
CAPITOLUL 17. ONI 2015 220

gr dina cu morcovi, respectiv cuvântul NU în caz contrar, iar pe a doua linie va conµine un num r
natural reprezentând num rul de salturi pe care le face iepura³ul pornind din c suµa K.
Dac  valoarea lui P este 2, se va rezolva numai punctul 2) din cerinµe. În acest caz, ³ierul
de ie³ire iepuras.out va conµine pe prima linie dou  numere naturale separate printr-un spaµiu
reprezentând, în ordine, c suµa de pornire ³i num rul maxim de c suµe determinat, iar pe a doua
linie, un ³ir de numere naturale separate prin câte un spaµiu reprezentând numerele din c suµele în
care iepura³ul nu s-a aat sau nu a s rit pe parcursul drumului, de la stânga la dreapta, începând
cu c suµa 1. Dac  num rul maxim de c suµe traversate este chiar N linia a doua nu va conµine
niciun num r.

Restricµii ³i preciz ri
a 1 & N & 7000
a 1&K&N
a 0 & numerele conµinute în c suµe & 100
a Pentru rezolvarea corect  a primei cerinµe se acord  30 de puncte, pentru rezolvarea corect 
a celei de a doua cerinµe se acord  70 de puncte.

Exemple
iepuras.in iepuras.out Explicaµii
NU P 1, pentru acest test, se rezolva cerinµa 1).
2 Iepura³ul pleac  din c suµa 3, sare în c suµa cu
num rul de ordine 7 ³i mai departe, în c suµa
cu num rul de ordine 11, unde g sind num rul
0 se opre³te.
2 2 13 P 2, pentru acest test, se rezolv  cerinµa
14 3 2 6 0 1 1 2 0 0 2 1 2). Pentru a traversa un num r maxim de
2 3601121400231 c suµe, iepura³ul pleac  din c suµa cu num rul
de ordine 2 ³i sare, pe rând, în c suµele cu
numerele de ordine 8, 9, 13, ³i apoi în gr din ,
traversând astfel 13 c suµe (de la c suµa 2 la
c suµa 14). Iepura³ul nu s-a aat sau nu a
s rit în c suµele de pe poziµiile 1, 3, 4, 5, 6, 7,
10, 11, 12 ³i 14.

Timp maxim de executare/test: 1.0 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 10 KB

17.1.1 Indicaµii de rezolvare


Soluµia 1
Cerinµa 1
Memor m traseul cu c suµe într-un vector pe poziµiile de la 1 pâna la N.
Pornim parcurgerea vectorului de la poziµia k ³i parcurgem vectorul cât timp valoarea gasit 
în c suµ  este diferit  de 0 ³i indicele c suµei este mai mic sau egal cu N.
Cre³tem indicele vectorului cu valoarea care se g se³te memorat  în c suµ  dac  num rul nu
este prim sau cu dublul valorii care se g se³te în c suµ  dac  num rul este prim. Increment m
num rul de salturi pe care le face iepura³ul.

Algoritmul se repet  pân  când ajungem într-o c suµ  care conµine num rul 0 sau pân  când
indicele calculat dep ³e³te valoarea N.
Dac  indicele la care ajungem este mai mic sau egal cu N, iepura³ul nu ajunge la gr dina cu
morcovi ³i scriem NU, altfel iepura³ul ajunge la gr dina cu morcovi ³i scriem DA.
La nal a³ m num rul de salturi.

Cerinµa 2
Calcul m num rul de c suµe peste care poate s ri iepura³ul (ca la cerinµa 1) pornind din c suµa
1.
CAPITOLUL 17. ONI 2015 221

Dac  indicele c suµei la care ajunge iepura³ul este mai mare strict decat N atunci
num rul de c suµe = N - poziµia de pornire + 1
altfel
num rul de c suµe = indicele c suµe - poziµia de pornire + 1.

Actualiz m maximum ³i poziµia de pornire.


Repet m algoritmul pentru restul c suµelor pân  la N.
Scriem poziµia de pornire ³i valoarea num rului maxim de c suµe în ³ier.
Scriem toate c suµele de la 1 pân  la c suµa de pornire determinat  mai sus apoi scriem toate
c suµele de pe traseul iepura³ului, cu excepµia c suµei de pornire ³i a celor în care a s rit.
Dac  ultima c suµ  în care ajunge iepura³ul are indicele strict mai mic decât N, scriem restul
c suµelor pân  la N.
2
Soluµia are complexitatea O n .
Soluµia 2
Cerinµa 1
Se memoreaz  numerele din casuµe într-un vector v.
Se simuleaz  s riturile iepura³ului ce porne³te din c suµa k ³i se opreste e când ajunge la o
c suµ  ce conµine num rul 0 e când ajunge în gr dina cu morcovi.

Cerinµa 2
Pentru a determina num rul maxim de c suµe traversate se construie³te începând cu poziµia
n, un vector suplimentar a cu semnicaµia:
ai = poziµia în care se opre³te iepura³ul ce porne³te din c suµa cu num rul i.

~
„n; dac  pornim din poziµia i iepura³ul ajunge în gr din 
„
„
„i;
„ dac  ai 0
ai „
‚
„
„
„ai  2 ˜ ai; dac  ai este num r prim
„
„
„ai  ai; ai
€ dac  nu este num r prim

Pentru ecare poziµie i, începând cu poziµia n se determin  num rul c suµelor traversate ca


ind l ai  i  1 ³i se actualizeaz  valoarea maxim , reµinându-se poziµia.

17.1.2 Cod surs 

Listing 17.1.1: iepuras_1.cpp

1 #include <iostream>
2 #include <fstream>
3 #include <cmath>
4
5 using namespace std;
6 const int DIM=100000;
7 int v[DIM],x[101];
8
9 /*void afisare(int N, unsigned int v[DIM])
10 {
11 int i;
12 for(i=1;i<=N;i++)
13 cout<<v[i]<<’ ’;
14 cout<<endl;
15 }*/
16
17 void prim(int n)
18 {
19 int i,j;
20 for (i=2;i<=n;i++)
21 x[i]=1;
22 for (i=2;i<=sqrt(n);i++)
23 if (x[i])
24 for (j=i;j<=n/i;j++)
25 x[i*j]=0;
26 }
27
28 int main()
CAPITOLUL 17. ONI 2015 222

29 {
30 int N, K, P, i, j, l, nr=0, Max=0, poz; //nr-numar salturi din pozitia i
31 ifstream in("iepuras.in");
32 ofstream out("iepuras.out");
33
34 in>>P>>N>>K;
35 for(i=1;i<=N;i++) in>>v[i];
36 prim(100);
37
38
39 if(P==1)
40 { //cerinta 1
41 j=K; nr=0;
42 while(v[j] && j<=N)
43 {
44 nr++;
45 if(x[v[j]])
46 j+=2*v[j];
47 else
48 j+=v[j];
49 }
50
51 if(j<=N)
52 {
53 out<<"NU"<<endl;
54 out<<nr;
55 }
56 else
57 {
58 out<<"DA"<<endl;
59 out<<nr;
60 }
61 }
62 else
63 {
64 //cerinta 2
65 i=1,j=1;
66 while(i<=N && j<=N)
67 {
68 j=i;nr=1;
69 while(v[j] && j<=N)
70 {
71 if(x[v[j]])
72 j+=2*v[j];
73 else
74 j+=v[j];
75 }
76
77 if(j>N)
78 nr=N-i+1;
79 else
80 nr=j-i+1;
81 if(nr>Max)
82 poz=i, Max=nr;
83 i++;
84 }
85
86 out<<poz<<’ ’<<Max<<’\n’;
87
88 for(i=1;i<=poz-1;i++)
89 out<<v[i]<<’ ’;
90
91 j=poz;
92 for(i=1;i<=Max && i<=N;i++)
93 {
94 if(x[v[j]])
95 j+=2*v[j];
96 else
97 j+=v[j];
98
99 for(l=poz+1;l<j && l<=N;l++)
100 out<<v[l]<<’ ’;
101
102 poz=j;
103 }
104
CAPITOLUL 17. ONI 2015 223

105 for(i=j+1;i<=N;i++)
106 out<<v[i]<<’ ’;
107 }
108 return 0;
109 }

Listing 17.1.2: iepuras_2.cpp

1 #include <cstdio>
2 #include <cassert>
3
4 using namespace std;
5
6 int i, N, A[100005], Countstep, step, P, K, Pos, Count, CountMax;
7 bool Prim[100];
8
9 bool prim(int x)
10 {
11 for(int d=2; d*d<=x; d++)
12 if(x%d==0) return false;
13 return (x>=2);
14 }
15
16 int main()
17 {
18 freopen("iepuras.in", "r",stdin);
19 freopen("iepuras.out","w",stdout);
20
21 scanf("%d\n%d%d\n",&P, &N, &K);
22 assert(P>0&& P<3 && N>=1 && N<=7000);
23
24 for(int i=1; i<=N; i++)
25 {
26 scanf("%d", &A[i]);
27 assert( A[i]>=0 && A[i]<=100);
28 }
29
30 for(int i=2; i<=100; i++) Prim[i]=prim(i);
31
32 if(P==1)
33 { Countstep=0;
34 for(i=K; i<=N && A[i]; i+=step, Countstep++)
35 {
36 if (Prim[A[i]]) step=A[i]*2;
37 else step=A[i];
38 }
39
40 if (i>N) printf("DA\n%d", Countstep);
41 else printf("NU\n%d", Countstep);
42 }
43 else
44 {
45 CountMax=0;
46 for(int I=1; I<=N ; I++)
47 {
48 for(i=I; i<=N && A[i]; i+=step)
49 {
50 if (Prim[A[i]]) step=A[i]*2;
51 else step=A[i];
52 }
53
54 if (i>N) i = N;
55
56 if(i- I + 1>CountMax)
57 {
58 CountMax=i- I + 1;
59 Pos = I;
60 }
61 }
62
63 printf("%d %d\n", Pos, CountMax);
64
65 for(i=1; i<=N; i++)
66 if(i!=Pos) printf("%d ", A[i]);
67 else
CAPITOLUL 17. ONI 2015 224

68 if (Prim[A[i]]) Pos+=A[i]*2;
69 else Pos+=A[i];
70 }
71
72 return 0;
73 }

Listing 17.1.3: iepuras_3.cpp

1 #include <cstdio>
2 #include <cassert>
3
4 using namespace std;
5
6 int i, N, A[100005],Countstep, step, P, K, Pos, Count, CountMax;
7 bool Prim[100];
8
9 bool prim(int x)
10 {
11 for(int d=2; d*d<=x; d++)
12 if(x%d==0) return false;
13 return (x>=2);
14 }
15
16 int main()
17 {
18 freopen("iepuras.in", "r",stdin);
19 freopen("iepuras.out","w",stdout);
20
21 scanf("%d\n%d%d\n",&P, &N, &K);
22
23 for(int i=1; i<=N; i++)
24 {
25 scanf("%d", &A[i]);
26 }
27
28 for(int i=2; i<=100; i++) Prim[i]=prim(i);
29
30 if(P==1)
31 { Countstep=0;
32 for(i=K; i<=N && A[i]; i+=step, Countstep++)
33 {
34 if (Prim[A[i]]) step=A[i]*2;
35 else step=A[i];
36 }
37
38 if (i>N) printf("DA\n%d", Countstep);
39 else printf("NU\n%d", Countstep);
40 }
41 else
42 {
43 CountMax=0;
44 for(int I=1; I<=N ; I++)
45 {
46 for(i=I; i<=N && A[i]; i+=step)
47 {
48 if (Prim[A[i]]) step=A[i]*2;
49 else step=A[i];
50 }
51
52 if (i>N) i = N;
53
54 if(i- I + 1>CountMax)
55 {
56 CountMax=i- I + 1;
57 Pos = I;
58 }
59 }
60
61 printf("%d %d\n", Pos, CountMax);
62
63 for(i=1; i<=N; i++)
64 if(i!=Pos) printf("%d ", A[i]);
65 else
66 if (Prim[A[i]]) Pos+=A[i]*2;
CAPITOLUL 17. ONI 2015 225

67 else Pos+=A[i];
68 }
69
70 return 0;
71 }

Listing 17.1.4: iepuras_4.cpp

1 #include <fstream>
2 #include <iostream>
3
4 using namespace std;
5
6 int prim (int x)
7 {
8 if (x<2) return 0;
9 if (x==2) return 1;
10 if (x%2==0) return 0;
11 for (int i=3; i*i<=x; i++)
12 if (x%i==0) return 0;
13 return 1;
14 }
15
16 int v[100001];
17 int a[100001];
18
19 int main()
20 {
21 ifstream f("iepuras.in");
22 ofstream g("iepuras.out");
23
24 int n,p,k,i,j,nr=0,l;
25
26 f>>p>>n>>k;
27 for (i=1; i<=n; i++) f>>v[i];
28
29 if (p==1)
30 {
31 while (k<=n && v[k]!=0)
32 {
33 nr++;
34 if (prim (v[k])) k=k+2*v[k];
35 else k=k+v[k];
36 }
37
38 if (k>n) g<<"DA"<<’\n’<<nr<<’\n’;
39 else g<<"NU"<<’\n’<<nr<<’\n’;
40 }
41 else
42 {
43 int vm=-1;
44 for (i=n; i>=1; i--)
45 {
46 if (v[i]==0)
47 a[i]=i;
48 else
49 if (prim(v[i]))
50 {
51 j=i+2*v[i];
52 if (j<n) a[i]=a[j];
53 else a[i]=n;
54 }
55 else
56 {
57 j=i+v[i];
58 if (j<n) a[i]=a[j];
59 else a[i]=n;
60 }
61
62 l=a[i]-i+1;
63 if (vm<=l){vm=l; k=i;}
64 }
65
66 g<<k<<’ ’<<vm<<’\n’;
67
CAPITOLUL 17. ONI 2015 226

68 int u=1;
69
70 for (i=1; i<k; i++) g<<v[i]<<’ ’;
71
72 while (k<=n && v[k]!=0)
73 {
74 u=k+1;
75 if (prim (v[k])) k=k+2*v[k];
76 else k=k+v[k];
77
78 if (k<=n) for (i=u; i<k; i++) g<<v[i]<<’ ’;
79 else for (i=u; i<=n; i++) g<<v[i]<<’ ’;
80 }
81
82 if (k<n && v[k]==0)
83 for (i=k+1; i<=n; i++) g<<v[i]<<’ ’;
84
85 g<<’\n’;
86 }
87
88 return 0;
89 }

Listing 17.1.5: iepuras_5.cpp

1 #include <fstream>
2 #include <cassert>
3
4 using namespace std;
5
6 int prim (int x)
7 {
8 if (x<2) return 0;
9 if (x==2) return 1;
10 if (x%2==0) return 0;
11 for (int i=3; i*i<=x; i++)
12 if (x%i==0) return 0;
13 return 1;
14 }
15
16 int v[100001];
17 int a[100001];
18
19 int main()
20 {
21 ifstream f("iepuras.in");
22 ofstream g("iepuras.out");
23
24 int n,p,k,i,j,nr=0,l,x;
25
26 f>>p>>n>>k;
27
28 i=0;
29 while (f>>x)
30 {
31 i++; v[i]=x;
32 assert (v[i]>=0&&v[i]<=100);
33 }
34
35 assert(p==1 || p==2);
36 assert(n>=1&& n<=7000);
37 assert(k<=n && k>=1);
38 assert(i==n);
39
40 if (p==1)
41 {
42 while (k<=n && v[k]!=0)
43 {
44 nr++;
45 if (prim (v[k])) k=k+2*v[k];
46 else k=k+v[k];
47 }
48
49 if (k>n) g<<"DA"<<’\n’<<nr<<’\n’;
50 else g<<"NU"<<’\n’<<nr<<’\n’;
CAPITOLUL 17. ONI 2015 227

51 }
52 else
53 {
54 int vm=-1;
55 for (i=n; i>=1; i--)
56 {
57 if (v[i]==0)
58 a[i]=i;
59 else
60 if (prim(v[i]))
61 {
62 j=i+2*v[i];
63 if (j<n) a[i]=a[j];
64 else a[i]=n;
65 }
66 else
67 {
68 j=i+v[i];
69 if (j<n) a[i]=a[j];
70 else a[i]=n;
71 }
72
73 l=a[i]-i+1;
74 if (vm<=l){vm=l; k=i;}
75 }
76
77 g<<k<<’ ’<<vm<<’\n’;
78
79 int u=1;
80
81 for (i=1; i<k; i++) g<<v[i]<<’ ’;
82 while (k<=n && v[k]!=0)
83 {
84 u=k+1;
85 if (prim (v[k])) k=k+2*v[k];
86 else k=k+v[k];
87
88 if (k<=n) for (i=u; i<k; i++) g<<v[i]<<’ ’;
89 else for (i=u; i<=n; i++) g<<v[i]<<’ ’;
90 }
91
92 if (k<n && v[k]==0)
93 for (i=k+1; i<=n; i++) g<<v[i]<<’ ’;
94
95 g<<’\n’;
96 }
97
98 return 0;
99 }

Listing 17.1.6: iepuras_6.cpp

1 #include <fstream>
2 #include <math.h>
3
4 #define MAX 100
5
6 using namespace std;
7
8 ifstream f("iepuras.in");
9 ofstream g("iepuras.out");
10
11 bool c[MAX],e1[100001];
12 int e[100001],salturi,N,P,M,K,pozMin,nrMax;
13
14 int main()
15 {
16 int i,j,aux;
17 c[1]=1;
18
19 //generare ciur
20 M=sqrt(MAX);
21 for(i=2;i<=M;i++)
22 if(c[i]==0)
23 for(j=i*i;j<=MAX;j+=i)c[j]=1;
CAPITOLUL 17. ONI 2015 228

24
25 //citire
26 f>>P>>N>>K;
27 for(i=1;i<=N;i++)f>>e[i];
28
29 if(P==1)//1)
30 {
31 //sarituri iepure
32 for(i=K;i<=N;)
33 if(e[i]==0)break;
34 else
35 {
36 salturi++;aux=e[i];if(c[aux]==0)aux*=2; i=i+aux;
37 }
38
39 //verficare
40 if(i<=N)g<<"NU"<<’\n’;else g<<"DA"<<’\n’;
41 g<<salturi<<’\n’;
42 }
43 else//2)
44 {
45 for(i=1;N-i>nrMax;i++)
46 {
47 //caut nrMax si pozMin
48 j=i;
49 while(j<=N && e[j]!=0)
50 {
51 if(c[e[j]]==0)j+=2*e[j];
52 else j+=e[j];
53 }
54
55 if(j>N)salturi=N-i+1;
56 else salturi=j-i+1;
57
58 if(salturi>nrMax) {nrMax=salturi;pozMin=i;}
59 }
60
61 //afisez pozMin si nrMax
62 g<<pozMin<<’ ’<<nrMax<<’\n’;
63
64 //afisez casutele pana la pozMin
65 for(i=1;i<pozMin;i++) g<<e[i]<<’ ’;
66
67 //fac traseul maxim
68 for(i=pozMin;i<=N;)
69 {
70 e1[i]=1;
71 if(e[i]==0)break;
72 else
73 {
74 aux=e[i];if(c[aux]==0)aux*=2;i+=aux;e1[i]=1;
75 }
76 }
77
78 //afisez casutele de la pozMin pana unde a mers
79 for(i=pozMin;i<=pozMin+nrMax-1;i++)
80 if(e1[i]==0)g<<e[i]<<’ ’;
81
82 //afisez casutele pana la N
83 for(;i<=N;i++)if(e1[i]!=-1)g<<e[i]<<’ ’;
84
85 g<<’\n’;
86 }
87
88 f.close();
89 g.close();
90 return 0;
91 }

17.1.3 *Rezolvare detaliat 


CAPITOLUL 17. ONI 2015 229

17.2 inventie
Problema 2 - inventie 100 de puncte
Lui Mihai îi place matematica distractiv , sau poate mai mult distracµia decât matematica.
Pentru a sc pa de teme, el a inventat operaµia smile notat  cu semnul , operaµie care se aplic 
numerelor naturale nenule conform exemplelor de mai jos:
6 4=210 8 5=313 6 6=12 43 1500=14571543
9 2=711 7 6=113 6 10=416 23 23=46
Profesorul de matematic  i-a promis nota 10 pentru invenµie, numai dac  ³tie s  determine
corect num rul divizorilor pari pentru rezultatul obµinut prin operaµia smile. Astfel, Mihai a
primit N perechi de numere a, b pentru care trebuie s  calculeze a b ³i s  determine dac 
rezultatul obµinut are divizori pari.

Cerinµe
Scrieµi un program care cite³te un num r natural N ³i N perechi de numere naturale a, b ³i
a³eaz :
a) pentru ecare pereche de numere a, b, rezultatul a b;
b) cel mai mic ³i cel mai mare rezultat a b care nu are divizori pari.

Date de intrare
Fi³ierul de intrare inventie.in conµine pe prima linie un num r natural N . Fiecare din urm -
toarele N linii conµine câte dou  numere naturale a, b desp rµite printr-un spaµiu.

Date de ie³ire
În ³ierul de ie³ire inventie.out:
a pentru ecare din cele N perechi a, b, se va a³a rezultatul a b, ecare rezultat pe câte o
linie, în ordinea în care perechile apar în ³ierul de intrare;
a dac  toate cele N rezultate obµinute au divizori pari, pe linia N  1 se va a³a valoarea 0
(zero);
a dac  s-a obµinut m car un rezultat f r  divizori pari, atunci, pe linia N  1 se va a³a cel
mai mic rezultat a b care nu are divizori pari, ³i pe linia N  2 se va a³a cel mai mare rezultat
a b care nu are divizori pari. Dac  un singur rezultat nu are divizori pari, atunci acesta va  scris
³i pe linia N  1 ³i pe linia N  2.

Restricµii ³i preciz ri
a 1 & N & 20
a a ³i b sunt numere naturale nenule de maxim 18 cifre ecare

Exemple
inventie.in inventie.out Explicaµii
8 210 Prin operaµia smile se obµin, în ordine, valorile 210, 711,
6 4 711 313, 113, 12, 416, 14571543, 46.
9 2 313 Dintre acestea nu au divizori pari numerele 711, 313, 113,
8 5 113 14571543, cel mai mic ind 113 ³i cel mai mare 14571543.
7 6 12
6 6 416
6 10 14571543
43 1500 46
23 23 113
14571543
2 26 Prin operaµia smile se obµin, în ordine, valorile 26,
13 13 9761512 9761512, ambele numere având divizori pari.
268 1244 0

Timp maxim de executare/test: 0.5 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 10 KB
CAPITOLUL 17. ONI 2015 230

17.2.1 Indicaµii de rezolvare


Rezultatul "invenµiei" se obµine prin concatenarea valorilor ¶a  b¶ si a  b.
Un caz special este cazul a b, cand rezultatul este a  b.
Numerele care au 0 divizori pari sunt numerele impare, prin urmare pentru a doua cerinµ  ne
intereseaz  doar perechile a, b în care ab este num r par, adic  perechile a, b în care a ³i b
au parit µi diferite.
Se determin  minimul ³i maximul dintre rezultatele obµinute din perechile a, b cu a ³i b având
parit µi diferite.
Numerele a ³i b având maxim 18 cifre, rezultatul invenµiei poate  un num r mare, deci trebuie
efectuate comparaµii între numere mari.

17.2.2 Cod surs 

Listing 17.2.1: inventie_1.cpp

1 #include<fstream>
2 #include<algorithm>
3
4 using namespace std;
5
6 int main()
7 {
8 int gasit=0,n,v[60],vmin[60],vmax[60],maimic,maimare,i,k;
9
10 unsigned long long s,dif,a,b;
11
12 ifstream f("inventie.in");
13 ofstream g("inventie.out");
14
15 f>>n;
16
17 for (i=1; i<=n; i++)
18 {
19 f>>a>>b;
20 if (a==b) g<<a+b<<’\n’;
21 else
22 {
23 if (a>b) dif=a-b;
24 else dif=b-a;
25 g<<dif<<a+b<<’\n’;
26 }
27
28 if (a%2!=b%2)
29 {
30 k=0; // numarul cifrelor
31 gasit=1;
32 s=a+b;
33 while (s)
34 {
35 k++;
36 vmin[k]=vmax[k]=s%10;
37 s=s/10;
38 }
39 while (dif)
40 {
41 k++;
42 vmin[k]=vmax[k]=dif%10;
43 dif=dif/10;
44 }
45 vmin[0]=vmax[0]=k;
46 break;
47 }
48 }
49
50 i++;
51 while (i<=n)
52 {
53 f>>a>>b; //g<<" am citit "<<a<<’ ’<<b<<"la pasul "<<i<<’\n’;
54 if (a==b) g<<a+b<<’\n’;
55 else
CAPITOLUL 17. ONI 2015 231

56 {
57 if (a>b) dif=a-b;
58 else dif=b-a;
59 g<<dif<<a+b<<’\n’;
60 }
61
62 if (a%2!=b%2)
63 {
64 k=0; // numarul cifrelor
65 s=a+b;
66 while (s)
67 {
68 k++;
69 v[k]=s%10;
70 s=s/10;
71 }
72 while (dif)
73 {
74 k++;
75 v[k]=dif%10;
76 dif=dif/10;
77 }
78
79 v[0]=k;
80 // verific daca noul rezultat este mai mic decat vmin,
81 // sau mai mare decat vmax
82 if (v[0]<vmin[0])
83 for (int j=0; j<=v[0]; j++) vmin[j]=v[j];
84 else if (v[0]>vmax[0])
85 for (int j=0; j<=v[0]; j++) vmax[j]=v[j];
86 else
87 {
88 if (v[0]==vmin[0])
89 {
90 maimic=1;// pres ca v<vmin
91 for (int j=v[0]; j>=1; j--)
92 if (v[j]>vmin[j])
93 {
94 maimic=0;
95 break;
96 }
97 else if (v[j]<vmin[j]) break;
98 if (maimic){
99 for (int j=0; j<=v[0]; j++) vmin[j]=v[j];
100 }
101 }
102
103 if (v[0]==vmax[0])
104 {
105 maimare=1; // pres ca v>vmax
106 for (int j=v[0]; j>=1; j--)
107 if (v[j]<vmax[j])
108 {
109 maimare=0;
110 break;
111 }
112 else if (v[j]>vmax[j]) break;
113 if (maimare)
114 for (int j=0; j<=v[0]; j++) vmax[j]=v[j];
115 }
116 }
117 }
118 i++;
119 }
120
121 if (gasit==0) g<<0<<’\n’;
122 else
123 {
124 for (int j=vmin[0]; j>=1; j--) g<<vmin[j];
125 g<<’\n’;
126 for (int j=vmax[0]; j>=1; j--) g<<vmax[j];
127 g<<’\n’;
128 }
129 return 0;
130 }
CAPITOLUL 17. ONI 2015 232

Listing 17.2.2: inventie_2cpp

1 #include <fstream>
2 #include <cstring>
3
4 using namespace std;
5
6 ifstream fin("inventie.in");
7 ofstream fout("inventie.out");
8
9 unsigned ct,ad[40],i,k,maxx[40],minn[40];
10 int j;
11
12 void aduna(unsigned long long a, unsigned long long b)
13 {
14 i=0;
15 ct=0;
16 while(a||b)
17 {
18 ad[++i]=(a%10+b%10+ct)%10;
19 ct=(a%10+b%10+ct)/10;
20 a/=10;
21 b/=10;
22 }
23 if(ct) ad[++i]=ct;
24 ad[0]=i;
25 }
26
27 int comp(unsigned x[],unsigned y[])
28 {
29 if(x[0]<y[0]) return -1;
30 else
31 if(x[0]>y[0]) return 1;
32 else
33 {
34 for(j=x[0];j>=1;j--)
35 if(x[j]<y[j]) return -1;
36 else if (x[j]>y[j])return 1;
37 return 0;
38 }
39 }
40
41 int main()
42 {
43 unsigned n,ok=0;
44 unsigned long long a,b,z;
45
46 maxx[0]=0;
47 minn[0]=39;
48 for(j=1;j<=39;j++) minn[j]=9;
49 fin>>n;
50 for(k=1;k<=n;k++)
51 {
52 memset(ad,0,sizeof(ad));
53 fin>>a>>b;
54 aduna(a,b);
55
56 if(a==b);
57 else
58 if(a>b) fout<<a-b;
59 else fout<<b-a;
60
61 for(j=ad[0];j>=1;j--) fout<<ad[j];
62 fout<<’\n’;
63
64 if(a%2!=b%2)
65 {
66 ok=1;
67 z = a>b ? a-b : b-a;
68 j=ad[0];
69
70 while(z)
71 {
72 ad[++j]=z%10;
73 z/=10;
74 }
CAPITOLUL 17. ONI 2015 233

75
76 ad[0]=j;
77 if(comp(ad,minn)<0)
78 {
79 for(j=ad[0];j>=0;j--) minn[j]=ad[j];
80 }
81 if(comp(ad,maxx)>0)
82 for(j=ad[0];j>=0;j--){ maxx[j]=ad[j]; }
83 }
84 }
85
86 if(ok)
87 {
88 for(k=minn[0];k>=1;k--) fout<<minn[k];
89 fout<<’\n’;
90
91 for(k=maxx[0];k>=1;k--)fout<<maxx[k];
92 fout<<’\n’;
93 }
94 else fout<<0<<’\n’;
95
96 return 0;
97 }

Listing 17.2.3: inventie_3.cpp

1 #include <cstdio>
2 #include <cassert>
3
4 using namespace std;
5
6 unsigned long long x, y, Y, X;
7
8 int Min[55], Max[55], m, b[55], i, N;
9
10 int main()
11 {
12 freopen("inventie.in", "r",stdin);
13 freopen("inventie.out","w",stdout);
14
15 scanf("%d\n",&N);
16
17 for(int i= 1; i<=50; i++) Min[i]=9;
18
19 Min[0]=50;
20 for(int i= 1; i<=N; i++)
21 {
22 scanf("%lld %lld\n",&x, &y);
23
24 X=(x<y ? y-x: x-y);
25
26 Y= x + y;
27 if(x!=y) printf("%llu",X);
28 printf("%llu\n",Y);
29
30 if(x%2!=y%2)
31 {
32 m=0;
33 while(Y)
34 {
35 b[++m]=Y%10;
36 Y/=10;
37 }
38
39 while(X)
40 {
41 b[++m]=X%10;
42 X/=10;
43 }
44
45 b[0]=m;
46 if(b[0] > Max[0])
47 for(int i=0; i<=b[0]; i++) Max[i]=b[i];
48
49 if(b[0] < Min[0])
CAPITOLUL 17. ONI 2015 234

50 for(int i=0; i<=b[0]; i++) Min[i]=b[i];


51
52 if(b[0]==Max[0])
53 {
54 for(int i=b[0]; i>=1 && b[i]==Max[i]; i--);
55
56 if(i>0 && b[i]>Max[i])
57 for(int i=0; i<=b[0]; i++) Max[i]=b[i];
58 }
59
60 if(b[0]==Min[0])
61 {
62 for(int i=b[0]; i>=1 && b[i]==Min[i]; i--);
63 if(i>0 && b[i]<Min[i])
64 for(int i=0; i<=b[0]; i++) Min[i]=b[i];
65 }
66 }
67 }
68
69 if(Min[0]==50 && Max[0]==0) printf("0\n");
70 else
71 {
72 for(int i=Min[0]; i>=1 ; i--) printf("%d", Min[i]);
73 printf("\n");
74 for(int i=Max[0]; i>=1 ; i--) printf("%d", Max[i]);
75 }
76
77 return 0;
78
79 }

Listing 17.2.4: inventie_4_20p.cpp

1 #include<fstream>
2
3 using namespace std;
4
5 int main()
6 {
7 int n,i,gasit=0;
8 unsigned int s,dif,a,b,vmin,vmax,p,nr;
9
10 ifstream f("inventie.in");
11 ofstream g("inventie.out");
12
13 f>>n;
14 for (i=1; i<=n; i++)
15 {
16 f>>a>>b;
17 if (a==b) nr=a+b;
18 else
19 {
20 if (a>b) dif=a-b;
21 else dif=b-a;
22 s=a+b;
23 p=1;
24 while (s)
25 {
26 s=s/10;
27 p=p*10;
28 }
29 nr=dif*p+a+b;
30 }
31 g<<nr<<’\n’;
32 if (a%2!=b%2)
33 {
34 gasit=1;
35 vmin=vmax=nr;
36 break;
37 }
38 }
39 i++;
40 while (i<=n)
41 {
42 f>>a>>b; //g<<" am citit "<<a<<’ ’<<b<<"la pasul "<<i<<’\n’;
CAPITOLUL 17. ONI 2015 235

43 if (a==b) nr=a+b;
44 else
45 {
46 if (a>b) dif=a-b;
47 else dif=b-a;
48 s=a+b;
49 p=1;
50 while (s)
51 {
52 s=s/10;
53 p=p*10;
54 }
55 nr=dif*p+a+b;
56 }
57 g<<nr<<’\n’;
58 if (a%2!=b%2)
59 {
60 if (vmin>nr) vmin=nr;
61 if (vmax<nr) vmax=nr;
62 }
63 i++;
64 }
65 if (gasit==0) g<<0<<’\n’;
66 else
67 g<<vmin<<’\n’<<vmax<<’\n’;
68 return 0;
69 }

Listing 17.2.5: inventie_5_45p.cpp

1 #include<fstream>
2
3 using namespace std;
4
5 int main()
6 {
7 int n,i,gasit=0;
8 unsigned long long s,dif,a,b,vmin,vmax,p,nr;
9
10 ifstream f("inventie.in");
11 ofstream g("inventie.out");
12
13 f>>n;
14 for (i=1; i<=n; i++)
15 {
16 f>>a>>b;
17 if (a==b) nr=a+b;
18 else
19 {
20 if (a>b) dif=a-b;
21 else dif=b-a;
22 s=a+b;
23 p=1;
24 while (s)
25 {
26 s=s/10;
27 p=p*10;
28 }
29 nr=dif*p+a+b;
30 }
31 g<<nr<<’\n’;
32 if (a%2!=b%2)
33 {
34 gasit=1;
35 vmin=vmax=nr;
36 break;
37 }
38 }
39 i++;
40 while (i<=n)
41 {
42 f>>a>>b; //g<<" am citit "<<a<<’ ’<<b<<"la pasul "<<i<<’\n’;
43 if (a==b) nr=a+b;
44 else
45 {
CAPITOLUL 17. ONI 2015 236

46 if (a>b) dif=a-b;
47 else dif=b-a;
48 s=a+b;
49 p=1;
50 while (s)
51 {
52 s=s/10;
53 p=p*10;
54 }
55 nr=dif*p+a+b;
56 }
57 g<<nr<<’\n’;
58 if (a%2!=b%2)
59 {
60 if (vmin>nr) vmin=nr;
61 if (vmax<nr) vmax=nr;
62 }
63
64 i++;
65 }
66 if (gasit==0) g<<0<<’\n’;
67 else
68 g<<vmin<<’\n’<<vmax<<’\n’;
69 return 0;
70 }

Listing 17.2.6: inventie_6.cpp

1 #include <fstream>
2 #include <math.h>
3
4 using namespace std;
5
6 ifstream f("inventie.in");
7 ofstream g("inventie.out");
8
9 unsigned long long a,b,c,d;
10 int N,nrmin[40],nrmax[40];
11
12 int compar(int v1[],int v2[])
13 {
14 int i;
15 if(v1[0]>v2[0]) return 1;
16 if(v1[0]<v2[0]) return 2;
17 for(i=1;i<=v1[0];i++)
18 if(v1[i]!=v2[i])break;
19 if(i>v1[0])return 0;
20 if(v1[i]>v2[i])return 1;
21 else return 2;
22 }
23
24 void copie(int v1[], int v2[])
25 {
26 for(int i=0;i<=v2[0];i++) v1[i]=v2[i];
27 }
28
29 int main()
30 {
31 f>>N;
32 nrmin[0]=40;
33 int i;
34 for(i=1;i<=N;i++)
35 {
36 f>>a>>b;
37 if(a>=b)c=a-b;
38 else c=b-a;
39 d=a+b;
40 if(c!=0)g<<c;
41 g<<d;
42 g<<’\n’;
43 if(a%2!=b%2)
44 {
45 int v[40]={0};
46
47 //adaug c in vector
CAPITOLUL 17. ONI 2015 237

48 if(c!=0)
49 {
50 int nrc=0;
51 unsigned long long c1=c;
52 while(c1>0){nrc++;c1/=10;}
53 v[0]=nrc;
54 for(int ii=nrc;ii>=1;ii--)
55 {
56 v[ii]=c%10;
57 c/=10;
58 }
59 }
60
61 //completez cu d=a+b
62 int nrc=0;
63 unsigned long long d1=d;
64 while(d1>0){nrc++;d1/=10;}
65 v[0]+=nrc;
66 for(int ii=v[0];d>0;ii--){v[ii]=d%10;d/=10;}
67 if(compar(v,nrmin)==2)copie(nrmin,v);
68 if(compar(v,nrmax)==1)copie(nrmax,v);
69 }
70 }
71
72 if(nrmax[0]!=0)
73 {
74 int i;
75 for(i=1;i<=nrmin[0];i++)g<<nrmin[i];
76 g<<’\n’;
77 for(i=1;i<=nrmax[0];i++)g<<nrmax[i];
78 g<<’\n’;
79 }
80 else g<<0<<’\n’;
81
82 f.close();
83 g.close();
84 return 0;
85 }

Listing 17.2.7: inventie_7.cpp

1 #include <fstream>
2 #include <string.h>
3
4 using namespace std;
5
6 ifstream f("inventie.in");
7 ofstream g("inventie.out");
8
9 unsigned long long a,b,c,d;
10 int N;
11
12 char nrmin[40]="999999999999999999999999999999999999999",nrmax[40],v[40];
13
14 int main()
15 {
16 f>>N;
17 int i;
18 for(i=1;i<=N;i++)
19 {
20 f>>a>>b;
21
22 if(a>=b)c=a-b;
23 else c=b-a;
24
25 d=a+b;
26 if(c!=0)g<<c;
27 g<<d;
28 g<<’\n’;
29
30 if(a%2!=b%2)
31 {
32 //pun d in v oglindit
33 int nrc=0;
34 while(d>0){v[nrc++]=’0’+d%10;d/=10;}
CAPITOLUL 17. ONI 2015 238

35
36 //pun c in v oglindit
37 if(c!=0)
38 {
39 while(c>0){v[nrc++]=’0’+c%10;c/=10;}
40 }
41
42 v[nrc]=0;
43 for(int j=0;j<strlen(v)/2;j++)
44 {
45 char aux=v[j];
46 v[j]=v[strlen(v)-j-1];
47 v[strlen(v)-j-1]=aux;
48 }
49
50 if(strlen(v)<strlen(nrmin)) strcpy(nrmin,v);
51 else
52 if(strlen(v)==strlen(nrmin) && strcmp(v,nrmin)<0)strcpy(nrmin,v);
53
54 if(strlen(v)>strlen(nrmax))strcpy(nrmax,v);
55 else
56 if(strlen(v)==strlen(nrmax) && strcmp(v,nrmax)>0)strcpy(nrmax,v);
57 }
58 }
59
60 if(nrmax[0]!=0) g<<nrmin<<’\n’<<nrmax<<’\n’;
61 else g<<0<<’\n’;
62
63 f.close();
64 g.close();
65 return 0;
66 }

Listing 17.2.8: inventie_8_35p.cpp

1 #include<fstream>
2
3 using namespace std;
4
5 int main()
6 {
7 int n,i,gasit=0;
8 long long s,dif,a,b,vmin,vmax,p,nr;
9
10 ifstream f("inventie.in");
11 ofstream g("inventie.out");
12
13 f>>n;
14 for (i=1; i<=n; i++)
15 {
16 f>>a>>b;
17 if (a==b) nr=a+b;
18 else
19 {
20 if (a>b) dif=a-b;
21 else dif=b-a;
22 s=a+b;
23 p=1;
24 while (s)
25 {
26 s=s/10;
27 p=p*10;
28 }
29 nr=dif*p+a+b;
30 }
31 g<<nr<<’\n’;
32 if (a%2!=b%2)
33 {
34 gasit=1;
35 vmin=vmax=nr;
36 break;
37 }
38 }
39 i++;
40 while (i<=n)
CAPITOLUL 17. ONI 2015 239

41 {
42 f>>a>>b; //g<<" am citit "<<a<<’ ’<<b<<"la pasul "<<i<<’\n’;
43 if (a==b) nr=a+b;
44 else
45 {
46 if (a>b) dif=a-b;
47 else dif=b-a;
48 s=a+b;
49 p=1;
50 while (s)
51 {
52 s=s/10;
53 p=p*10;
54 }
55 nr=dif*p+a+b;
56 }
57 g<<nr<<’\n’;
58 if (a%2!=b%2)
59 {
60 if (vmin>nr) vmin=nr;
61 if (vmax<nr) vmax=nr;
62 }
63
64 i++;
65 }
66 if (gasit==0) g<<0<<’\n’;
67 else
68 g<<vmin<<’\n’<<vmax<<’\n’;
69 return 0;
70 }

17.2.3 *Rezolvare detaliat 

17.3 mesaj
Problema 3 - mesaj 100 de puncte
În µara lui Piticot cuvintele au doar dou  litere, prima ind o majuscul  (liter  mare) iar a
doua o minuscul  (liter  mic ). Piticii Mi ³i Gi se distreaz  ³i î³i trimit mesaje ascunzând cuvintele
în cadrul unor secvenµe transmise sub forma unor ³iruri de litere.
Piticul Mi scrie ³i trimite un mesaj piticului Gi respectând urm -
toarele reguli:
a un mesaj conµine una sau mai multe secvenµe;
a orice liter  care apare în mesaj, de cel puµin dou  ori, pe poziµii
al turate, este numit  terminator;
a o secvenµ  se încheie când s-a întâlnit o succesiune de litere ter-
minator;
a cuvântul este format din prima majuscul  ³i ultima minuscul  din
secvenµ , f r  a lua în seam  litera terminator a secvenµei; Figura 17.1: mesaj

a o secvenµ  ascunde un cuvânt dac  terminatorul s u se repet  de exact dou  ori ³i dac 
conµine cel puµin o liter  mare ³i o liter  mic , ignorând terminatorul de secvenµ ;
a costul unui cuvânt este egal cu num rul total de apariµii al celor dou  litere din care este
format, în cadrul secvenµei în care a fost ascuns, luând în considerare inclusiv literele terminator.
De exemplu secvenµa s f u E e t R u E E ascunde un cuvânt deoarece conµine ³i majuscule
³i minuscule, iar litera terminator de secvenµ , E, se repet  de exact dou  ori. Secvenµa ascunde
cuvântul Eu, iar costul cuvântului este 5 (3 litere E + 2 dou  litere u).
La primirea mesajului, piticul Gi determin , pentru ecare majuscul , costul maxim al cuvin-
telor care încep cu aceasta.

Cerinµe
Scrieµi un program care determin :
1) num rul de secvenµe trimise care nu ascund cuvinte;
2) cuvintele din mesaj, în ordinea în care au fost trimise de piticul Mi;
3) pentru ecare majuscul , câte cuvinte care încep cu ea au costul maxim determinat de Gi.
CAPITOLUL 17. ONI 2015 240

Date de intrare
Fi³ierul de intrare mesaj.in conµine pe prima linie un num r natural P . Pentru toate testele
de intrare, num rul P poate avea numai una dintre valorile 1, 2 3.
sau
Pe a doua linie a ³ierului de intrare se g se³te num rul natural N reprezentând num rul de
litere folosite de Mi pentru scrierea mesajului.
Pe a treia linie se g sesc N litere mari ³i mici ale alfabetului englez, separate prin câte un
spaµiu, reprezentând literele mesajului, în ordinea în care au fost trimise.

Date de ie³ire
Dac  valoarea lui P este 1, se va rezolva numai punctul 1) din cerinµe. În acest caz, ³ierul de
ie³ire mesaj.out va conµine pe prima linie un num r natural reprezentând r spunsul la cerinµa
1).
Dac  valoarea lui P este 2, se va rezolva numai punctul 2) din cerinµe. În acest caz, ³ierul de
ie³ire mesaj.out va conµine cuvintele din mesaj, ecare cuvânt scris pe câte o linie, în ordinea în
care au fost trimise.
Dac  valoarea lui P este 3, se va rezolva numai punctul 3) din cerinµe. În acest caz, ³ierul de
ie³ire mesaj.out va conµine pe ecare linie câte o majuscul  urmat  de un num r natural nenul,
separate printr-un spaµiu. Majusculele vor  a³ate în ordine de la A la Z, îns  doar cele pentru
care au existat în mesaj cuvinte care au început cu ele.

Restricµii ³i preciz ri
a 1&N & 2000000
a litera terminator a unei secvenµe poate  ori minuscul  ori majuscul ;
a ultimele litere din ³ier sunt literele terminator ale ultimei secvenµe din mesajul trimis;
a se garanteaz  c  în ³irul de litere din ³ierul de intrare se a  ascuns cel puµin un cuvânt;
a majusculele alfabetului englez sunt A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S,
T, U, V, W, X, Y, Z;
a pentru 50% din teste N & 1000000
a Pentru rezolvarea cerinµei 1) se acord  20 de puncte, pentru rezolvarea cerinµei 2) se acord 
40 de puncte, iar pentru rezolvarea cerinµei 3) se acord  40 de puncte.

Exemple:
mesaj.in mesaj.out
1 4
34
w w w w e D o r F D o r r t R n e R e y y j j i M o e i t t t j w w

Explicaµie:
Textul conµine ³ase secvenµe: Sunt 4 secvenµe care nu ascund cuvinte:
1) w w w w a prima secvenµ  ³i a patra deoarece conµin numai
2) e D o r F D o r r terminatorul;
3) t R n e R e y y a secvenµa a cincea nu se decodic  deoarece termi-
4) j j natorul se repet  de mai mult de dou  ori;
5) i M o e i t t t a secvenµa a ³asea nu conµine majuscule.
6) j w w

mesaj.in mesaj.out
2 Nu
34 Do
u N a a e D o r F D o r r t R n e R e y y j j i M o e i t t t j w w Re

Explicaµie:
Textul conµine ³ase secvenµe: Prima secvenµ  are terminatorul a care se repet  de
1) u N a a dou  ori ³i ascunde cuvântul Nu
2) e D o r F D o r r A doua secvenµ  are terminatorul r ³i ascunde cu-
3) t R n e R e y y vântul Do.
4) j j A treia are terminatorul y ³i ascunde cuvântul Re.
5) i M o e i t t t Ultimele trei secvenµe nu ascund cuvinte.
6) j w w
CAPITOLUL 17. ONI 2015 241

mesaj.in mesaj.out
3 A 2
24 B 1
A a t t B b B t t e A e a n n B w I I F i e F F F 1

Explicaµie:
Textul conµine cinci secvenµe: Cuvintele transmise în mesaj sunt
1) A a t t Aa (cost 2)
2) B b B t t Bb (cost 3)
3) e A e a n n Aa (cost 2)
4) B w I I Bw (cost 2)
5) F i e F F Fe (cost 4)
Costul maxim al cuvintelor care încep cu A este 2 ³i
au fost 2 cuvinte transmise.
Pentru litera B s-a transmis un singur cuvânt de cost
maxim 3.
Pentru litera F s-a transmis un singur cuvânt de cost
maxim 4.

Timp maxim de executare/test: 1.5 secunde


Memorie: total 1 MB din care pentru stiv  1 MB
Dimensiune maxim  a sursei: 10 KB

17.3.1 Indicaµii de rezolvare


Problema poate  rezolvat  citind caracter cu caracter ³i memorând doar ultimele dou  litere
citite.
Pe parcursul citiri se reµine num rul apariµiilor consecutive al unui caracter. în funcµie de
acesta se identic  ecare secvenµ . în cadrul secvenµei curente se actualizeaz :
a cele dou  litere ale posibilului cuvânt ascuns în secvenµ  curent ,
a num rul de apariµii al ec rei minuscule ale alfabetului englez (se folose³te un vector de
frecvenµ )
a num rul de apariµii al primei majuscule întâlnite în cadrul secvenµei curente

La nalul unei secvenµe se actualizeaz  dac  este cazul, costul maxim al unui cuvânt care
începe cu majuscula din cuvântului determinat la pasul curent.
Dac  se opteaz  pentru preluarea literelor într-un vector de 1 milion de caractere, se vor obµine
50 de puncte.

17.3.2 Cod surs 

Listing 17.3.1: mesaj_1.c

1 #include <stdio.h>
2 #include <ctype.h>
3
4 int l=1, nr=0, nLw=0, N,fL[27],fC[27], nM, Cost, CostMax[27],P, Nrsecv, i;
5 char c, x , y, z, first, last, s;
6
7 int main()
8 {
9 freopen("mesaj.in", "r",stdin);
10 freopen("mesaj.out","w",stdout);
11
12 scanf("%d\n",&P);
13 scanf("%d\n%c%c",&N, &x, &s);
14
15 if(islower(x)) fL[x-’a’]++;
16
17 l=1;
18 first=last=’#’;
19 while(s!=’\n’)
20 {
21 scanf("%c%c", &y, &s);
CAPITOLUL 17. ONI 2015 242

22 if(islower(y)) fL[y-’a’]++;
23
24 while (x!=y && s!=’\n’)
25 {
26 if(islower(x)) last=x;
27 else
28 if(first==’#’) {first=x; nM=1;}
29 else
30 if(first==x) nM++;
31
32 x=y;
33 scanf("%c%c", &y, &s);
34 if(islower(y)) fL[y-’a’]++;
35 if(s==’\n’) break;
36 }
37
38 if (x==y) l=2;
39 while (x==y && s!=’\n’)
40 {
41 scanf("%c%c", &y, &s);
42 if(islower(y)) fL[y-’a’]++;
43 if(x==y) l++;
44 if(s==’\n’) break;
45 }
46
47 if(first==x) nM+=l;
48 if(l==2 && first!=’#’ && last!=’#’)
49 {
50 if(P==2) printf("%c%c\n",first,last);
51 Cost=nM + fL[last-’a’];
52 if(last==y)Cost--;
53 if(Cost==CostMax[first-’A’]) fC[first-’A’]++;
54 if(Cost>CostMax[first-’A’])
55 {
56 fC[first-’A’]=1;
57 CostMax[first-’A’]=Cost;
58 }
59 }
60 else Nrsecv++;
61
62 x=y;
63 l=1;
64 first=last=’#’;
65 nM=0;
66 for(i=0;i<27;i++) fL[i]=0;
67 Cost=0;
68 if(islower(x)) fL[x-’a’]++;
69 }
70
71 if(P==1)printf("%d\n", Nrsecv);
72 if(P==3)
73 for(i=0;i<26;i++)
74 if(fC[i]) printf("%c %d\n", (char)(’A’+i), fC[i]);
75
76 return 0;
77 }

Listing 17.3.2: mesaj_2.cpp

1 #include <cstdio>
2 #include <cctype>
3 #include <cassert>
4
5 using namespace std;
6
7 int l=1, nr=0, nLw=0, N,fL[27],fC[27], nM, Cost, CostMax[27],P, Nrsecv, i;
8 char c, x , y, z, first, last, s;
9
10 int main()
11 {
12 freopen("mesaj.in", "r",stdin);
13 freopen("mesaj.out","w",stdout);
14
15 scanf("%d\n",&P);
16 scanf("%d\n%c%c",&N, &x, &s);
CAPITOLUL 17. ONI 2015 243

17
18 if(islower(x)) fL[x-’a’]++;
19 l=1;
20 first=last=’#’;
21 while(s!=’\n’)
22 {
23 scanf("%c%c", &y, &s);
24 if(islower(y)) fL[y-’a’]++;
25 while (x!=y && s!=’\n’)
26 {
27 if(islower(x)) last=x;
28 else
29 if(first==’#’) {first=x; nM=1;}
30 else if(first==x) nM++;
31 x=y;
32 scanf("%c%c", &y, &s);
33 if(islower(y)) fL[y-’a’]++;
34 if(s==’\n’) break;
35 }
36
37 if (x==y) l=2;
38 while (x==y && s!=’\n’)
39 {
40 scanf("%c%c", &y, &s);
41 if(islower(y)) fL[y-’a’]++;
42 if(x==y) l++;
43 if(s==’\n’) break;
44 }
45
46 if(first==x) nM+=l;
47 if(l==2 && first!=’#’ && last!=’#’)
48 {
49 if(P==2) printf("%c%c\n",first,last);
50 Cost=nM + fL[last-’a’];
51 if(last==y)Cost--;
52 if(Cost==CostMax[first-’A’]) fC[first-’A’]++;
53 if(Cost>CostMax[first-’A’])
54 {
55 fC[first-’A’]=1;
56 CostMax[first-’A’]=Cost;
57 }
58 }
59 else Nrsecv++;
60
61 x=y;
62 l=1;
63 first=last=’#’;
64 nM=0;
65 for(int i=0;i<27;i++)fL[i]=0;
66 Cost=0;
67 if(islower(x)) fL[x-’a’]++;
68 }
69
70 if(P==1)printf("%d\n", Nrsecv);
71 if(P==3)
72 for(i=0;i<26;i++)
73 if(fC[i]) printf("%c %d\n", (char)(’A’+i), fC[i]);
74
75 return 0;
76 }

Listing 17.3.3: mesaj_3.cpp

1 #include <fstream>
2 #include <cctype>
3
4 using namespace std;
5
6 ifstream in("mesaj.in");
7 ofstream out("mesaj.out");
8
9 int majCounts[256];
10 int minCounts[256];
11 int maxCost[256];
12 int maxCostCounts[256];
CAPITOLUL 17. ONI 2015 244

13
14 int main()
15 {
16 int P;
17 in >> P;
18
19 int N;
20 in >> N;
21
22 int numSecvente = 0;
23 int numSecventeCuCuvinte = 0;
24
25 char ch = ’#’;
26 int countCh = 1;
27
28 char majCh = ’#’;
29 char minCh = ’#’;
30
31 for (int i = 0; i <= N; ++ i)
32 {
33 char peekCh;
34 if (i < N)
35 {
36 in >> peekCh;
37 }
38 else
39 {
40 peekCh = ’#’;
41 }
42
43 if (ch == peekCh)
44 {
45 countCh ++;
46 }
47 else
48 {
49 switch (countCh)
50 {
51 case 1:
52 switch (P)
53 {
54 case 1:
55 if (isupper(ch) && majCh == ’#’) majCh = ch;
56 if (islower(ch)) minCh = ch;
57 break;
58 case 2:
59 if (isupper(ch) && majCh == ’#’) majCh = ch;
60 if (islower(ch)) minCh = ch;
61 break;
62 case 3:
63 if (isupper(ch) && majCh == ’#’) majCh = ch;
64 if (islower(ch)) minCh = ch;
65
66 if (isupper(ch)) majCounts[ch] ++;
67 if (islower(ch)) minCounts[ch] ++;
68 break;
69 }
70 break;
71
72 case 2:
73 switch(P)
74 {
75 case 1:
76 numSecvente ++;
77 if (majCh != ’#’ && minCh != ’#’)
78 numSecventeCuCuvinte ++;
79
80 majCh = minCh = ’#’;
81 break;
82 case 2:
83 if (majCh != ’#’ && minCh != ’#’)
84 {
85 out << majCh << minCh << ’\n’;
86 }
87
88 majCh = minCh = ’#’;
CAPITOLUL 17. ONI 2015 245

89 break;
90 case 3:
91 if (isupper(ch)) majCounts[ch] += 2;
92 if (islower(ch)) minCounts[ch] += 2;
93
94 if (majCh != ’#’ && minCh != ’#’)
95 {
96 int cost = majCounts[majCh]+minCounts[minCh];
97 if (cost > maxCost[majCh])
98 {
99 maxCost[majCh] = cost;
100 maxCostCounts[majCh] = 1;
101 }
102 else
103 if (cost == maxCost[majCh])
104 {
105 maxCostCounts[majCh] ++;
106 }
107 }
108
109 majCh = minCh = ’#’;
110 for(int ii=0; ii<256;ii++) majCounts[ii]=0;
111 for(int ii=0; ii<256;ii++) minCounts[ii]=0;
112 break;
113 }
114 break;
115
116 default:
117 switch (P)
118 {
119 case 1:
120 numSecvente ++;
121
122 majCh = minCh = ’#’;
123 break;
124 case 2:
125 majCh = minCh = ’#’;
126 break;
127 case 3:
128 majCh = minCh = ’#’;
129 for(int ii=0; ii<256;ii++) majCounts[ii]=0;
130 for(int ii=0; ii<256;ii++) minCounts[ii]=0;
131 break;
132 }
133 }
134
135 countCh = 1;
136 ch = peekCh;
137 }
138 }
139
140 switch(P)
141 {
142 case 1:
143 out << numSecvente - numSecventeCuCuvinte << ’\n’;
144 break;
145 case 3:
146 for (char ch = ’A’; ch != ’Z’; ++ ch)
147 {
148 if (maxCost[ch])
149 {
150 out << ch << ’ ’ << maxCostCounts[ch] << ’\n’;
151 }
152 }
153 break;
154 }
155
156 return 0;
157 }

Listing 17.3.4: mesaj_4.cpp

1 #include<fstream>
2 #include<iostream>
3
CAPITOLUL 17. ONI 2015 246

4 using namespace std;


5
6 char pr[500000];
7 char ul[500000];
8
9 int main()
10 {
11 ifstream f("mesaj.in");
12 ofstream g("mesaj.out");
13
14 int n,t=0,nrlitmici=0, nrlitmari=0,i=1,nr=0,kp=0,ns=0,j,p;
15 char c,u,prima, ultima;
16
17 int nrmari[28]= {0};
18 int nrmici[28]= {0};
19 int costmax [28]= {0};
20 int cate[28]= {0};
21
22 f>>p>>n;
23 f>>c;
24 while (i<=n-1)
25 {
26 for (j=0; j<=27; j++) nrmici[j]=nrmari[j]=0;
27 u=c;
28 if (u>=’a’ && u<=’z’) nrmici[u-’a’]++;
29 else nrmari[u-’A’]++;
30 f>>c;
31 i++;
32 while (c!=u&&i<=n)
33 {
34 if (c>=’a’ && c<=’z’) nrmici[c-’a’]++;
35 else nrmari[c-’A’]++;
36
37 if (u>=’a’&&u<=’z’)
38 {
39 nrlitmici++;
40 ultima=u;
41 }
42 else
43 {
44 nrlitmari++;
45 if (nrlitmari==1) prima=u;
46 }
47
48 if (i==n)
49 {
50 i++;
51 break;
52 }
53 u=c;
54 f>>c;
55 i++;
56 }
57
58 while (c==u&&i<=n)
59 {
60 if (c>=’a’ && c<=’z’) nrmici[c-’a’]++;
61 else nrmari[c-’A’]++;
62
63 nr++;
64 if (i==n)
65 {
66 i++;
67 break;
68 }
69 f>>c;
70 i++;
71 }
72
73 if (nr==1 && nrlitmici>0 && nrlitmari>0)
74 {
75 pr[kp]=prima;
76 ul[kp]=ultima;
77 kp++;
78 if (costmax[prima-’A’]<nrmari[prima-’A’]+nrmici[ultima-’a’])
79 {
CAPITOLUL 17. ONI 2015 247

80 costmax[prima-’A’]=nrmari[prima-’A’]+nrmici[ultima-’a’];
81 cate[prima-’A’]=1;
82 }
83 else
84 if (costmax[prima-’A’]==nrmari[prima-’A’]+nrmici[ultima-’a’])
85 cate[prima-’A’]++;
86 }
87 else { ns++;}
88
89 nr=0;
90 nrlitmici=0;
91 nrlitmari=0;
92 }
93
94 if (p==2)
95 for(i=0; i<kp; i++) g<<pr[i]<<ul[i]<<’\n’;
96 else
97 if (p==1)
98 g<<ns<<’\n’;
99 else
100 for (c=’A’; c<=’Z’; c++)
101 if (costmax[c-’A’]>0) g<<c<<’ ’<<cate[c-’A’]<<’\n’;
102
103 return 0;
104 }

Listing 17.3.5: mesaj_5.cpp

1 #include <iostream>
2 #include <fstream>
3
4 using namespace std;
5
6 ifstream in("mesaj.in");
7 ofstream out("mesaj.out");
8
9 char prim[100000],ultim[100000];
10 int lmici[28],lmari[28],cost[28]={0};
11
12 int main()
13 {
14 char x,y;
15 int i,j,P,N,nrsv=0,sw=1,nrt=0,nrs=0,cost=0,cost_max[28]={0},nrc[28]={0};
16 char prima_M=’*’,ultima_m=’*’;
17
18 in>>P;
19 in>>N;
20 in>>x;
21 i=1;
22
23 while(i<=N)
24 {
25 for(j=0;j<=28;j++)
26 lmari[j]=lmici[j]=0;
27
28 if(’a’<=x && x<=’z’)
29 lmici[x-’a’]++;
30 else
31 lmari[x-’A’]++;
32
33 in>>y;
34 i++;
35 while(x!=y && i<=N)
36 {
37 if(’a’<=x && x<=’z’)
38 ultima_m=x;
39 else
40 if(sw)
41 prima_M=x,sw=0;
42
43 if(’a’<=y && y<=’z’)
44 lmici[y-’a’]++;
45 else
46 lmari[y-’A’]++;
47
CAPITOLUL 17. ONI 2015 248

48 x=y;
49 in>>y; i++;
50 }
51
52 nrt=1;
53 while(x==y && i<=N)
54 {
55 nrt++;
56 if(’a’<=y && y<=’z’)
57 lmici[y-’a’]++;
58 else
59 lmari[x-’A’]++;
60 x=y;
61 in>>y;
62 i++;
63 }
64
65 if(P==2 && nrt==2 && prima_M!=’*’ && ultima_m!=’*’)
66 out<<prima_M<<ultima_m<<’\n’;
67 if(nrt>=2)
68 {
69 if(nrt==2 && (prima_M==’*’ || ultima_m==’*’))
70 nrsv++;
71 if(nrt==2 && (prima_M!=’*’ || ultima_m!=’*’))
72 {
73 cost=lmari[prima_M-’A’]+lmici[ultima_m-’a’];
74 if(cost>cost_max[prima_M-’A’])
75 cost_max[prima_M-’A’]=cost, nrc[prima_M-’A’]=1;
76 else
77 if(cost==cost_max[prima_M-’A’])
78 nrc[prima_M-’A’]++;
79 }
80 if(nrt>2)
81 nrsv++;
82 nrt=0;
83 sw=1;
84 prima_M=ultima_m=’*’;
85 }
86 x=y;
87 }
88
89 if(P==1 && i>N)
90 out<<nrsv;
91 else
92 if(P==3)
93 for(j=0;j<=27;j++)
94 if(cost_max[j]!=0)
95 out<<(char)(’A’+j)<<’ ’<<nrc[j]<<’\n’;
96
97 in.close();
98 out.close();
99 return 0;
100 }

Listing 17.3.6: mesaj_6.cpp

1 #include <fstream>
2 #include <cstring>
3 #include <cctype>
4
5 using namespace std;
6
7 ifstream in("mesaj.in");
8 ofstream out("mesaj.out");
9
10 int majCounts[256];
11 int minCounts[256];
12 int maxCost[256];
13 int maxCostCounts[256];
14
15 int main()
16 {
17 int P;
18 in >> P;
19
CAPITOLUL 17. ONI 2015 249

20 int N;
21 in >> N;
22
23 int numSecvente = 0;
24 int numSecventeCuCuvinte = 0;
25
26 char ch = ’#’;
27 int countCh = 1;
28
29 char majCh = ’#’;
30 char minCh = ’#’;
31
32 for (int i = 0; i <= N; ++ i)
33 {
34 char peekCh;
35 if (i < N)
36 {
37 in >> peekCh;
38 }
39 else
40 {
41 peekCh = ’#’;
42 }
43
44 if (ch == peekCh)
45 {
46 countCh ++;
47 }
48 else
49 {
50 switch (countCh)
51 {
52 case 1:
53 switch (P)
54 {
55 case 1:
56 if (isupper(ch) && majCh == ’#’) majCh = ch;
57 if (islower(ch)) minCh = ch;
58 break;
59 case 2:
60 if (isupper(ch) && majCh == ’#’) majCh = ch;
61 if (islower(ch)) minCh = ch;
62 break;
63 case 3:
64 if (isupper(ch) && majCh == ’#’) majCh = ch;
65 if (islower(ch)) minCh = ch;
66
67 if (isupper(ch)) majCounts[ch] ++;
68 if (islower(ch)) minCounts[ch] ++;
69 break;
70 }
71 break;
72
73 case 2:
74 switch(P)
75 {
76 case 1:
77 numSecvente ++;
78 if (majCh != ’#’ && minCh != ’#’)
79 numSecventeCuCuvinte ++;
80
81 majCh = minCh = ’#’;
82 break;
83 case 2:
84 if (majCh != ’#’ && minCh != ’#’)
85 {
86 out << majCh << minCh << ’\n’;
87 }
88
89 majCh = minCh = ’#’;
90 break;
91 case 3:
92 if (isupper(ch)) majCounts[ch] += 2;
93 if (islower(ch)) minCounts[ch] += 2;
94
95 if (majCh != ’#’ && minCh != ’#’)
CAPITOLUL 17. ONI 2015 250

96 {
97 int cost = majCounts[majCh]+minCounts[minCh];
98 if (cost > maxCost[majCh])
99 {
100 maxCost[majCh] = cost;
101 maxCostCounts[majCh] = 1;
102 }
103 else
104 if (cost == maxCost[majCh])
105 {
106 maxCostCounts[majCh] ++;
107 }
108 }
109
110 majCh = minCh = ’#’;
111 memset(majCounts, 0, sizeof(majCounts));
112 memset(minCounts, 0, sizeof(minCounts));
113 break;
114 }
115 break;
116
117 default:
118 switch (P)
119 {
120 case 1:
121 numSecvente ++;
122
123 majCh = minCh = ’#’;
124 break;
125 case 2:
126 majCh = minCh = ’#’;
127 break;
128 case 3:
129 majCh = minCh = ’#’;
130 memset(majCounts, 0, sizeof(majCounts));
131 memset(minCounts, 0, sizeof(minCounts));
132 break;
133 }
134 }
135
136 countCh = 1;
137 ch = peekCh;
138 }
139 }
140
141 switch(P)
142 {
143 case 1:
144 out << numSecvente - numSecventeCuCuvinte << ’\n’;
145 break;
146 case 3:
147 for (char ch = ’A’; ch != ’Z’; ++ ch)
148 {
149 if (maxCost[ch])
150 {
151 out << ch << ’ ’ << maxCostCounts[ch] << ’\n’;
152 }
153 }
154 break;
155 }
156
157 return 0;
158 }

Listing 17.3.7: mesaj_7.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("mesaj.in");
6 ofstream g("mesaj.out");
7
8 char s[1000001],minu,maju;
9 int N,P,nr;//nr=nr de repetari ale unei litere
CAPITOLUL 17. ONI 2015 251

10 int nrs,nrsl;//nrs=nr secvente; nrsl=nr secvente ce contin cuvinte


11 int cost, cmax[26],nrap[26];
12
13 int main()
14 {
15 //citire
16 int i;
17 f>>P>>N;
18 for(i=1;i<=N;i++)f>>s[i];
19
20 //1)numarare secvente si secvente ce contin cuvinte
21 if(P==1)
22 {
23 maju=minu=’ ’;
24 if(s[1]>=’A’ && s[1]<=’Z’ && s[1]!=s[2] && maju==’ ’)maju=s[1];
25 else
26 if(s[1]>=’a’ && s[1]<=’z’ && s[1]!=s[2])minu=s[1];
27
28 for(i=2;i<=N;)
29 {
30 if(s[i]!=s[i-1])
31 {
32 if(s[i]>=’A’ && s[i]<=’Z’ && s[i]!=s[i+1] && maju==’ ’)
33 maju=s[i];
34 else
35 if(s[i]>=’a’ && s[i]<=’z’ && s[i]!=s[i+1])
36 minu=s[i];
37 i++;
38 }
39 else
40 {
41 //se termina o secventa
42 nrs++;
43 nr=0;
44 while(s[i]==s[i-1] && i<=N)
45 {
46 i++;
47 nr++;
48 }
49 if(maju!=’ ’ && minu!=’ ’ && nr==1)
50 nrsl++;
51 maju=minu=’ ’;
52 }
53 }
54 g<<nrs-nrsl<<’\n’;
55 }
56
57 //2)afisare cuvinte
58 if(P==2)
59 {
60 maju=minu=’ ’;
61 if(s[1]>=’A’ && s[1]<=’Z’ && s[1]!=s[2] && maju==’ ’)
62 maju=s[1];
63 else
64 if(s[1]>=’a’ && s[1]<=’z’ && s[1]!=s[2])
65 minu=s[1];
66
67 for(i=2;i<=N;)
68 {
69 if(s[i]!=s[i-1])
70 {
71 if(s[i]>=’A’ && s[i]<=’Z’ && s[i]!=s[i+1] && maju==’ ’)
72 maju=s[i];
73 else
74 if(s[i]>=’a’ && s[i]<=’z’ && s[i]!=s[i+1])
75 minu=s[i];
76 i++;
77 }
78 else
79 {
80 //se termina o secventa
81 nrs++;nr=0;while(s[i]==s[i-1] && i<=N){i++;nr++;}
82 if(maju!=’ ’ && minu!=’ ’ && nr==1)g<<maju<<minu<<’\n’;
83 maju=minu=’ ’;
84 }
85 }
CAPITOLUL 17. ONI 2015 252

86 }
87
88 //3)afisare cuvinte
89 if(P==3)
90 {
91 int j=1,k;
92 maju=minu=’ ’;
93 if(s[1]>=’A’ && s[1]<=’Z’ && s[1]!=s[2] && maju==’ ’)
94 maju=s[1];
95 else
96 if(s[1]>=’a’ && s[1]<=’z’ && s[1]!=s[2])
97 minu=s[1];
98
99 for(i=2;i<=N;)
100 {
101 if(s[i]!=s[i-1])
102 {
103 if(s[i]>=’A’ && s[i]<=’Z’ && s[i]!=s[i+1] && maju==’ ’)
104 maju=s[i];
105 else
106 if(s[i]>=’a’ && s[i]<=’z’ && s[i]!=s[i+1])
107 minu=s[i];
108 i++;
109 }
110 else
111 {
112 //se termina o secventa
113 nrs++;
114 cost=0;
115 nr=0;
116 while(s[i]==s[i-1] && i<=N){i++; nr++;}
117 if(maju!=’ ’ && minu!=’ ’ && nr==1)
118 {
119 for(k=j;k<=i-1;k++)
120 if(s[k]==maju)cost++;
121 else
122 if(s[k]==minu)cost++;
123
124 if(cost>cmax[maju-’A’])
125 {
126 cmax[maju-’A’]=cost;
127 nrap[maju-’A’]=1;
128 }
129 else
130 if(cost==cmax[maju-’A’])
131 {
132 nrap[maju-’A’]++;
133 }
134 }
135 maju=minu=’ ’;j=i;
136 }
137 }
138
139 for(i=0;i<26;i++)
140 if(cmax[i]>0) g<<(char)(i+’A’)<<’ ’<<nrap[i]<<’\n’;
141 }
142 f.close();g.close();return 0;
143 }

17.3.3 *Rezolvare detaliat 


Capitolul 18

ONI 2014

18.1 2048
Problema 1 - 2048 100 de puncte
Ada ³i Ben sunt pasionaµi de jocurile pe calculator ³i tocmai au descoperit cea mai recent 
versiune a jocului 2048.
Regulile jocului sunt foarte simple:

a se porne³te de la un ³ir de N piese pe care sunt


înscrise numere din mulµimea { 2, 4, 8, 16, 32, 64, 128,
256, 512, 1024, 2048 };

a piesele sunt a³ezate în locaµii numerotate consecu-


tiv cu numerele 1, 2, ..., N;
a la ecare pas, poate avea loc o MUTARE la
STÂNGA sau o MUTARE la DREAPTA;

a pentru ecare joc este stabilit un num r maxim de


mut ri M;
a dac  are loc o MUTARE la DREAPTA, atunci:

- piesele pot fuziona la dreapta, începând cu penul-


tima pies  din ³ir: dac  o pies  se a  pe o poziµie i ³i
are înscris  valoarea k, iar pe poziµia i1 se a  o pies 
Figura 18.1: 2048
cu aceea³i valoare k , atunci aceste piese vor fuziona, pe
poziµia i1 se va obµine o pies  cu valoarea 2k , iar pe poziµia i r mâne o locaµie liber ;
- dup  efectuarea fuzion rilor, piesele se aliniaz  la dreapta, astfel încât ultima pies  s  se ae
pe poziµia n;
a dac  are loc o MUTARE la STâNGA, atunci:

- piesele pot fuziona la stânga, începând cu a doua pies  din ³ir: dac  o pies  se a  pe o
poziµie i ³i are înscris  valoarea k, iar pe poziµia i1 se a  o pies  cu aceea³i valoare k, atunci
aceste piese vor fuziona, pe poziµia i1 se va obµine o pies  cu valoarea 2k , iar pe poziµia i
r mâne o locaµie liber ;
- dup  efectuarea fuzion rilor, piesele se aliniaz  la stânga, astfel încât prima pies  s  se ae
pe poziµia 1;
a jocul se încheie atunci când se ajunge în una dintre urm toarele situaµii:

- pe cel puµin una dintre piese se a  înscris  valoarea 2048;


- valorile înscrise nu se mai pot modica prin mutarea pieselor;
- s-au efectuat toate cele M mut ri.

Cerinµe
Scrieµi un program care s  citeasc  numerele naturale N (num rul iniµial de piese) ³i M
(num rul maxim de mut ri), un ³ir de N numere reprezentând, în ordine, numerele înscrise pe
cele N piese ³i cel mult M caractere din mulµimea rS, D x ce reprezint  mut rile xate de c tre
Ada ³i Ben, ³i care determin :

253
CAPITOLUL 18. ONI 2014 254

a) num rul X de mut ri efectuate pân  la încheierea jocului;


b) num rul maxim Y inscris pe una dintre piese la încheierea jocului;
c) num rul maxim Z de fuzion ri efectuate la o mutare.

Date de intrare
Fi³ierul de intrare 2048.in conµine pe prima linie, separate prin câte un spaµiu, numerele N
³i M. A doua linie a ³ierului conµine cele N numere inscrise, în ordine, pe piese, separate prin
câte un spaµiu. A treia linie a ³ierului conµine cele M caractere, separate prin câte un spaµiu, ce
reprezint  cele M direcµii de mutare.

Date de ie³ire
Fi³ierul de ie³ire 2048.out va conµine pe prima linie num rul X , pe a doua linie num rul Y
³i pe a treia linie num rul Z.

Restricµii ³i preciz ri
- 2 & N, M & 10000;
- caracterul D indic  o mutare la dreapta, iar caracterul S indic  o mutare la stânga;
- pentru rezolvarea cerinµei a) se acord  40% din punctaj, pentru cerinµa b) 40% din punctaj
³i pentru cerinµa c) 20% din punctaj.

Exemple
2048.in 2048.out Explicaµii
7 10 4 Succesiunea de mut ri este reprezentat  în gura 1.
16 4 4 2 2 4 8 32 Au fost efectuate 4 mut ri pân  la încheierea jocului, cea
D D S D S D S S D D 2 mai mare valoare inscris  pe una dintre piese ind 32.
Num rul maxim de fuzion ri, dou , a fost obµinut la prima
mutare.

Timp maxim de executare/test: 0.5 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 5 KB

18.1.1 Indicaµii de rezolvare


Se memoreaz  ³irul de numere în tabloul unidimensional a de lungime n.
Se memoreaz  în dou  variabile st ³i dr poziµiile de început ³i de sfâr³it ale secvenµei de piese
r mase în tablou.
Se cite³te, pe rând, câte o mutare, se parcurge tabloul a în sensul mut rii (de la st la dr sau
invers) ³i se efectueaz  toate fuzion rile posibile, contorizându-se num rul acestora.
La încheierea jocului se determin  valoarea maxim  care se a  în tablou în intervalul
ast, adr .

18.1.2 Cod surs 

Listing 18.1.1: 2048.cpp

1 //Cristina Sichim, C.N. Ferdinand I Bacau


2 #include <fstream>
3
4 using namespace std;
5
6 ifstream f("2048.in");
7 ofstream g("2048.out");
8
9 int v[10001],n,m,i,j,k,st,dr,p,X,Y,Z,z,s;
10 char d;
11
12 int main()
13 {
14 f>>n>>m;
15 for(i=1;i<=n;++i){f>>v[i]; if(v[i]==2048) s=1;}
CAPITOLUL 18. ONI 2014 255

16
17 st=1;dr=n;
18 for(i=1;i<=m && !s;i++)
19 { f>>d;
20 z=0;
21 if(d==’D’)
22 {for(j=dr;j>st;j--)
23 if(v[j]==v[j-1]) {v[j]*=2;
24 if(v[j]==2048) s=1;
25 for(k=j-1;k>st;k--)v[k]=v[k-1];
26 st++;
27 z++;
28 }
29 }
30 else
31 { for(j=st;j<dr;j++)
32 if(v[j]==v[j+1]){ v[j]*=2;
33 if(v[j]==2048) s=1;
34 for(k=j+1;k<dr;k++)v[k]=v[k+1];
35 dr--;
36 z++;
37 }
38 }
39 X=i;
40 if(z==0) X=i-1,i=m;
41 Z=max(Z,z);
42 if(s)i=m;
43 }
44
45 Y=v[st];
46 for(i=st+1;i<=dr;i++) Y=max(Y,v[i]);
47 g<<X<<’\n’<<Y<<’\n’<<Z<<’\n’;
48 f.close();g.close();
49
50 return 0;
51 }

Listing 18.1.2: 2048A.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("2048.in");
6 ofstream g("2048.out");
7
8 int p[10001],n,m,k,i,ii,nrfuz,x,y,z,j,in,sf,mutat,gata,P;
9 char d,ud;
10
11 int main()
12 {
13 //citire
14 f>>n>>m;
15
16 for(i=1;i<=n;i++){f>>p[i];if(p[i]==2048){gata=1;y=2048;}}
17
18 in=1;sf=n;
19 for(i=1;i<=m && !gata;i++)
20 {
21 f>>d;nrfuz=0;mutat=0;
22 if(d==’D’)
23 {for(j=sf;j>in;j--)
24 if(p[j]==p[j-1])
25 {
26 nrfuz++;mutat=1;if(P>=in && P<=j-1)P++;
27 p[j]*=2;
28 for(k=j-1;k>in;k--)p[k]=p[k-1];
29 in++;
30 }
31 }
32 else
33 {for(j=in;j<sf;j++)
34 if(p[j]==p[j+1])
35 {
36 nrfuz++;mutat=1;if(P<=sf && P>=j+1)P--;
CAPITOLUL 18. ONI 2014 256

37 p[j]*=2;
38 for(k=j+1;k<sf;k++)p[k]=p[k+1];
39 sf--;
40 }
41 }
42
43 if(nrfuz>z)z=nrfuz;
44 if(!mutat)gata=1;else ud=d,x++;
45
46 for(ii=in;ii<=sf;ii++)
47 if(p[ii]>y)y=p[ii];
48
49 if(y==2048)gata=1;
50 }
51
52 if(ud==’D’)P=P+n-sf;
53 else P=P-(in-1);
54
55 g<<x<<endl<<y<<endl<<z<<endl;
56
57 f.close();g.close();return 0;
58 return 0;
59 }

Listing 18.1.3: 2048F.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 int n,i,j,v[10010],p[12],x,y,z,m,k,f=1;
6 char c;
7
8 int main()
9 {
10 x=y=z=0;
11 ifstream fin("2048.in");
12 ofstream fout("2048.out");
13
14 fin>>n>>m;
15 for(i=1;i<=n;i++)
16 {fin>>v[i];
17 k=0;x=v[i];
18 while(x>1) x>>=1,k++;
19 p[k]++;
20 }
21
22 x=0;
23 while(x<m&&!p[11]&&f)
24 { x++;
25 fin>>c;
26
27 if(c==’S’)
28 {
29 f=0;
30 for(i=2;i<=n;)
31 if(v[i]==v[i-1])
32 {v[i-1]*=2;
33 k=0;f++;
34 while(v[i]>1) v[i]>>=1,k++;
35 p[k]-=2;p[k+1]++;
36 for(j=i;j<n;j++)
37 v[j]=v[j+1];
38 n--;i++;
39 }
40 else i++;
41 if(f>z)z=f;
42 }
43 else
44 {
45 f=0;
46 for(i=n-1;i>=1;i--)
47 if(v[i]==v[i+1])
48 {v[i]*=2;
49 k=0;f++;
CAPITOLUL 18. ONI 2014 257

50 while(v[i+1]>1) v[i+1]>>=1,k++;
51 p[k]-=2;p[k+1]++;
52 for(j=i+1;j<n;j++)
53 v[j]=v[j+1];
54 n--;i--;
55 }
56 if(f>z)z=f;
57 }
58
59 //for(i=1;i<=11;i++) fout<<p[i]<<’ ’; fout<<’\n’;
60 //for(i=1;i<=n;i++) fout<<v[i]<<’ ’; fout<<’\n’;
61 }
62
63 if(p[11]) y=2048;
64 else
65 {
66 for(i=11;!p[i];i--);
67 y=1<<i;
68 }
69
70 if(!f)x--;
71
72 fout<<x<<’\n’<<y<<’\n’<<z<<’\n’;
73
74 fin.close();
75 fout.close();
76 return 0;
77 }

Listing 18.1.4: 2048G.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 long long a[10001], Y;
6 int z,i,x,Z,j,k,N,M,gata=1;
7 char c;
8
9 int main()
10 {
11 ifstream f("2048.in");
12 ofstream g("2048.out");
13
14 f>>N>>M;f>>a[1];
15
16 for(i=2;i<=N;i++) {f>>a[i];if(a[i]==a[i-1] )gata=0;}
17 for(i=1;i<=N;i++) if(a[i]==2048) gata=1;
18
19 for(i=1;i<=M && (gata==0);i++)
20 {
21
22 f>>c;
23
24 x++;Z=0;
25 if(c==’D’)
26 { int q=N;
27 for(j=N;j>1;j--)
28 if(a[j]==a[j-1])
29 { a[j]=2*a[j];if(a[j]==2048) gata=1;
30 for(k=j-1;k<N;k++) a[k]=a[k+1];
31 q--;Z++;j--; }
32 if(q==N) {gata=1;x--;} else N=q;
33
34 }
35 else
36 { int q=N;
37 for(j=1;j<N;j++)
38 if(a[j]==a[j+1])
39 { a[j]=2*a[j];if(a[j]==2048)gata=1;
40 for(k=j+1;k<N;k++) a[k]=a[k+1];
41 N--;Z++;
42 }
43 if(q==N) {x--;gata=1;}
44
CAPITOLUL 18. ONI 2014 258

45 }
46
47 if(z<Z) z=Z;
48 }
49
50 Y=a[1];N++;
51
52 for(i=1;i<=N;i++)
53 {
54 if(a[i]>Y) Y=a[i];
55 }
56
57 g<<x<<endl<<Y<<endl<<z<<endl;
58
59 f.close();
60 g.close();
61 return 0;
62 }

Listing 18.1.5: 2048L.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream fin("2048.in");
6 ofstream fout("2048.out");
7
8 int n,m,a[10001],i,x,y,z,st,dr,nr,k,j,p,sch;
9 char c,uc,uuc;
10
11 int main()
12 {
13 fin>>n>>m;
14 for(i=1;i<=n;i++)
15 fin>>a[i];
16
17 x=y=z=0;
18 for(j=1;j<=n;j++)
19 y=max(y,a[j]);
20
21 if(y!=2048)
22 {x=y=z=0;
23 st=1;dr=n;
24 for(i=1;i<=m;i++)
25 {
26 fin>>c;
27 nr=0;
28 x++;
29
30 if(c==’S’)
31 {
32 for(j=st;j<dr;j++)
33 if(a[j]==a[j+1])
34 {
35 a[j]=2*a[j];nr++;
36 if(j+1==p)p--,sch=1;
37 else sch=0;
38 for(k=j+1;k<dr;k++)
39 {
40 a[k]=a[k+1];
41 if(k+1==p&&!sch){p--;sch=1;}
42 }
43 dr--;
44 }
45
46 z=max(z,nr);
47 }
48 else
49 {
50 for(j=dr;j>st;j--)
51 if(a[j]==a[j-1])
52 {
53 a[j]=2*a[j];nr++;
54 if(j-1==p)p++,sch=1;
CAPITOLUL 18. ONI 2014 259

55 else sch=0;
56 for(k=j-1;k>=st;k--)
57 {
58 a[k]=a[k-1];
59 if(k-1==p&&sch==0){p++;sch=1;}
60 }
61 st++;
62 }
63
64 z=max(z,nr);
65 }
66
67 if(nr==0)x--;
68
69 for(j=1;j<=n;j++)
70 y=max(y,a[j]);
71
72 if(nr==0)uuc=uc;
73 else uuc=c;
74
75 if(y==2048||nr==0)break;
76
77 uc=c;
78 }
79 }
80
81 fout<<x<<’\n’<<y<<’\n’<<z<<’\n’;
82 fout.close();
83 return 0;
84 }

Listing 18.1.6: 2048R.cpp

1 //Raluca Costineanu
2 #include <fstream>
3
4 using namespace std;
5
6 int a[10001], n, m;
7 char d;
8
9 ifstream f("2048.in");
10 ofstream g("2048.out");
11
12 int main()
13 {
14 int i, nr=0, p, u, k, max=0, nrf, nrm=0;
15 bool ok=1, e2048=0;
16
17 f>>n>>m;
18 for(i=1;i<=n;i++){f>>a[i];if(a[i]>nrm)nrm=a[i];}
19
20 if(nrm==2048)e2048=1,ok=0;
21
22 p=1; u=n;
23 while(ok)
24 {
25 f>>d; nr++;
26 nrf=0;
27 if(d==’S’)
28 {
29 k=p;
30 for(i=p;i<u;i++)
31 if(a[i]==a[i+1]) {a[k++]=2*a[i]; i++; nrf++; if(a[k-1]>nrm)nrm=a[k-1];}
32 else a[k++]=a[i];
33
34 if(i==u)a[k++]=a[i];
35 u=k-1;
36 }
37 else
38 {
39 k=u;
40 for(i=u;i>p;i--)
41 if(a[i]==a[i-1]) {a[k--]=2*a[i]; i--; nrf++;if(a[k+1]>nrm)nrm=a[k+1];}
42 else a[k--]=a[i];
CAPITOLUL 18. ONI 2014 260

43
44 if(i==p) a[k--]=a[i];
45 p=k+1;
46 }
47
48 if(nrm==2048)e2048=1;
49
50 if(nrf==0)ok=0;
51 else if(nrf>max)max=nrf;
52
53 if(nr==m)ok=0;
54
55 if(e2048==1)ok=0;
56 //for(i=p;i<=u;i++)g<<a[i]<<’ ’;g<<’\n’;
57 }
58
59 if(nr==m or e2048==1)
60 g<<nr<<’\n’;
61 else
62 g<<nr-1<<’\n’;
63
64 g<<nrm<<’\n’<<max<<’\n’;
65
66 f.close();
67 g.close();
68 return 0;
69 }

18.1.3 *Rezolvare detaliat 

18.2 babilon
Problema 2 - babilon 100 de puncte
Babilonienii au dezvoltat un sistem poziµional de scriere a numerelor, în care orice num r

natural se poate reprezenta utilizând semnele (unu), (zece) ³i spaµii.

Valorile k " r2, 3, ..., 9x se obµin scriind semnul de k ori (scrierea babilonian  a lui 3 este

).

Numerele 11, 12, ..., 59 se obµin ca succesiuni de semne urmate de semne (43 se reprezint 

ca ).
Sistemul folose³te gruparea unit µilor câte ³aizeci. Astfel, pentru a scrie um rul ³aizeci se
folose³te acela³i semn ca pentru unu, dar valoarea sa este dat  de poziµia în care se g se³te semnul

.
Babilonienii nu foloseau cifra 0. Pentru poziµionarea corect  a semnelor se utiliza spaµiu

(60 se reprezint  ca , 3600 se reprezint  ca etc.).

Se codic  scrierea babilonian  a unui num r utilizând cifra 1 în locul semnului , cifra 2 în

locul semnului ³i cifra 3 în loc de spaµiu, ca în exemplele de mai jos:

Scrierea
babilonian 
Codicarea 1311 12 1221111 123111
scrierii
babiloniene
Valoarea 1*60+2=62 1*60+10=70 1*60+20+4=84 1*60*60+10*60+3=4203
zecimal 
a num rului

Cerinµe
Dându-se un num r natural n ³i un ³ir de n cifre din mulµimea r1, 2, 3x, reprezentând codicarea
scrierii babiloniene a unui num r natural, s  se determine:
CAPITOLUL 18. ONI 2014 261

a) num rul maxim de cifre 1 aate pe poziµii consecutive în codicarea scrierii babiloniene


date;
b) num rul natural din sistemul zecimal corespunz tor scrierii babiloniene date.

Date de intrare
Fi³ierul de intrare babilon.in conµine:
a pe prima linie un num r natural p(1&p&2 );
a pe a doua linie un num r natural n;
a pe a treia linie n cifre separate prin câte un spaµiu, reprezentând codicarea scrierii babilo-
niene a unui num r natural.

Date de ie³ire
Dac  valoarea lui p este 1, atunci se va rezolva numai punctul a) din cerinµ . În acest caz,
³ierul de ie³ire babilon.out va conµine pe prima linie un num r natural reprezentând num rul
maxim de cifre 1 aate pe poziµii consecutive în codicarea scrierii babiloniene date.
Dac  valoarea lui p este 2, atunci se va rezolva numai punctul b) din cerinµ . În acest caz,
³ierul de ie³ire babilon.out va conµine pe prima linie num rul natural corespunz tor scrierii
babiloniene date.

Restricµii ³i preciz ri
2 & n & 10
9
a ;
a se garanteaz  faptul c  num rul de cifre al rezultatului de la punctul b) (num rul zecimal)
este mai mic decât 20;
a 30% din teste vor avea pe prima linie valoarea 1, iar restul de 70% din teste vor avea pe
prima linie valoarea 2.

Exemple
babilon.in babilon.out Explicaµii
1 3 1 1 3 2 1 1 1 2.
8 Cea mai lung  secvenµ  de cifre 1 are lungimea 3.
1 1 3 2 1 1 1 2
2 7213
7
1 1 3 2 1 1 1

2 se înmulµe³te de dou  ori cu 60 (o dat  pentru


c  este urmat de spaµiu ³i înc  o dat  pentru c 
precede o grup  care începe cu semnul $ ), apoi
se adun  valoarea 13.
2*60*60+10+3=7213
2 11541
9
1 1 1 2 1 1 2 2 1

3 se înmulµe³te cu 60 de dou  ori pentru c  este


precedat de dou  grupe care încep cu semnul $ ,
apoi se adun  12 înmulµit cu 60 ³i la nal se adun 
21.
3*60*60+12*60+21=11541

Timp maxim de executare/test: 0.1 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 5 KB

18.2.1 Indicaµii de rezolvare


Prof. Florentina Ungureanu, Colegiul Naµional de Informatic  Piatra-Neamµ
CAPITOLUL 18. ONI 2014 262

Punctul a):
Se citesc pe rând valorile din ³ier, se determin  lungimea ec rei secvenµe de cifre 1 ³i se
reµine lungimea maxim .

Punctul b):
Se cite³te prima cifr  ³i se iniµializeaz  o variabil  z cu 1 dac  cifra este 1 (corespunz tor

semnului ), respectiv cu 10 dac  este egal  cu 2 (corespunz tor semnului ). Se continu 


citirea câte unei cifre ³i la întâlnirea cifrei 3 (corespunz toare unui spaµiu în scrierea babilonian )
sau a cifrei 2 precedat  de o cifr  1 (ignorând eventualele cifre 3 corespunz toare spaµiilor) valoarea
z se înmulµe³te cu 60. Pentru ecare cifr  1 întâlnit , z se incrementeaz  cu 1, iar pentru ecare
cifr  2, se incrementeaz  cu 10.

18.2.2 Cod surs 

Listing 18.2.1: babilon.cpp

1 //Florentina Ungureanu - Colegiul National de Informatica Piatra-Neamt


2 #include <fstream>
3 #include <iostream>
4 #include <string.h>
5
6 using namespace std;
7 unsigned n, v, a, b, c;
8
9 ifstream f("babilon.in");
10 ofstream g("babilon.out");
11
12 int main()
13 {
14 long long z=0;
15 unsigned i, fr, fmax;
16 f>>v>>n;
17 if(v==1)
18 {
19 f>>a;
20 fmax=fr=a==1;
21 for(i=2;i<=n;i++)
22 {
23 f>>b;
24 if(a*b==1) fr++;
25 else
26 {
27 if (fr>fmax) fmax=fr;
28 fr=b==1;
29 }
30 a=b;
31 }
32
33 if (fr>fmax) fmax=fr;
34 g<<fmax<<’\n’;
35 }
36 else
37 {
38 f>>a;
39 if(a==1)z=1;
40 else
41 if(a==2)z=10;
42 else z=0;
43
44 for(i=2;i<=n;i++)
45 {
46 f>>b;
47 if (b>a) z=z*60;
48 if(b==1)z++;
49 else if(b==2)z+=10;
50 if (b!=3) a=b;
51 }
52
53 g<<z<<’\n’;
54 }
55
56 f.close();
CAPITOLUL 18. ONI 2014 263

57 g.close();
58 return 0;
59 }

Listing 18.2.2: babilonA.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream f("babilon.in");
6 ofstream g("babilon.out");
7
8 int var,n,i,c[121],l,lmax,prec;
9 long long nrb;
10
11 int main()
12 {
13 //citire-prelucare
14 f>>var>>n;
15 for(i=1;i<=n;i++) f>>c[i];
16 if(var==1)
17 {
18 for(i=1;i<=n;i++)
19 {
20 if(c[i]==1) l++;
21 else {if(l>lmax) lmax=l;
22 l=0;
23 }
24 }
25 {if(l>lmax) lmax=l;l=0;} g<<lmax<<endl;
26 }
27 else
28 {
29 for(i=1;i<=n;i++)
30 if(c[i]==1) nrb++,prec=c[i];
31 else if(c[i]==3) nrb*=60;
32 else {
33 if(prec==1)nrb*=60;
34 nrb+=10;prec=c[i];
35 }
36 g<<nrb<<endl;
37 }
38 return 0;
39 }

Listing 18.2.3: babilonC.cpp

1 #include <fstream>
2 //Cristina Sichim
3
4 using namespace std;
5
6 ifstream f("babilon.in");
7 ofstream g("babilon.out");
8
9 long long r;
10 int v,n,i,c,a,k1,k;
11
12 int main()
13 { f>>v>>n;
14 for(i=1;i<=n;++i)
15 { f>>c;
16 switch(c)
17 {case 1: r++,a=c,k++,k1=max(k,k1);break;
18 case 2: if(a==1) r*=60;r+=10,a=c,k=0;break;
19 default:r*=60,k=0;
20 }
21 }
22
23 if(v==1)g<<k1<<’\n’;
24 else g<<r<<’\n’;
25
26 f.close();
CAPITOLUL 18. ONI 2014 264

27 g.close();
28 return 0;
29 }

Listing 18.2.4: babilonL.cpp

1 #include <fstream>
2
3 using namespace std;
4
5 ifstream fin("babilon.in");
6 ofstream fout("babilon.out");
7
8 int n, c1,c2,i,x,caz,nr1,nrmax;
9 long long nr;
10 char c;
11
12 int main()
13 {
14 fin>>caz;
15 if(caz==1)
16 {
17 fin>>n;nr1=0;
18 for(i=1;i<=n;i++)
19 {
20 fin>>c;c1=c-’0’;
21 if(c1==1)nr1++;
22 else
23 {
24 if(nr1>nrmax)nrmax=nr1;
25 nr1=0;
26 }
27 }
28 if(nr1>nrmax)nrmax=nr1;
29 fout<<nrmax<<’\n’;
30 }
31 else
32 {
33 fin>>n>>c;
34 nr=nr1=0;
35 c1=c-’0’;
36 if(c1==1){nr1++;x=1;}
37 else x=10;
38 for(i=2;i<=n;i++)
39 {
40 fin>>c;
41 c2=c-’0’;
42 if(c2==1)
43 {x++;nr1++;}
44 else
45 if(c2==2)
46 {
47 if(c1==2)x=x+10;
48 else
49 if(nr1)
50 {
51 nr=nr*60+x;//fout<<x<<’ ’<<nr<<’\n’;
52 x=10;
53 nr1=0;
54 }
55 else x=10;
56 }
57 else
58 {
59 nr=nr*60+x;//fout<<x<<’ ’;
60 x=0;
61 }
62 c1=c2;
63 }
64 nr=nr*60+x;
65 fout<<nr<<’\n’;
66 }
67 fout.close();
68 return 0;
69 }
CAPITOLUL 18. ONI 2014 265

18.2.3 *Rezolvare detaliat 


18.3 iepurasi
Problema 3 - iepurasi 100 de puncte
Se construie³te un ³ir de numere naturale care
respect  restricµiile:
- primul num r din ³ir este 9;
- numerele se genereaz  în ordine strict cres-
c toare;
- ³irul conµine toate numerele formate doar cu
cifrele 7, 8 ³i 9 cu proprietatea c  num rul cifrelor
9 este mai mare sau egal decât num rul cifrelor 8
³i num rul cifrelor 8 este mai mare sau egal decât
num rul cifrelor 7.

Primii 14 termeni ai ³irului, în ordine, sunt: 9,


89, 98, 99, 789, 798, 879, 897, 899, 978, 987, 989, Figura 18.2: iepurasi
998, 999.

Pornind de la aceste numere, Liv a inventat un joc interactiv: N iepura³i sunt a³ezaµi în ³ir,
ecare având câte un cartona³. Fiecare cartona³ are dou  feµe, o faµ  alb  pe care este inscripµionat
un num r din acest ³ir ³i o faµ  gri, pe care este inscripµionat  poziµia acelui num r în ³ir, poziµii
numerotate în ordine, începând cu valoarea 14.
Exemple. Cartona³ul care are pe faµa gri inscripµionat num rul 1 va avea pe faµa alb 
inscripµionat num rul 9, iar cartona³ul care are pe faµa gri inscripµionat num rul 5 va avea pe faµa
alb  inscripµionat num rul 789.
Iepura³ii sunt a³ezaµi într-o ordine oarecare ³i µin cartona³ele astfel încât s  se vad  faµa
gri. Jocul const  în a rearanja iepura³ii de la stânga la dreapta, descresc tor dup  numerele
inscripµionate pe feµele gri, având la dispoziµie doar operaµia T AP pe un iepura³. Când se aplic 
operaµia T AP unui iepura³ atunci secvenµa de iepura³i, începând de la cel pe care s-a f cut T AP ³i
pân  la sfâr³itul ³irului (spre dreapta), este oglindit  (ca în imaginea de mai sus). Dup  oglindire,
toµi iepura³ii din acea secvenµ  µin cartona³ele astfel încât s  se vad  faµa alb . Se dore³te aplicarea
unui num r cât mai mic de operaµii T AP pentru rearanjarea iepura³ilor.

Cerinµe
Scrieµi un program care s  citeasc  numerele naturale N (reprezentând num rul de iepura³i) ³i
a1 , a2 , ..., aN (reprezentând, în ordine, numerele inscripµionate pe feµele gri) ³i care s  determine:
a) Num rul minim de operaµii T AP necesare rearanj rii iepura³ilor;
b) Cel mai mic num r aat pe o faµ  alb  care nu se vede, în cazul în care au r mas cartona³e
neîntoarse. Dac  toate cartona³ele au fost întoarse (la toate ind vizibil  faµa alb ) se va a³a cel
mai mare num r aat pe o faµ  alb  a unui cartona³.

Date de intrare
Fi³ierul de intrare iepurasi.in conµine pe prima linie num rul natural N reprezentând num rul
de iepura³i. A doua linie a ³ierului conµine, în ordine, cele N numere: a1 , a2 , ...,aN , separate
prin câte un spaµiu, reprezentând în ordine, numerele inscripµionate pe feµele gri ale cartona³elor.

Date de ie³ire
Fi³ierul de ie³ire iepurasi.out va conµine pe prima linie un num r reprezentând num rul
minim de operaµii T AP necesare rearanj rii iepura³ilor.
A doua linie va conµine un num r reprezentând cel mai mic num r aat pe o faµ  alb  care nu
se vede (în cazul în care au r mas cartona³e neîntoarse), respectiv cel mai mare num r aat pe o
faµ  alb  a unui cartona³, în cazul în care toate cartona³ele au fost întoarse (la toate ind vizibil 
faµa alb ).

Restricµii ³i preciz ri
CAPITOLUL 18. ONI 2014 266

a 2 & N & 10000;


a 1 & ai & 10000 (1 & i & N );
a N , a1 , a2 , ..., aN sunt numere naturale;
a pentru rezolvarea cerinµei a) se acord  50% din punctaj, iar pentru cerinµa b) se acord  50%
din punctaj.

Exemple
iepurasi.in iepurasi.out Explicaµii
5 1 Se aplic  o singur  operaµie TAP pe iepura³ul cu num rul
14 5 8 9 10 999 de ordine 5.
Cartona³ul neîntors are num rul de ordine 14 (999).

Timp maxim de executare/test: 1.0 secunde


Memorie: total 5 MB din care pentru stiv  5 MB
Dimensiune maxim  a sursei: 5 KB

18.3.1 Indicaµii de rezolvare


Cerinµa a)
Întrucât problema cere ca rearanjarea iepura³ilor s  se fac  de la stânga la dreapta, primul
iepura³ care trebuie repoziµionat este iepura³ul cu cel mai mare num r pe faµa gri. Urmând aceea³i
idee, la ecare pas i, trebuie repoziµionat iepura³ul cu cel mai mare num r pe faµa gri, care se a 
pe o poziµie j (i & j & n). Costul unei astfel de repoziµion ri poate  0, 1 sau 2.
Soluµia1. Se parcurge tabloul cu numerele de ordine ale iepura³ilor, de la stânga la dreapta,
³i pentru ecare ai se veric  dac  este maxim pe secvenµa ai ... an. Dac  nu este maxim,
se caut  poziµia elementului maxim aat la dreapta lui i, e aceasta imax ³i se execut  un T AP
pe iepura³ul cu num rul de ordine aimax, dac  imax j N ³i apoi un T AP pe iepura³ul cu
num rul de ordine ai.
Soluµia2. Se face o copie a tabloului unidimensional cu numerele de ordine ale iepura³ilor citite
(a1). Se ordoneaz  descresc tor a1 ³i se compar  cu ³irul iniµial. În cazul în care ai j a1i se
execut  T AP pe ai, dac  a1N  ai sau se face T AP pe aj , dac  a1j  ai ³i T AP pe
ai.
Soluµia3. Se realizeaz  un precalcul care num r  pentru ecare cartona³ gri, câte elemente
sunt mai mici ca valoare ³i se reµine într-un tablou poziµia pe care ar ocupa-o în ³irul sortat ³i în
alt tablou poziµia pe care o ocup  în ³irul actual. Pentru un cartona³ care nu se a  pe poziµia
sa nal  se realizeaz  T AP din poziµia elementului care ar  trebuit s  se ae în aceast  poziµie.
Dac  acest element se a  în ³irul actual pe poziµia n se face un T AP , iar dac  nu, se fac dou 
T AP -uri (primul ca s  ajung  pe poziµia n ³i al doilea ca s  ajung  la locul s u).

Cerinµa b)
Soluµia1. Se utilizeaz  4 tablouri unidimensionale, unul pentru memorarea tuturor numerelor
ce se pot forma, în ordine cresc toare, cu cifrele 7, 8 ³i 9 ³i trei tablouri unidimensionale în care
se memoreaz  frecvenµa de apariµie a cifrelor 7, 8 ³i 9 în numerele generate.

Soluµia2. Se simuleaz  o generare în baza 4 în care resturilor 1, 2, 3 li se asociaz  cifrele 7, 8


³i 9.

18.3.2 Cod surs 

Listing 18.3.1: iepurasi_AI.cpp

1 //Ana Intuneric
2 #include <fstream>
3
4 using namespace std;
5
6 ifstream f("iepurasi.in");
7 ofstream g("iepurasi.out");
8
9 long long toate[200001],ncurent;
CAPITOLUL 18. ONI 2014 267

10 int N,a[10001],dim_sir,TAP,nr1,nr2;
11 bool viz[10001];
12 char fr7[200001],fr8[200001],fr9[200001];
13
14 int main()
15 {
16 int i,j,k,maxi,imax,aux,c7,c8,c9;;
17 //citire
18 f>>N;
19 for(i=1;i<=N;i++)f>>a[i];
20
21 //sortare descrescatoare
22 for(i=1;i<=N;i++)
23 {
24 imax=i;maxi=a[i];
25 for(j=i+1;j<=N;j++)
26 if(a[j]>maxi)maxi=a[j],imax=j;
27 if(imax!=i)
28 {
29 if(a[N]!=maxi)
30 {
31 TAP++;
32 //TAP pe iepurasul imax
33 for(j=imax,k=N;j<k;j++,k--)
34 aux=a[j],a[j]=a[k],a[k]=aux,viz[j]=true,viz[k]=true;
35 }
36 //TAP pe iepurasul i
37 if(a[i]!=maxi)
38 {
39 TAP++;
40 for(j=i,k=N;j<k;j++,k--)
41 aux=a[j],a[j]=a[k],a[k]=aux,viz[j]=true,viz[k]=true;
42 }
43 }
44 }
45
46 //det cartonas minim/maxim
47 if(viz[1])k=a[1];
48 else
49 {
50 i=1;while(!viz[i] && i<=N)i++;
51 k=a[i-1];
52 }
53
54 //constructie sir de numere cu cifrele 7,8,9 pana la numarul de pe pozitia k
55 fr7[1]=1;fr8[2]=1;fr9[3]=1;
56 toate[1]=7;toate[2]=8;toate[3]=9;
57 dim_sir=0;nr1=1;nr2=3;
58 while(dim_sir<k)
59 {
60 c7=fr7[nr1];c8=fr8[nr1];c9=fr9[nr1];
61 ncurent=toate[nr1];nr1++;nr2--;
62 if(c7<=c8 && c8<=c9) dim_sir++;
63
64 fr7[nr1+nr2]=c7+1;fr8[nr1+nr2]=c8;fr9[nr1+nr2]=c9;
65 toate[nr1+nr2]=10*ncurent+7;nr2++;
66
67 fr7[nr1+nr2]=c7;fr8[nr1+nr2]=c8+1;fr9[nr1+nr2]=c9;
68 toate[nr1+nr2]=10*ncurent+8;nr2++;
69
70 fr7[nr1+nr2]=c7;fr8[nr1+nr2]=c8;fr9[nr1+nr2]=c9+1;
71 toate[nr1+nr2]=10*ncurent+9;nr2++;
72 }
73
74 //afisare
75 g<<TAP<<endl<<ncurent<<endl;
76 f.close();g.close();return 0;
77 return 0;
78 }

Listing 18.3.2: iepurasi_CS.cpp

1 //Cristina Sichim
2 #include <fstream>
3 #include <algorithm>
CAPITOLUL 18. ONI 2014 268

4
5 using namespace std;
6
7 ifstream f("iepurasi.in");
8 ofstream g("iepurasi.out");
9
10 int v1[10001],v2[10001],c[4],n,i,j,k,t,tap;
11 long long z,x,y;
12
13 bool cand(int i,int j) {return (i>j);}
14
15 int main()
16 { f>>n;
17 for(i=1;i<=n;i++){f>>v1[i];v2[i]=v1[i];}
18
19 sort(v2+1,v2+n+1,cand);
20
21 i=1;while(i<=n && v1[i]==v2[i])i++;
22 if(i==n+1)k=v2[n];
23 else if(i==1) k=v2[1];
24 else k=v2[i-1];
25
26 for(;i<n;i++)
27 if(v1[i]!=v2[i])
28 { j=i;
29 while(v1[j]!=v2[i])j++;
30 if(j!=n) tap++,reverse(v1+j,v1+n+1);
31 tap++;reverse(v1+i,v1+n+1);
32 }
33
34 //c[1]->7,c[2]->8,c[3]->9
35 x=1;
36 while(k)
37 { c[0]=c[1]=c[2]=c[3]=0;t=1;
38 y=x++;
39 z=0;
40 while(y)z+=(y%4+6)*t,c[y%4]++,y=y/4,t=t*10;
41 if(c[0]==0 && c[3]>=c[2] && c[2]>=c[1]) k--;
42 }
43
44 g<<tap<<’\n’<<z<<’\n’;
45 f.close();g.close();
46 return 0;
47 }

Listing 18.3.3: iepurasi_gina.cpp

1 #include <fstream>
2
3 using namespace std;
4 long long a[10001],n,i,Imax,x,j,k,I[10001],tap,gata,J,aux;
5 int main()
6 { ifstream f("iepurasi.in");ofstream g("iepurasi.out");
7 f>>n;
8 for(i=1;i<=n;i++) f>>a[i];
9 for(k=1;k<n;k++)
10 { Imax=k;
11 for(j=k+1;j<=n;j++) if(a[j]>a[Imax]) Imax=j;
12 if(k!=Imax)
13 { tap++;J=n;
14 if(Imax!=n)
15 {for(j=Imax;j<J;j++)
16 {aux=a[j];a[j]=a[J];a[J]=aux; J--;I[j]=1;I[J]=1;}
17 I[j]=1;tap++;}
18 J=n;
19 for(j=k;j<J;j++){aux=a[j];a[j]=a[J];a[J]=aux; J--;I[j]=1;I[J]=1;}
20 I[j]=1;
21 }
22 }
23 int i1=0,i2=0;
24 for(i=n;i>=1;i--)
25 if(!a[i])
26 if(i1==0)i1=i;
27 else
28 if(i2==0)i2=i;
CAPITOLUL 18. ONI 2014 269

29 else
30 break;
31 //if(i1*i2)
32 // {g<<i1<<" "<<i2<<endl;}
33 //else
34 // {g<<a[2]<<" "<<a[1]<<endl;}
35 //g<<tap<<endl;
36 //for(i=1;i<=n;i++)
37 //g<<a[i]<<’ ’;
38 long long P,x,i=1,n4,n7=0;
39 i=1;
40 for(n7=0;n7<=a[1];i++)
41 if(i%4)
42 { int c[4],ok=1;
43 for(int j=0;j<=3;j++)c[j]=0;
44 P=1;x=i;n4=0;
45 while(x)
46 {n4=n4+(x%4+6)*P;
47 c[x%4]++;x=x/4; P=P*10;
48 }
49 if(c[0]!=0 || c[1]>c[2] || c[1]>c[3] || c[2]>c[3])ok=0;
50 if(ok)
51 {
52 //g<<i<<’ ’<<n4<<endl;
53 I[++n7]=n4;
54 }
55 }
56
57 g<<tap<<endl;
58 if(i1*i2)
59 {//g<<I[i1]<<" "<<I[i2]<<endl;
60 g<<I[i2]<<endl;
61 }
62 else
63 {//g<<I[a[2]]<<" "<<I[a[1]]<<endl;
64 g<<I[a[1]]<<endl;
65 }
66
67 f.close();
68 g.close();
69 return 0;
70 }

Listing 18.3.4: iepurasi_lucia.cpp

1 #include <fstream>
2 #include<algorithm>
3
4 using namespace std;
5
6 ifstream fin("iepurasi.in");
7 ofstream fout("iepurasi.out");
8
9 int n, a[10011], i, viz[10011], ao[10011],nro,caz,m1,m2,poz,nt,nr;
10 long long s[20100];
11
12 void adauga(int cm,int poz,int m)
13 {
14 long long nrnou,x,nv,pp,sf,inc;
15 nv=0;
16 pp=1;
17 x=s[poz];
18 while(pp<x)
19 {
20 sf=x%pp;
21 inc=x/pp;
22 nrnou=(inc*10+cm)*pp+sf;
23 nt++;
24 s[nt]=nrnou;
25 for(i=nt-1; i>=nr+1; i--)
26 if(s[nt]==s[i])
27 {
28 nt--;
29 break;
30 }
CAPITOLUL 18. ONI 2014 270

31 pp=pp*10;
32 nv++;
33 // if(nt>=m)return;
34 }
35 nrnou=cm*pp+x;;
36 nt++;
37 s[nt]=nrnou;
38 for(i=nt-1; i>=nr+1; i--)
39 if(s[nt]==s[i])
40 {
41 nt--;
42 break;
43 }
44 // if(nt>=m)return;
45 }
46
47 void construieste(int m)
48 {
49 long long i,k,c7,c8,c9,nv;
50 long long x;
51 s[1]=9;
52 k=1;
53 nr=1;
54 nt=nr;
55 //m=7000;
56 while(nt<m)
57 {
58 for(poz=k; poz<=nr; poz++)
59 {
60 x=s[poz];
61 c7=c8=c9=0;
62 nv=0;
63 while(x)
64 {
65 if(x%10==7)c7++;
66 if(x%10==8)c8++;
67 if(x%10==9)c9++;
68 x=x/10;
69 nv++;
70 }
71 if(c8<c9)adauga(8,poz,m);
72 if(c7<c8&&c8<=c9)adauga(7,poz,m);
73 adauga(9,poz,m);
74
75 }
76 //if(nt>=m)break;
77 x=0;
78 for(i=1; i<=nv+1; i++)
79 x=x*10+9;
80 s[++nt]=x;
81 for(i=nt-1; i>=nr+1; i--)
82 if(s[nt]==s[i])
83 {
84 nt--;
85 break;
86 }
87 k=nr+1;
88 nr=nt;
89 }
90 sort(s+1,s+nt+1);
91 }
92
93 void schimba(int st)
94 {
95 int i,j;
96 i=st;
97 j=n;
98 while(i<=j)
99 {
100 swap(a[i],a[j]);
101 viz[i]=1;
102 viz[j]=1;
103 i++;
104 j--;
105 }
106 }
CAPITOLUL 18. ONI 2014 271

107
108 int main()
109 {
110 fin>>n;
111 for(i=1; i<=n; i++)
112 {
113 fin>>a[i];
114 ao[i]=a[i];
115 }
116
117 sort(ao+1,ao+n+1);
118
119 for(i=1; i<=n/2; i++)
120 swap(ao[i],ao[n+1-i]);
121
122 for(i=1; i<=n; i++)
123 if(ao[i]!=a[i])
124 {
125 nro++;
126 for(poz=i+1; poz<=n; poz++)
127 if(a[poz]==ao[i])break;
128 if(poz!=n)
129 {
130 schimba(poz);
131 nro++;
132 schimba(i);
133 }
134 else schimba(i);
135 }
136 caz=2;
137 for(i=1; i<=n; i++)
138 if(viz[i]==0)
139 {
140 caz=1;
141 break;
142 }
143 if(caz==1)
144 {
145 m1=10001;
146 for(i=1; i<=n; i++)
147 if(viz[i]==0 && m1>a[i])
148 m1=a[i];
149 else break;
150 }
151 else
152 {
153 m1=0;
154 for(i=1; i<=n; i++)
155 if(m1<a[i]) m1=a[i];
156
157 }
158
159 construieste(m1);
160 fout<<nro<<’\n’<<s[m1]<<’\n’;
161 fout.close();
162 return 0;
163 }

Listing 18.3.5: iepurasiM.cpp

1 #include <fstream>
2 #include <iostream>
3 #include <algorithm>
4
5 using namespace std;
6 unsigned long long a[10001],sir[10001],vmax,vmin,i,x,nr,j,t,m;
7 int n,b[10001],y[10001],d[10001],p1,p2,p,k,ok,rez,ii,cif[10];
8
9 ifstream f("iepurasi.in");
10 ofstream g("iepurasi.out");
11
12 int main()
13 {f>>n;
14 for(i=1;i<=n;i++)
15 {
CAPITOLUL 18. ONI 2014 272

16 f>>a[i];
17 if(a[i]>vmax) vmax=a[i];
18 }
19
20 f.close();
21
22 //varianta generare sir care intra in timp
23 for(i=1;nr<=vmax;i++)
24 {t=1;
25 for(j=0;j<=3;j++)cif[j]=0;
26 x=i;m=0;
27 while(x)
28 {m=m+(x%4+6)*t;cif[x%4]++;x=x/4; t=t*10;}
29 ok=1;if(cif[0]!=0)ok=0;
30 if(ok)for(j=1;j<3;j++)if(cif[j]>cif[j+1])ok=0;
31 if(ok) sir[++nr]=m;
32 }
33
34 //varianta de generare sir care nu intra in timp
35 /*nr=0;s
36 for(i=1;nr<=vmax; i++)
37 {
38 if(i%10>6)
39 for(j=0;j<=9;j++) cif[j]=0;
40 x=i;
41 ok=1;
42 while(x)
43
44 { if(x%10<7){ok=0;x=0;}
45 cif[x%10]++;x=x/10;
46 }
47 if (cif[7]>cif[8]|| cif[8]>cif[9])ok=0;
48
49 if(ok){nr++;sir[nr]=i;}
50
51
52 }
53 */
54
55 for(i=1;i<=n;i++)
56 {k=0;
57 for(j=1;j<=n;j++)if(a[j]<a[i])k++;
58 b[i]=k+1;y[k+1]=i;
59 }
60
61 vmin=a[1];p=0;
62 ok=1;
63 for(j=1;j<=n;j++)
64 {
65 if(b[j]!=n-j+1) {;p=j;break;}
66 if(vmin>a[j])vmin=a[j];
67
68 }
69
70 for(i=1;i<=n; i++)
71 if(b[i]!=n-i+1)
72 {
73 p1=i;p2=y[n-i+1];
74 if(p2==n)
75 {rez++;k=0; for(j=p2;j>=p1; j--) {k++;d[k]=b[j];} }
76 else
77 { rez=rez+2;k=0;
78 for(j=p2;j<=n; j++){k++;d[k]=b[j];}
79 for(j=p2-1;j>=p1; j--){k++;d[k]=b[j];}
80 }
81 for(ii=1;ii<=k; ii++) {b[p1+ii-1]=d[ii];y[d[ii]]=p1+ii-1;}
82 }
83
84 g<<rez<<endl;
85 if(p==1)g<<sir[vmax]<<endl;
86 else
87 g<<sir[vmin]<<endl;
88
89 g.close();
90 }
CAPITOLUL 18. ONI 2014 273

18.3.3 *Rezolvare detaliat 


Capitolul 19

ONI 2013

19.1 greieri
Problema 1 - greieri 100 de puncte
Pe o linie orizontal  se g sesc n
greieri. Ei încep s  stea capr  într-
o ordine prestabilit  începând cu ul-
timul, pe rând, pân  la primul. Toµi
greierii care îl preced  pe cel care st 
capr  sar peste acesta, în ordine.
De exemplu pentru n=4, mai întâi
st  capr  greierele 4 ³i peste el sar,
în ordine, 3, 2 ³i 1. Apoi st  capr 
greierele 3 ³i sar peste el, în ordine, 2,
1 ³i 4. Apoi st  capr  greierele 2 ³i
peste el sar, în ordine, 1, 3 ³i 4. Apoi
Figura 19.1: greieri
st  capr  greierele 1 ³i sar peste el,
în ordine, 4 , 3 ³i 2, ³i se revine la ordinea iniµial .

Cerinµe
Scrieµi un program care cite³te numerele naturale n ³i m ³i determin :
a) De câte s rituri este nevoie pentru a se ajunge la ordinea iniµial ?
b) Cum vor  a³ezaµi greierii dup  m s rituri?

Date de intrare
Fi³ierul de intrare greieri.in conµine pe prima linie numerele naturale n ³i m, separate printr-
un spaµiu, cu semnicaµia din enunµ.

Date de ie³ire
Fi³ierul de ie³ire greieri.out va conµine:
a) pe prima linie o valoare ce reprezint  num rul de s rituri dup  care se revine la ordinea
iniµial ;
b) pe a doua linie numerele ce reprezint  ordinea greierilor dup  m pa³i, separate prin spaµii.

Restricµii ³i preciz ri
a 2 & n & 100000
a 1 & m & 2000000000
a se acord  20% din punctaj pentru rezolvarea corect  cerinµei a)
a se acord  80% din punctaj pentru rezolvarea corect  cerinµei b)
a r spunsurile la cele dou  cerinµe vor  scrise exact pe linia indicat ; în cazul în care nu
cunoa³teµi rezolvarea la una dintre cerinµe, pe linia respectiv  se va scrie valoarea 1;
a ecare linie din ³ierul de intrare se termin  cu caracterul sfâr³it de linie

274
CAPITOLUL 19. ONI 2013 275

Exemple
greieri.in greieri.out Explicaµii
4 5 12 Dup  cum se vede ³i în imagine pornind de la linia iniµial 
4 3 1 2 1 2 3 4 la primul pas sare greierele 3 peste 4, la pasul 2
sare greierele 2 peste 4, la pasul trei sare greierele 1 peste
4, la pasul patru sare greierele 2 peste 3, iar la pasul cinci
sare greierele 1 peste 3.

Timp maxim de executare/test: 0.4 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 5 KB

19.1.1 *Indicaµii de rezolvare


matematic 

19.1.2 *Cod surs 

19.1.3 *Rezolvare detaliat 

19.2 Onigim
Problema 2 - Onigim 1000 de puncte
La ONIGIM 2013 particip  N elevi de clasa a V-a având ca id-uri, în ordine, numerele naturale
de la 1 la N. Anul acesta organizatorii au a³at la clasa a V-a toate punctajele distincte obµinute
de elevi, în ordine strict cresc toare p1 , p2 , ..., pK , ³i un ³ir de N valori a1 , a2 , ..., aN , unde ai
reprezint  num rul de elevi care au punctaje strict mai mici decât punctajul elevului având id-ul
i (1 & i & N ).

Cerinµe
Cunoscând num rul de elevi (N ), num rul de punctaje distincte (K ) obµinute de elevii de
clasa a V-a, punctajele p1 , p2 , ..., pK , în ordine strict cresc toare, ³i valorile a1 , a2 , ..., aN , cu
semnicaµia din enunµ, s  se scrie un program care determin :
a) Punctajul obµinut de ecare elev în ordinea cresc toare a id-urilor.
b) Num rul de distincµii acordate de organizatori. Num rul de distincµii este egal cu num rul
de elevi care au obµinut cele mai mari trei punctaje distincte.
c) Num rul maxim de elevi care au obµinut acela³i punctaj.

Date de intrare
Fi³ierul de intrare onigim.in conµine pe prima linie numerele naturale N ³i K reprezentând
num rul de elevi, respectiv num rul de punctaje distincte obµinute de elevi.
Pe a doua linie sunt K numere naturale în ordine strict cresc toare p1 , p2 , ..., pK reprezentând
punctajele distincte obµinute de elevi, ³i pe a treia linie sunt N numere naturale a1 , a2 , ..., aN ,
unde ai reprezint  num rul de elevi care au punctaje strict mai mici decât punctajul elevului cu
ID-ul i.

Date de ie³ire
Fi³ierul de ie³ire onigim.out va conµine trei linii.
Pe prima linie se a  N numere naturale v1 , v2 , ..., vN reprezentând punctajele obµinute de cei
N concurenµi (vi - punctajul concurentului cu ID-ul i), pe a doua linie se a  un num r natural
D reprezentând num rul de distincµii acordate de organizatori, pe a treia linie se a  un num r
natural M reprezentând num rul maxim de elevi care au obµinut acela³i punctaj.

Restricµii ³i preciz ri
CAPITOLUL 19. ONI 2013 276

a 1 & N & 1000;


a 1 & pi & 300, (1 & i & N );
a 0 & ai $ 1000, (1 & i & N );
a 3 & K & 300;
a Pentru prima cerinµ  rezolvat  corect se acord  40% din punctaj; pentru a doua cerinµ 
rezolvat  corect se acord  30% din punctaj; pentru a treia cerinµ  rezolvat  corect se acord  30%
din punctaj;
a R spunsurile la cele trei cerinµe vor  scrise exact pe linia indicat ; în cazul în care nu
cunoa³teµi rezolvarea la una dintre cerinµe, pe linia respectiv  se va scrie valoarea 1;
a Fiecare linie din ³ierul de intrare se termin  cu caracterul sfâr³it de linie.

Exemple
onigim.in onigim.out Explicaµii
6 4 200 150 100 100 175 200 Sunt 4 elevi care au punctajul mai mic decât punc-
100 150 175 200 4 tajul elevului cu id-ul 1, 2 elevi cu punctajul mai
4 2 0 0 3 4 2 mic decât punctajul elevului cu id-ul 2, etc.
Cele mai mari 3 punctaje sunt obµinute de 4 elevi.
Num rul maxim de elevi care au acela³i punctaj
este 2.

Timp maxim de executare/test: 0.1 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 5 KB

19.2.1 *Indicaµii de rezolvare


list , tablou, tablou vector (unidimensional), tablou vector caracteristic (de frecvenµ )

19.2.2 *Cod surs 

19.2.3 *Rezolvare detaliat 

19.3 Extraprime
Problema 3 - Extraprime 100 de puncte
Gigel, mare amator de probleme de matematic  ³i informatic , a observat c  unele numere
prime au o proprietate interesant : orice cifr  ar elimina dintr-un astfel de num r, num rul obµinut
este tot num r prim. A numit astfel de numere numere extraprime. De exemplu, num rul 317
este un num r extraprim: el este num r prim ³i, în plus, dac  elimin m cifra 3, obµinem 17, care
este prim; dac  elimin m 1, obµinem 37, care este prim; dac  elimin m 7, obµinem 31, care este ³i
el num r prim.

Cerinµe
Spunem c  x este între a ³i b dac  x'a ³i x & b. Fiind date dou  valori naturale a ³i b, s  se
determine câte numere extraprime exist  între a ³i b, precum ³i cel mai mic ³i cel mai mare num r
extraprim dintre a ³i b.

Date de intrare
Pe prima linie a ³ierului de intrare extraprime.in se g sesc cele dou  valori naturale a ³i b,
separate printr-un spaµiu.

Date de ie³ire
CAPITOLUL 19. ONI 2013 277

Fi³ierul de ie³ire extraprime.out va avea 3 linii.


Pe prima linie se va scrie un num r natural nr reprezentând num rul de numere extraprime
dintre a ³i b.
Pe linia a doua a ³ierului de ie³ire se va scrie cel mai mic num r extraprim dintre a ³i b, iar
pe linia a treia a ³ierului de ie³ire se va scrie cel mai mare num r extraprim dintre a ³i b.

Restricµii ³i preciz ri
a 10 $ a & b $ 10000000
a Num rul 1 nu este prim.
a Pentru datele de test exist  întotdeauna soluµie.

Exemple
extraprime.in extraprime.out Explicaµii
10 100 4 Se a  4 numere extraprime mai mari decât 10 ³i mai
23 mici decât 100: 23, 37, 53 ³i 73.
73

Timp maxim de executare/test: 1.1 secunde


Memorie: total 32 MB din care pentru stiv  32 MB
Dimensiune maxim  a sursei: 15 KB

19.3.1 *Indicaµii de rezolvare


matematic 

19.3.2 *Cod surs 

19.3.3 *Rezolvare detaliat 


Capitolul 20

ONI 2012

20.1 culegere
Problema 1 - culegere 100 de puncte
O culegere de probleme are P pagini, numerotate de la 1 la P.
Problemele din culegere sunt numerotate cu 1, 2, 3, ..., etc, în ordi-
nea apariµiei lor în culegere.
Pe prima pagin  a culegerii este scris  o singur  problem  (cea cu
num rul 1).
Pe a doua pagin  sunt scrise exact dou  probleme (cele cu numerele Figura 20.1: culegere
2 ³i 3, în aceast  ordine).
Pe cea de-a treia pagin  sunt scrise exact trei probleme (cele cu numerele 4, 5 ³i 6, în aceast 
ordine), ..., pe cea de a P -a pagin  sunt scrise exact P probleme.

Cerinµe
Scrieµi un program care cite³te numerele naturale P ³i N ³i determin  valorile:
a) T, num rul total de cifre care au fost utilizate în numerotarea tuturor problemelor din
culegere;
b) M, num rul minim de pagini pe care ar trebui s  le aib  culegerea, astfel încât aceasta s 
conµin  ³i problema numerotat  cu N.

Date de intrare
Fi³ierul culegere.in conµine pe prima linie cele dou  numere naturale P ³i N , separate printr-
un spaµiu, cu semnicaµia din enunµ.

Date de ie³ire
Fi³ierul culegere.out conµine:
a pe prima linie num rul natural T , cu semnicaµia din enunµ;
a pe a doua linie num rul natural M , cu semnicaµia din enunµ.

Restricµii ³i preciz ri
a 1 & P & 16000;
a 1 & N & 2112600000;
a pentru rezolvarea corect  a cerinµei a) se acord  50% din punctaj;
a pentru rezolvarea corect  a cerinµei b) se acord  50% din punctaj.

Exemple

278
CAPITOLUL 20. ONI 2012 279

culegere.in culegere.out Explicaµii


5 9 21 Problemele sunt numerotate cu numerele:
4 a 1 (pagina 1)

a 2, 3 (pagina 2)

a 4, 5, 6 (pagina 3)

a 7, 8, 9, 10 (pagina 4)

a 11, 12, 13, 14, 15 (pagina 5).

În scrierea acestor numere s-au folosit 21 de cifre => T 21.


Pentru a conµine ³i problema cu num rul 9, culegerea trebuie s 
aib  minimum 4 pagini => M 4.

Timp maxim de executare/test: 0.1 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 10 KB

20.1.1 Indicaµii de rezolvare


prof. Carmen Minc , Colegiul Naµional de Informatic  Tudor Vianu, Bucure³ti

O soluµie care obµine 100p poate  construit  pe baza urm torului algoritm:

Cerinµa a)
a Se determin  num rul total nt de exerciµii pe care le poate conµine culegerea de P pagini:

nt  P ˜ P  1©2

Se observ  c  nt & 16000 ˜ 16001©2 128008000


a Se determin  num rul k de cifre din scrierea zecimal  a lui nt (k & 9)

Figura 20.2: culegereIR1

a Se determin  num rul T total de cifre utilizate în scrierea tuturor numerelor naturale nenule
cel mult egale cu nt, observând c :

Figura 20.3: culegereIR2

Figura 20.4: culegereIR3


CAPITOLUL 20. ONI 2012 280

Cerinµa b)
a Se determin  cel mai mic num r natural M cu proprietatea c  1  2  3  ...  M ' N. Acesta
va reprezenta num rul minim de pagini cerut.

Figura 20.5: culegereIR4

20.1.2 Cod surs 

Listing 20.1.1: culegere_2.cpp

1 //prof.Carmen Minca
2
3 #include <fstream>
4
5 using namespace std;
6
7 int main()
8 { long long nt,p10=1,k=0,M,i,T=0, P,N,x;
9
10 ifstream f("culegere.in");
11 ofstream g("culegere.out");
12
13 f>>P>>N;
14
15 nt=P*(P+1)/2;
16 x=nt;
17 while(x)
18 {
19 k++; x/=10;
20 }
21
22 for(i=1;i<k;i++)
23 {
24 T=T+i*p10;
25 p10*=10;
26 }
27
28 T=T*9+(nt-p10+1)*k;
29 g<<T<<endl;
30
31 long long probl=0;
32 for(M=1;probl+M<N;M++)
33 probl+=M;
34
35 g<<M<<endl;
36
37 return 0;
38 }

Listing 20.1.2: culegere_3.cpp

1 //prof.Carmen Minca
2 //solutie care depaseste continutul programei de gimnaziu
3
4 #include <fstream>
5 #include <cmath>
6
7 using namespace std;
8
9 int main()
10 {
11 long long n,p=1,k,i,nrc=0, P,N;
12
13 ifstream f("culegere.in");
CAPITOLUL 20. ONI 2012 281

14 ofstream g("culegere.out");
15
16 f>>P>>N;
17
18 n=P*(P+1)/2;
19 k=log10(n*1.0);
20 k++;
21
22 for(i=1;i<k;i++)
23 {
24 nrc=nrc+i*p;
25 p*=10;
26 }
27
28 nrc=nrc*9+(n-p+1)*k;
29 g<<nrc<<endl;
30 long long pag=1;
31 if(N>1)
32 {
33 pag=(-1+sqrt(1.+8*N))/2;
34 if(pag*(pag+1)<2*N)pag++;
35 }
36 g<<pag<<endl;
37 return 0;
38 }

20.1.3 *Rezolvare detaliat 

20.2 culori
Problema 2 - culori 100 de puncte
Fiecare dintre cei N copii, numerotaµi de la 1 la N , prime³te câte un cartona³ colorat. Doamna
dirigint  îi a³eaz  în cerc, în ordinea numerot rii, în sens orar. Astfel, ecare copil are doi vecini,
a³ezaµi în stânga, respectiv în dreapta lui.
Andrei, pasionat de informatic , asociaz  ec rei culori distincte un cod, reprezentat printr-un
num r natural nenul, ³i inscripµioneaz  ecare cartona³ cu codul corespunz tor culorii acestuia.

Cerinµe
Scrieµi un program care cite³te dou  numere naturale N ³i K ³i determin  pentru Andrei:
a) num rul copiilor din cerc care au cartona³e de aceea³i culoare cu cartona³ele vecinilor;
b) num rul maxim de cartona³e de aceea³i culoare ce sunt deµinute de copiii a³ezaµi pe K
poziµii consecutive în cercul format.

Date de intrare
Fi³ierul de intrare culori.in conµine pe prima linie numerele naturale N ³iK , separate printr-
un spaµiu, ³i pe ecare dintre urm toarele N linii, câte un num r natural. Cele N numere repre-
zint  codurile culorilor cartona³elor, în ordinea numerot rii copiilor, începând cu copilul 1.

Date de ie³ire
Fi³ierul de ie³ire culori.out conµine:
a pe prima linie, num rul natural determinat la cerinµa a);
a pe a doua linie, num rul natural determinat la cerinµa b).

Restricµii ³i preciz ri
a 2$N & 1000;
a 2$K & N;
a codurile culorilor sunt numere naturale nenule, consecutive, mai mici sau egale cu 100;
a dac  C este codul maxim asociat unei culori (1 & C & 100) atunci exist  cel puµin C cartona³e
care au codurile distincte: 1, 2, 3, ..., C ;
a se acord  30% din punctaj pentru rezolvarea corect  a cerinµei a);
a se acord  70% din punctaj pentru rezolvarea corect  a cerinµei b).
CAPITOLUL 20. ONI 2012 282

Exemple
culori.in culori.out Explicaµii
8 5 2
Sunt doi copii care au, ecare, car-
3 4
tona³e identice cu cei doi vecini (co-
1
pilul 5 ³i copilul 8).
2
Num rul maxim de cartona³e de
1
aceea³i culoare deµinute de copiii
1
1
a³ezaµi pe K 5 poziµii consecutive
în cercul format este 4 (dintre copiii
3
2, 3, 4, 5, 6 doar copiii 2, 4, 5 ³i 6 au
3
cartona³e de culoarea 1). Figura 20.6: culori

Timp maxim de executare/test: 0.1 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 10 KB

20.2.1 Indicaµii de rezolvare


prof. Adriana Simulescu, Liceul GRIGORE MOISIL Timi³oara

O soluµie se poate obµine astfel:


Codurile culorilor cartona³elor se citesc în vectorulx. Pe m sur  ce se citesc aceste coduri se
calculeaz  num rul de copii nrc care au cartona³e de aceea³i culoare cu cea a cartona³elor vecinilor
³i num rul de culori c determinând maximul din valorile vectorului x.
Pentru rezolvarea cerinµei b) vectorul x se dubleaz  astfel: xN  1 x1, xN  2 x2,
..., x2 ˜ N  1 xN  1

Figura 20.7: culoriIR1

Calcul m num rul pentru cerinµa b) astfel:


Pentru copiii cu numerele de ordine de la 1 la K am construit vectorul de apariµii ale codurilor
culorilor cartona³elor ap ³i se determin  num rul maxim de apariµii maxck .
CAPITOLUL 20. ONI 2012 283

Figura 20.8: culoriIR2

Pentru urm toarele secvenµe de k (i 2, 3, ..., N ) copii al turaµi scad din vectorul de apariµii
prezenµa culorii cartona³ului copiluluii  1 ³i adun prezenµa culorii cartona³ului copilului i  K  1.
Pentru ecare secvenµ  se actualizeaz  maximul cu elementele din vectorul de apariµii.

Figura 20.9: culoriIR3

20.2.2 Cod surs 

Listing 20.2.1: culori_1.cpp

1 //prof.Adriana Simulescu
2 #include<fstream>
3
4 using namespace std;
5
6 int x[2001],apc[101],N,k,c,nrc,apc1[101],maxck,nrck,nrmax,nrmaxk;
7
8 ifstream fin("culori.in");
9 ofstream fout("culori.out");
10
11 void citire()
12 {int i;
13 fin>>N>>k;
14 fin>>x[1];
15 x[N+1]=x[1];
16 c=x[1];
17 fin>>x[2];
18 x[N+2]=x[2];
19 if(x[2]>c)c=x[2];
20
21 for(i=3;i<=N;i++)
22 {fin>>x[i];
23 x[N+i]=x[i];
24 if(x[i]>c)c=x[i];
25 if(x[i-1]==x[i-2]&&x[i]==x[i-1])
26 nrc++;
27 }
28 if(x[1]==x[N]&&x[N]==x[N-1])
29 nrc++;
30 if(x[1]==x[2]&&x[1]==x[N])
31 nrc++;
32 }
33
34 int main()
35 {int i,j;
36 citire();
37 maxck=0;
38 for(i=1;i<=k;i++)
39 {apc1[x[i]]++;
40 if(apc1[x[i]]>maxck)
41 maxck=apc1[x[i]];
CAPITOLUL 20. ONI 2012 284

42 }
43
44 for(i=2;i<=N;i++)
45 {apc1[x[i-1]]--;
46 apc1[x[i+k-1]]++;
47
48 for(j=1;j<=c;j++)
49 if(apc1[j]>maxck)
50 maxck=apc1[j];
51
52 }
53
54 fout<<nrc<<endl<<maxck<<endl;
55
56 fin.close();fout.close();
57 return 0;
58 }

Listing 20.2.2: culori_2.cpp

1 //prof.Sanda Junea
2 #include <fstream>
3 #include <iostream>
4
5 using namespace std;
6
7 ifstream f("culori.in");
8 ofstream g("culori.out");
9
10 int n,k,c[2001],a[2001],nrc,maxc,maxcc,c_max;
11
12 int main()
13 {int i,j;
14 f>>n>>k;
15 for(i=1;i<=n;i++)
16 {
17 f>>c[i];
18 if(c[i]>c_max)
19 c_max=c[i];
20 }
21 for(i=n+1;i<=n+n;i++)
22 {
23 c[i]=c[i-n];
24 }
25 for(i=2;i<n;i++)
26 if(c[i-1]==c[i] && c[i]==c[i+1])nrc++;
27 if(c[n]==c[n-1] && c[n]==c[1])nrc++;
28 if(c[1]==c[2] && c[1]==c[n])nrc++;
29 g<<nrc<<endl;
30
31 for(i=1;i<=k;i++)
32 a[c[i]]++;
33 maxc=0;
34 for(i=1;i<=c_max;i++)
35 if(a[i]>maxc)
36 maxc=a[i];
37 for(j=k+1;j<=n+n;j++)
38 {
39 a[c[j-k]]--; a[c[j]]++;
40 if(maxc>maxcc)
41 maxcc=maxc;
42 for(i=1;i<=c_max;i++)
43 if(a[i]>maxc)
44 maxc=a[i];
45 }
46 g<<maxcc;
47 f.close();g.close();
48 return 0;
49 }

20.2.3 *Rezolvare detaliat 


CAPITOLUL 20. ONI 2012 285

20.3 stele
Problema 3 - stele 100 de puncte
•ara Numerelor Fermecate era un µinut minunat!
Pân  ³i stelele de pe cer erau numerotate cu numere
naturale nenule distincte! Stelele f ceau parte din Con-
stelaµia Numerelor ³i erau aranjate într-un roi în form 
de triunghi, pe coloane ³i pe rânduri în cadrul ec rei
coloane, ca în desenul al turat. Stelele cu numerele 1,

3, 7, 13, 21, 31, ..., situate pe rândul marcat cu în


desen, formau centrul roiului de stele.
Coloanele din roi erau numerotate de la stânga la
dreapta, începând cu num rul 1, iar rândurile din cadrul
ec rei coloane erau numerotate de jos în sus, începând
cu num rul 1 (ca în desen).
Legenda spune c , pe vremuri, tr ia în µara Nume-
relor Fermecate o vr jitoare deosebit de rea ³i de puter-
nic . Tot ceea ce atingea aceast  vr jitoare cu bagheta
Figura 20.10: stele
magic  se pref cea în stan  de piatr . Ea î³i propusese
s -i preschimbe în statui pe toµi copiii din µinut.
În acea vreme înv µa la ³coal  Numerel, un b ieµel vrednic ³i curajos. Îl iubea toat  lumea!
Zâna Cea Bun  s-a hot rât s  îl ajute pe Numerel. Aceasta i-a promis inimosului b iat o baghet 
magic , pe care Numerel s  o foloseasc  împotriva vr jitoarei. Pentru a primi bagheta, Numerel
a cules pulberea celei de a K -a stele situat  în centrul roiului pentru a i-o da Zânei.
Dar aventura a continuat! Zâna locuia pe steaua cu num rul N, iar Numerel a trebuit s 
g seasc  adresa acesteia, respectiv num rul coloanei, precum ³i num rul rândului din coloan , pe
care se g sea aceast  stea.
Aventura voastr  abia acum începe!

Cerinµe
Scrieµi un program care cite³te dou  numere naturale K ³i N ³i determin  pentru Numerel:
a) num rul celei de a K -a stele situat  în centrul roiului;
b) coloana ³i rândul (din aceast  coloan ) corespunz toare adresei Zânei.

Date de intrare
Fi³ierul de intrare stele.in conµine pe prima linie cele dou  numere naturale, K ³i N , separate
printr-un spaµiu.

Date de ie³ire
Fi³ierul de ie³ire stele.out conµine:
a pe prima linie, num rul natural determinat la punctul a);
a pe a doua linie, coloana ³i rândul determinate la punctul b), în aceast  ordine, separate
printr-un spaµiu.

Restricµii ³i preciz ri
a 0 $ K & 60000;
a 0 $ N & 60000;
a se acord  20% din punctaj pentru rezolvarea corect  a cerinµei a);
a se acord  80% din punctaj pentru rezolvarea corect  a cerinµei b).

Exemple
stele.in stele.out Explicaµii
5 3 21 Primele K 5 stele din centrul roiului au numerele: 1, 3, 7, 13, 21 .
2 2 Steaua cu num rul N 3 se a  pe coloana 2 , rândul 2 .

2 5 3 3 5 Primele K 2 stele din centru roiului au numerele: 1, 3 .

Steaua cu num rul N 5 se a  pe coloana 3 , rândul 5 .

Timp maxim de executare/test: 0.5 secunde


Memorie: total 2 MB din care pentru stiv  2 MB
Dimensiune maxim  a sursei: 10 KB
CAPITOLUL 20. ONI 2012 286

20.3.1 Indicaµii de rezolvare


prof. Gina Balacea, Colegiul Naµional Vasile Alecsandri - Galaµi

O soluµie pentru 100p se poate obµine astfel:


a Se aranjeaz  numerele 1, 2, 3, 4, ... în form  de triunghi, astfel:

Figura 20.11: steleIR

a Se observ  c  num rul de jos al ec rei coloane i (nr. stelei de pe rândul 1, coloana i) este
2
p tratul perfect al num rului coloanei = i .
2
a Toate numerele de pe linia din mijloc se obµin cu formula i  i  1, unde i este num rul
2 2 2
coloanei: 3 2  2  1; 7 3  3  1; 13 4  4  1. Prin urmare, al K -lea element se determin 
2
cu formula K  K  1.
a Dat ind un num r N, se poate g si num rul rândului ³i al coloanei din triunghi, dup  cum
urmeaz :
Coloana = cel mai mic num r natural al c rui p trat perfect este mai mare sau egal ca N.
2
Rândul = Coloana N  1.
De exemplu, pentru N 6, avem : 2
2
$ 6 & 32 . Prin urmare coloana este 3 iar rândul este
2
3  31 7
a Nu este necesar ca datele s  e memorate într-un tabel.

20.3.2 Cod surs 

Listing 20.3.1: stele_1.cpp

1 //prof.Gina Balacea
2 #include<cstdio>
3
4 using namespace std;
5
6 unsigned long long i,j,n,K,N;
7
8 int main()
9 {FILE *f,*g;
10 f=fopen("stele.in","r");
11 g=fopen("stele.out","w");
12 fscanf(f,"%I64d %I64d",&K,&n);
13 fprintf(g,"%I64d\n",K*K-K+1);
14 N=1;
15 while(N*N<n) N++;
16 fprintf(g,"%I64d %I64d\n",N,N*N-n+1);
17 fclose(f);
18 fclose(g);
19 return 0;
20 }
CAPITOLUL 20. ONI 2012 287

Listing 20.3.2: stele_2.cpp

1 //prof.Liliana Chira
2 #include<cstdio>
3 #include<cmath>
4 int main()
5 {
6 unsigned long long c,l,N,K,p;
7
8 freopen("stele.in","r",stdin);
9 freopen("stele.out","w",stdout);
10
11 scanf("%I64d%I64d",&K,&N);
12 printf("%I64d\n",K*K-K+1);
13
14 p=(int)sqrt(N);
15 if(N==p*p)
16 c=p;
17 else c=p+1;
18 l=c*c-N+1;
19 printf("%I64d %I64d\n",c,l);
20
21 printf("\n");
22 return 0;
23 }

Listing 20.3.3: stele_3.cpp

1 //prof.Sanda Junea
2 #include<fstream>
3 #include<iostream>
4
5 using namespace std;
6
7 ifstream f("stele.in");
8 ofstream g("stele.out");
9
10 int k,n;
11 int main()
12 {
13 int i;
14 unsigned long long x;
15 f>>k>>n;
16 x=(unsigned long long)(k-1)*(k-1)+(k*k-(k-1)*(k-1)+1)/2;
17 g<<x<<endl;
18 i=1;
19 while(i*i<n)i++;
20 if(i*i==n)
21 g<<i<<" "<<1<<endl;
22 else
23 g<<i<<" "<<(i*i-n+1);
24 return 0;
25 }

20.3.3 *Rezolvare detaliat 


Capitolul 21

ONI 2011

21.1 Fagure
Problema 1 - Fagure 100 de puncte
Bunicul lui Ionel este apicultor ³i din acest motiv Ionel a vrut s  combine pasiunea lui pentru
numere cu meseria bunicului. El a a³ezat n numere sub forma unui ³ir de nr faguri, numerotaµi
de la 1 la nr. În cadrul unui fagure numerele au fost a³ezate în sensul rotirii acelor de ceasornic.
Pe latura comun  a doi faguri el a³eaz  numai dou  numere.
Mihuµ, fratele lui Ionel, ca s  fac  o glum  a amestecat numerele din faguri astfel: a luat
cel mai mare num r prim din al doilea fagure ³i l-a schimbat cu cel mai mare num r prim din
penultimul fagure (cu num rul de ordine nr  1), apoi a luat cel mai mare num r prim din al
treilea fagure ³i l-a schimbat cu cel mai mare num r prim din antepenultimul fagure (cu num rul
de ordine nr  2), continu  a³a pân  la mijlocul ³irului de faguri.
Mihuµ nu s-a atins de numerele care f ceau parte din latura comun  a doi faguri al turaµi.
Dac  în cadrul unui fagure Mihuµ nu a g sit un num r prim ce poate  mutat, atunci nu a realizat
interschimbarea în cadrul perechii de faguri corespunz toare.
Exemplu:
Ionel a plecat de la 18 numere:
2 11 37 14 5 12 17 101 97 26 3 19 13 5 130 7 213 907
³i le-a a³ezat conform modelului din gura 1. Modelul din gura 2 a rezultat dup  ce Mihuµ
a amestecat numerele. Mihuµ nu are voie s  amestece numerele: 11, 37, 101, 97, 19, 13.

Figura 21.1: fagure

Cerinµe
Scrieµi un program care s  citeasc  informaµiile din ³ierul de intrare fagure.in ³i care s 
determine:
a) num rul fagurilor pe care a reu³it Ionel s  îi construiasc ;
b) cel mai mic num r de ordine al fagurelui pe care Ionel a plasat valoarea x, înainte de
amestecarea realizat  de Mihuµ;
c) pentru un num r natural k , citit din ³ier, care este noul num r plasat de Mihuµ pe fagurele
cu num rul de ordine k. Dac  Mihuµ nu s-a atins de numerele de pe fagurele k se va scrie valoarea
0.

Date de intrare
Fi³ierul de intrare fagure.in conµine trei linii:
- pe prima linie se a  perechea de numere naturale n ³i k separate printr-un spaµiu cu sem-
nicaµiile din enunµ;

288
CAPITOLUL 21. ONI 2011 289

- a doua linie conµine cele n numere naturale nenule mai mici decât 32000, separate prin câte
un spaµiu, cu care Ionel a construit fagurii;
- pe ultima linie din ³ier se a  num rul natural x cu semnicaµia din enunµ. Valoarea x se
reg se³te în ³ier ³i pe linia a doua.

Date de ie³ire
Fi³ierul de ie³ire fagure.out va conµine trei linii:
a) pe prima linie se va scrie num rul natural nr ce reprezint  num rul fagurilor construiµi de
Ionel;
b) pe a doua linie se va scrie num rul de ordine minim al fagurelui pe care a fost plasat 
valoarea x. în cazul în care valoarea x se g se³te pe latura comun  a doi faguri al turaµi, se vor
a³a numerele de ordine ale celor doi faguri în ordinea cresc toare a valorilor, separate printr-un
spaµiu;
c) pe a treia linie se va scrie num rul pe care Mihuµ l-a plasat pe fagurele k dup  ce a amestecat
numerele sau valoarea 0 dac  nu s-a atins de fagurele k.

Restricµii ³i preciz ri
a Pentru toate testele, ultimul fagure construit de Ionel, este format din 6 numere.
a 10 & n $ 10000
a 2 & k & cu num rul de ordine al fagurelui din mijloc
a 1 & x $ 30000
a Pentru rezolvarea cerinµei a) se acord  30% din punctaj, pentru rezolvarea cerinµei b) 40%
din punctaj ³i pentru rezolvarea cerinµei c) 30% din punctaj.

Exemple
fagure.in fagure.out Explicaµii
18 2 4 4 reprezint  num rul fa-
2 11 37 14 5 12 17 101 97 26 3 19 13 5 130 7 213 907 2 3 gurilor construiµi de Ionel;
101 5 101 aparµine fagurilor 2 ³i
3; 5 reprezint  valoarea
plasat  de Mihuµ pe fagu-
rele 2.

Timp maxim de executare/test: 1.0 secunde

21.1.1 Indicaµii de rezolvare


prof. Daniela Taras  - Colegiul Naµional Gheorghe Vr nceanu Bac u
prof. Gavril Petru Florin - Colegiul Naµional Roman Vod  Roman

Punctul a): Fiecare fagure conµine dou  valori comune cu fagurele anterior la care se adaug 
alte patru valori. Num rul fagurilor se obµine cu urm toarea formul :
a nr n  2©4;
Punctul b): Pentru a determina num rul minim de ordine al fagurelui pe care se aa iniµial
valoarea x, se va realiza o c utare secvenµial , determinând poziµia primei apariµii a valorii x.
Dac  valoarea x este g sit  pe latura comuna a doi faguri, atunci se a³eaz  numerele de ordine
a celor doi faguri (în ordinea cresc toare a lor).
Se trateaz  separat cazul în care valoarea x apare în primul fagure sau în ultimul.

Punctul c): pentru a determina valoarea rezultat  dup  amestecare, se determin :


a num rul de ordine al fagurelui simetric cu fagurele k;
a primalitatea valorilor ce pot  amestecate;
a cea mai mare dintre valorile prime ce pot  amestecate.

În cazul în care fagurele k sau nr  k  1 nu conµine valori prime ce pot  amestecate, se va


scrie în ³ierul de ie³ire valoarea 0.
CAPITOLUL 21. ONI 2011 290

21.1.2 Cod surs 

Listing 21.1.1: fagure.cpp

1 #include<fstream>
2 #include<math.h>
3
4 using namespace std;
5
6 ifstream f("fagure.in");
7 ofstream g("fagure.out");
8
9 int v[10001];
10
11 int prim (int x)
12 {
13 long d;
14 if(x<2) return 0;
15 for(d=2;d<=sqrt(x);d++)
16 if(x%d==0) return 0;
17 return 1;
18 }
19
20
21 int main()
22 { int n,i,nr_fag,k,gasit=0,grupa,nr,poz,fag,x1,x2,x;
23 f>>n>>k;
24 for(i=1;i<=n;i++)
25 f>>v[i];
26 f>>x;
27
28 // cerinta 1 calculam si afisam numarul fagurilor construiti
29 nr_fag=(n-6)/4+1;
30 g<<nr_fag<<’\n’;
31
32 // cerinta 2 cautam prima aparitie a lui x in v
33 for(i=1;i<=n &&!gasit;i++)
34 if(v[i]==x) {gasit=1;poz=i;}
35
36 // verificam si afisam numarul sau numerele fagurilor din care face parte x
37 if(poz<=6)
38 if(poz==2 ||poz==3) g<<1<<’ ’<<2<<’\n’;
39 else g<<1<<’\n’;
40
41 else
42 if(poz==n-1 || poz==n-2) g<<nr_fag<<’\n’;
43 else
44 if((poz%4==0 || poz%4==1) && poz/4<nr_fag)
45 g<<poz/4<<’ ’<<poz/4+1<<’\n’;
46 else
47 if(poz%4==3) g<<poz/4+1<<’\n’;
48 else g<<poz/4<<’\n’;
49
50 // cerinta 3
51 // fagurele pe care s-a gasit initial numarul prim este
52 fag=nr_fag+1-k;
53
54 // discutam despre pozitiile fag*4-1, fag*4+2 pentru ca de pozitiile
55 // fag*4 si fag*4+1 nu avem voie sa ne atingem
56 // notam cu x1 si x2 pozitiile pe care le verificam
57 x1=fag*4-1;
58 x2=fag*4+2;
59
60 if(prim(v[x1])&& prim(v[x2]))
61 if(v[x1]>v[x2]) g<<v[x1]<<’\n’;
62 else g<<v[x2]<<’\n’;
63 else
64 {
65 if(prim(v[x1])) g<<v[x1]<<’\n’;
66
67 if (prim(v[x2])) g<<v[x2]<<’\n’;
68 }
69
70 if(prim(v[x1])==0 && prim(v[x2])==0)
CAPITOLUL 21. ONI 2011 291

71 g<<0<<’\n’;
72
73 f.close();
74 g.close();
75 return 0;
76 }

21.1.3 *Rezolvare detaliat 

21.2 Goe
Problema 2 - Goe 100 de puncte
Goe este un copil dr g la³, dar tare lene³.
Nu îi place nici s  scrie, nici s  numere. Cu
greu a fost convins de mama sa s  înveµe cifrele,
dar de scris tot nu poate s  le scrie pe toate. Nu
îi plac cifrele 2, 4, 5 ³i 7, iar cifra 6 o încurc  cu
9 ³i invers. “i asta nu este tot. Când mama sa îi
d  s  copieze numere, pentru a exersa scrierea
cifrelor, el le scrie în oglind , adic  scrie cifrele
în ordinea invers . De exemplu num rul 138
va  scris de Goe 831.
Mama lui Goe scrie în ecare zi, în or-
dine cresc toare, câte 9 numere naturale, s - Figura 21.2: Goe
rind îns  peste orice num r divizibil cu 10, ca în Figura 1. Goe copiaz  zilnic aceste numere. Din
p cate, el nu î³i îndreapt  niciuna dintre gre³eli: copiaz  numerele scriindu-le oglindite, nu scrie
numerele care conµin cifrele 2, 4, 5 ³i 7 ³i înlocuie³te, în continuare cifra 6 cu 9 ³i invers (vezi
Figura 2).

Cerinµe
Scrieµi un program care s  citeasc  numerele naturale nenule k, p ³i n ³i care s  determine:
a) Num rul de numere scrise de Goe în primele k zile;
b) Al p-lea palindrom scris corect de Goe; un num r este palindrom dac  este egal cu oglinditul
s u;
c) Cel mai mare num r scris de Goe în primele n zile.

Date de intrare
Fi³ierul goe.in conµine o singur  linie pe care sunt scrise trei numere naturale k, p ³i n, separate
prin câte un spaµiu.

Date de ie³ire
Fi³ierul de ie³ire goe.out va conµine 3 linii:
a) pe prima linie, se va scrie num rul de numere scrise de Goe în primele k zile;
b) pe a doua linie, se va scrie un num r natural reprezentând al p-lea palindrom scris corect
de Goe;
c) pe a treia linie, se va scrie cel mai mare num r scris de Goe în primele n zile.

Restricµii ³i preciz ri
a 1 & k & 100000
a 1 & p & 750
a 1 & n & 32000000
Pentru rezolvarea cerinµei a) se acord  40% din punctaj, pentru cerinµa b) 30% din punctaj ³i
pentru cerinµa c) 30% din punctaj.
CAPITOLUL 21. ONI 2011 292

Exemple
goe.in goe.out Explicaµii
5 15 15 numere a scris Goe în primele 5 zile.
8 111 Primele 8 palindroame scrise corect de Goe sunt:
3 91 1, 3, 8, 11, 33, 88, 101, 111.
Cel mai mare num r scris de Goe în primele 3 zile este 91.

Timp maxim de executare/test: 1.0 secunde

21.2.1 Indicaµii de rezolvare


prof. Ana Întuneric, C.N. "Ferdinand I" Bac u
prof. Dana Lica, C.N. "I.L.Caragiale" Ploie³ti

Cerinµa a):
Goe scrie într-o zi 5 numere sau niciunul. Este sucient s  se numere câte dintre primele k
numere naturale strict pozitive (zile) nu au în componenµ  una dintre cifrele 2, 4, 5 sau 7 ³i s  se
înmulµeasc  acest num r cu 5.

Cerinµa b):
Un palindrom scris corect de Goe conµine doar cifrele 0, 1, 3 ³i 8. El scrie 3 palindroame cu o
singur  cifr , 3 palindroame cu 2 cifre, 9 palindroame cu 3 cifre, 12 palindroame cu 12 cifre etc.
Deci num rul de palindroame se multiplic  cu 4 de ecare dat  când se trece de la un palindrom
cu un num r par de cifre la unul cu un num r impar de cifre (2c 2c  1).
Se determin  iniµial nrc, num rul de cifre pe care le are cel de-al p-lea palindrom, apoi se con-
struiesc, pe rând, palindroamele de nrc cifre pân  la cel de-al p-lea palindrom. Pentru construcµie
se poate utiliza scrierea în baza 4, înlocuind ulterior cifra 2 cu 3 ³i cifra 3 cu 8 (0 0, 1 1,
2 3, 3 8).
Cerinµa c):
Se observ  c  num rul maxim scris de Goe are prima cifr  9. Pentru a determina celelalte
cifre, se memoreaz  cifrele num rul n într-un vector ³i se prelucreaz  pe rând cifrele sale. Vectorul
se a³eaz  în mod invers.

21.2.2 Cod surs 

Listing 21.2.1: GOE.CPP

1 #include <fstream>
2 #include <math.h>
3
4 using namespace std;
5
6 ifstream f("goe.in");
7 ofstream g("goe.out");
8
9 long n,k,p,bune,max,nrn,put,x,aux,nrbune,ok,d;
10 int s[11];
11 long v[11],sum,power;
12 long i,j,nr,nrcif,posib,nrc,schimbat,r,l,inv,pn,un,copie,cifra;
13
14 int main()
15 {
16 f>>k>>p>>n;
17 //a)**************************
18 nrn=0;
19 for(i=1;i<=k;i++)
20 {
21 aux=i-1;ok=1;
22 while(aux>0)
23 {
24 if(aux % 10 == 2 || aux % 10 == 4 ||
25 aux % 10 == 5 || aux % 10 == 7) ok=0;
26 aux/=10;
27 }
28
CAPITOLUL 21. ONI 2011 293

29 if(ok)nrn=nrn+5;
30 }
31 g<<nrn<<’\n’;
32
33 //b)**************************
34 nrc=1; d=3; //d reprezinta cate numere palindroame de nrc cifre exista
35 while(p>d)
36 {
37 p=p-d;
38 nrc++;
39 if(nrc%2) d=d*4;
40 }
41
42 //d este modificat o data la 2 pasi, intrucat numarul de palindroame este
43 // acelasi pentru o lungime de 2*k si 2*k+1
44 /*in p avem al catelea numar de nrc cifre trebuie sa determinam
45 in c construim palindromul, dar in baza 4, pentru a face iarasi o
46 bijectie intre baza 4 si o baza cu cifrele 0,1,3,8 (singurele cifre cu
47 care se pot construi palindroame)
48 */
49 v[1]=1; v[nrc]=1; d=d/3; p--;
50 for(i=2;i<nrc;i++) v[i]=0;
51
52 i=1;
53 while(d>0)
54 {
55 v[i]=v[nrc-i+1]=v[i]+p/d;
56 p=p%d;
57 d/=4;
58 i++;
59 }
60
61 //trecem numarul din baza 4 in scrierea necesara
62 for(i=1;i<=nrc;i++)
63 {
64 if(v[i]==2) v[i]=3;
65 else
66 if(v[i]==3) v[i]=8;
67 }
68
69 for(i=1;i<=nrc;i++) g<<v[i];
70 g<<’\n’;
71
72 //c)**************************
73 nrc=log10(n)+1;
74 i=nrc;
75
76 while(n>0)
77 {
78 s[i]=n%10;
79 n=n/10;
80 i--;
81 }
82
83 i=1;
84 if(s[1]==1)
85 {
86 i++;
87 while(i<=nrc && s[i]==0)i++;
88 }
89
90 if(i==nrc+1)
91 {
92 for(j=1;j<=nrc;j++)g<<’9’;
93 g<<’\n’;
94 }
95 else
96 {
97 g<<’9’;
98 if(s[i]>1 && i<nrc && s[i+1]<6 || s[i]==1 && s[i+1]<6 || s[i]!=9)
99 {
100 s[i]--;
101 if(s[i]==2 || s[i]==4 || s[i]==5 || s[i]==7) s[i]--;
102 if(s[i]==4) s[i]=3;
103 }
104
CAPITOLUL 21. ONI 2011 294

105 i++;
106 for(;i<=nrc;i++) s[i]=9;
107 for(i=nrc;i>=1;i--)
108 {
109 if(s[i]==6) s[i]=9;
110 g<<s[i];
111 }
112
113 g<<’\n’;
114 }
115
116 f.close();
117 g.close();
118 return 0;
119 }

21.2.3 *Rezolvare detaliat 

21.3 P pu³a
Problema 3 - P pu³a 100 de puncte
P pu³a Matrio³ka este o juc rie din lemn,
goal  pe din untru. De aceea, în interiorul s u
poate  introdus  oricare alt  p pu³  Matri-
o³ka de în lµime mai mic .
Figura 21.3: papusa
La un magazin de suveniruri se g sesc n
p pu³i Matrio³ka a³ezate în ³ir, în num r egal, pe dou  rafturi al turate. Pe raftul din stânga
sunt expuse prima jum tate de p pu³i, situate în ³ir pe poziµiile 1, 2, ...., n©2, iar raftul din
dreapta ultima jum tate de p pu³i, situate în ³ir pe poziµiile n©2  1, ..., n. Prin notaµia n©2
se înµelege jum tatea num rului n.
Ana ³i Iulia vor s  cumpere cât mai multe p pu³i Matrio³ka, dar tat l lor le impune urm toarele
reguli:
a Iulia are voie s  aleag  p pu³i din raftul din stânga, iar Ana din raftul din dreapta
a Dac  de pe un raft se cump r  mai multe p pu³i, atunci ele se vor aa pe poziµii consecutive
pe raft;
a Prima p pu³  cump rat  de o fetiµ  va avea în lµimea mai mic  decât cea de a doua, a
doua decât cea de a treia ³i a³a mai departe astfel încât ecare p pu³  s  poate  introdus  în
urm toarea p pu³  cump rat ;
a Ultimele p pu³i cump rate trebuie s  se situeze doar la capetele rafturilor ³i în plus:
- dac  ultima p pu³  cump rat  de Iulia este pe poziµia 1 atunci ultima p pu³  cump rat  de
Ana trebuie s  e pe poziµia n;
- dac  ultima p pu³  cump rat  de Iulia este pe poziµia n©2 atunci ultima p pu³  cump rat 
de Ana trebuie s  e pe poziµia n©2  1.

Pentru a putea s  aleag  cât mai multe p pu³i respectând regulile impuse de tat l lor, fetiµelor
li se permite s  execute în acela³i timp urm toarea operaµie, pân  se revine la a³ezarea iniµial  a
p pu³ilor:
a Iulia mut  p pu³a de pe poziµia 1 pe poziµia n©2, deplasând cu o poziµie spre stânga toate
celelalte p pu³i din raftul s u;
a Ana mut  p pu³a de pe poziµia n pe poziµia n©2  1, deplasând cu o poziµie spre dreapta
toate celelalte p pu³i din raftul s u;

Cerinµe
Pentru a le ajuta pe Iulia ³i Ana s  achiziµioneze împreun  un num r maxim de p pu³i, scrieµi
un program care cite³te un num r natural n ³i în lµimile celor n p pu³i ³i determin :
a) num rul M de operaµii efectuate concomitent de fetiµe;
b) num rul maxim P de p pu³i care vor  cump rate.

Date de intrare
CAPITOLUL 21. ONI 2011 295

Fi³ierul text papusa.in conµine pe prima linie un num r natural par n, reprezentând num rul
de p pu³i. Pe linia a doua sunt n numere naturale separate prin câte un spaµiu, reprezentând
în lµimile p pu³ilor situate pe cele dou  rafturi, în ordine de la poziµia 1 la n.

Date de ie³ire
Fi³ierul de ie³ire papusa.out va conµine:
a) pe prima linie, num rul natural M;
b) pe a doua linie, num rul natural P.

Restricµii ³i preciz ri
a 2 & n & 1000, n este num r par
a 1 & în lµimile p pu³ilor & 10000
a Dac  num rul maxim de p pu³i se obµine f r  a face operaµii de mutare atunci M 0
a Pentru toate testele de intrare exist  o singur  conguraµie pentru care se poate cump ra
un num r maxim de p pu³i
a Pentru rezolvarea cerinµei a) se acord  40% din punctaj, pentru rezolvarea cerinµei b) 60%
din punctaj

Exemple
papusa.in papusa.out Explicaµii
8 2 Raftul Iuliei conµine p pu³ile de în lµimi 5, 7, 2, 4, iar al Anei
5 7 2 4 6 10 14 8 7 p pu³ile de în lµimi 6, 10, 14, 8. Pe aceast  a³ezare Iulia ³i
Ana pot cump ra p pu³ile de în lµime 2 4 6 sau 5 8. Se pot
cump ra cel mult 3 p pu³i.
Conguraµia obµinut  dup  prima operaµie de mutare este: 7
2 4 5 8 6 10 14
Pe aceast  a³ezare Iulia ³i Ana pot cump ra p pu³ile de în l-
µime 2 4 5 6 8 sau 2 7 6 10 14. Se pot cump ra cel mult 5
p pu³i.
Conguraµia obµinut  dup  a doua operaµie 2 4 5 7 14 8 6 10.
Pe aceast  a³ezare Iulia ³i Ana pot cump ra p pu³ile cu în l-
µimile 2 4 5 7 6 8 14 sau 2 6 10. Deci se pot cump ra cel mult
7 p pu³i.
Conguraµia obµinut  dup  a treia operaµie 4 5 7 2 10 14 8 6.
Pe aceast  a³ezare Iulia ³i Ana pot cump ra p pu³ile cu în l-
µimile 2 10 sau 4 6. Deci se pot cump ra cel mult 2 p pu³i.
Num rul maxim de p pu³i cump rate este 7 ³i se obµine dup 
a doua operaµie de mutare.

Timp maxim de executare/test: 1.0 secunde

21.3.1 Indicaµii de rezolvare


prof. Susana G l µan

Se genereaz  concomitent toate permut rile circulare ale primei jum t µi a ³irului, respectiv
ale celei de a doua jum t µi. Pentru ecare permutare, se determin  urm toarele valori:
L1 - lungimea secvenµei descresc toare care începe la poziµia 1
L2 - lungimea secvenµei cresc toare care se termin  pe poziµia n
L3 - lungimea secvenµei cresc toare care se termin  pe poziµia n©2
L4 - lungimea secvenµei descresc toare care începe pe poziµia n©2  1
Num rul maxim de p pu³i cump rate este maximul dintre sumele L1  L2 ³i L3  L4.
Num rul de operaµii cerute este egal cu num rul de ordine a permut rii pentru care se obµine
num rul maxim de p pu³i.
CAPITOLUL 21. ONI 2011 296

21.3.2 Cod surs 

Listing 21.3.1: papusa.cpp

1 //Suzana Galatan
2 #include <fstream>
3
4 using namespace std;
5
6 int main()
7 {
8 ifstream fin("papusa.in");
9 ofstream fout("papusa.out");
10
11 int n, x[1001];
12 int l11, l22, ok = 1;
13
14 fin >> n;
15
16 int i, pas = 0, l1, l2, aux1, aux2, secv = 0, perm = 0;
17 for(i = 1; i <= n; i++)
18 fin >> x[i];
19
20 while(pas < n/2)
21 {
22
23 l1 = l2 = 1;
24 l11 = 1, l22 = 1;
25 ok = 1;
26 for(i = n/2-1; i > 0 && ok; i--)
27 if(x[i+1] > x[i])l1++;
28 else ok = 0;
29
30 ok = 1;
31 for(i = n/2+2; i <= n&&ok; i++)
32 if(x[i-1] > x[i])l2++;
33 else ok = 0;
34
35
36 if(secv < (l1+l2))secv = l1+l2, perm = pas;
37
38 ok = 1;
39 for(i = n-1; i >= n/2 && ok; i--)
40 if(x[i+1] > x[i])l22++;
41 else ok = 0;
42
43 ok = 1;
44 for(i = 2; i <= n/2 && ok; i++)
45 if(x[i-1] > x[i])l11++;
46 else ok = 0;
47
48 if(secv <(l11+l22))secv =l11+l22, perm = pas;
49
50 pas++;
51 aux1 = x[1];
52 aux2 = x[n];
53 for(i = 1; i < n/2; i++)
54 {
55 x[i] = x[i+1];
56 x[n-i + 1] = x[n-i];
57 }
58
59 x[n/2] = aux1;
60 x[n/2+1] = aux2;
61 }
62
63 fout << perm<<"\n"<< secv<<"\n";
64 fin.close();
65 fout.close();
66 return 0;
67 }
CAPITOLUL 21. ONI 2011 297

21.3.3 *Rezolvare detaliat 


Capitolul 22

ONI 2010

22.1 cluburi
Problema 1 - cluburi 100 de puncte
La ³coala Iuliei, în clasa a V-a sunt n elevi. Pentru c  a³a e moda la aceast  ³coal , ecare
dintre cei n copii ³i-a creat câte un club.
Fiecare club are iniµial un singur membru: copilul care l-a creat. Copiii au hot rât c  num rul
membrilor unui club poate s  creasc  prin unicarea cu un alt club dup  urm toarea regul :
dou  cluburi se pot unica dac  au acela³i num r de membri. Prin unicare, unul dintre cluburi
continu  s  existe, iar cel lalt se desinµeaz . Clubul care continu  s  existe preia toµi membrii
clubului care se desinµeaz .
Deoarece elevii se distreaz  mai bine atunci când clubul are mai mulµi membri, ei au hot rât
s  unice cluburile dup  regula de mai sus, cât timp unicarea este posibil .

Cerinµe
Scrieµi un program care s  citeasc  num rul natural n ³i care s  determine:
a) cel mai mic num r natural k de cluburi care continu  s  existe dup  ce s-au produs toate
unic rile;
b) pentru ecare dintre cluburi, num rul de membri.

Date de intrare
Fi³ierul de intrare cluburi.in conµine o singur  linie pe care este scris un num r natural nenul
n, reprezentând num rul de elevi din clasa a V-a.

Date de ie³ire
Fi³ierul de ie³ire cluburi.out va conµine:
- pe prima linie un num r natural k, reprezentând cel mai mic num r de cluburi care continu 
s  existe dup  ce s-au produs toate unic rile
- pe a doua linie, k numere naturale nenule, separate prin câte un spaµiu, reprezentând num rul
de membri ai ec rui club, în ordinea cresc toare a num rului de membri.

Restricµii ³i preciz ri
a 1 & n & 30000
a În cazul în care num rul elevilor este impar se consider  c  elevul r mas singur formeaz  un
club.
a Pentru ecare test de intrare se poate determina cel puµin un club.
a Se acord  punctaje parµiale: cerinµa a) 30% din punctaj, cerinµa b) 70% din punctaj

298
CAPITOLUL 22. ONI 2010 299

Exemple:
cluburi.in cluburi.out Explicaµii
7 3 6 elevi formeaz  3 cluburi având ecare câte 2 membri, iar elevul
1 2 4 r mas formeaz  la rândul lui un club (cu un singur membru).
Apoi 2 dintre cluburile cu câte 2 membri se unesc ³i formeaz  un
singur club cu 4 membri, deci sunt 3 cluburi: 1 cu un membru, 1
cu 2 membri ³i 1 cu 4 membri.
24 2 Iniµial se formeaz  12 cluburi cu câte 2 membri, apoi 6 cu câte 4
8 16 membri.
Din cele 6 cluburi se vor forma apoi 3 cu câte 8 membri.
Dou  dintre cluburile cu 8 membri se unesc formand unul cu 16
membri. în nal r mân 2 cluburi, unul cu 8, iar cel lalt cu 16
membri.

Timp maxim de executare/test: 1.0 secunde

22.1.1 Indicaµii de rezolvare


prof. G l µan Suzana - Inspectoratul ³colar Judeµean Bistriµa-N s ud

Descrierea soluµiei
Num rul de cluburi care se formeaz  este egal cu suma resturilor obµinute prin împ rµirea
repetat  a num rului n la 2, atât timp cât n este diferit de 0.

Figura 22.1: cluburiIR1

k1
Num rul de membri ai ec rui club este egal cu 2 , unde k este egal cu num rul de împ rµiri
la 2 al lui n ³i la acel pas n%2 este egal cu 1.

Figura 22.2: cluburiIR2

Exemplu: Pentru n 13 se obµine:


r 1 0 1 1
k1 0 1 2 3
2 2 2 2 2
Num r membri 1 - 4 8
CAPITOLUL 22. ONI 2010 300

Figura 22.3: cluburiIR3

22.1.2 Cod surs 

Listing 22.1.1: cluburi_CS.cpp

1 //autor Sichim Cristina - 100p


2
3 #include<fstream>
4 #include <cstring>
5
6 using namespace std;
7
8 int main()
9 { int n,k=0,i;
10 long p=1;
11 char s[50];
12
13 ifstream f("cluburi.in");
14 ofstream g("cluburi.out");
15
16 f>>n;
17 itoa(n,s,2);
18
19 for(i=0;i<strlen(s);i++)
20 if(s[i]==’1’)k++;
21
22 g<<k<<’\n’;
23
24 for(i=strlen(s)-1;i>=0;i--)
25 {
26 if(s[i]==’1’) g<<p<<’ ’;
27 p=p*2;
28 }
29
30 g<<’\n’;
31
32 f.close();g.close();
33 return 0;
34 }

Listing 22.1.2: cluburi_fara_vectori.CPP


CAPITOLUL 22. ONI 2010 301

1 //autor Suzana Galatan


2 #include <fstream>
3
4 using namespace std;
5
6 ifstream fin("cluburi.in");
7 ofstream fout("cluburi.out");
8
9 int main()
10 {
11 int N;
12 fin >> N ;
13 int k = 0, c = N, cant = 1;
14
15 int x = N;
16 while(x)
17 {
18 if(x % 2 == 1)k++;
19 x = x/2;
20 }
21
22 fout << k <<"\n";
23
24 while(c)
25 {
26 if(c % 2 == 0)
27 c = c/2, cant = cant * 2;
28 else
29 {
30 c = c/2;
31 fout << cant <<" ";
32 cant = cant * 2;
33 }
34 }
35
36 fout << "\n";
37
38 fin.close();
39 fout.close();
40 return 0;
41 }

Listing 22.1.3: cluburi_SG.CPP

1 //autor Suzana Galatan -100p


2 #include <fstream>
3 using namespace std;
4
5 ifstream fin("cluburi.in");
6 ofstream fout("cluburi.out");
7 int main()
8 {
9 long int N;
10 fin >> N ;
11
12 long int nr = 0, c = N, cant = 1, gasit = 0, c1;
13 int x[100] = {0};
14
15 while(c)
16 {
17 if(c % 2 == 0)
18 c = c/2, cant = cant * 2;
19 else
20 {
21 /* if(gasit == 0)
22 {
23 c1 = cant;
24 gasit = 1;
25 } */
26 nr = nr + 1;
27 c = c/2;
28 x[nr] = cant;
29 cant = cant * 2;
30 }
31 }
CAPITOLUL 22. ONI 2010 302

32
33 fout << nr <<"\n";
34
35 // fout << c1 << " " << cant/ 2 <<"\n";
36
37 for(int i = 1; i < nr; i++)
38 fout << x[i] << " ";
39
40 fout << x[nr] << ’\n’;
41
42 fin.close();
43 fout.close();
44 return 0;
45 }

22.1.3 *Rezolvare detaliat 

22.2 domino
Problema 2 - domino 100 de puncte
Ionel are n piese de domino de diverse în lµimi. În joac , el a³eaz  piesele vertical într-un ³ir
(pe o rigl  gradat ), la distanµe nu neap rat egale una faµ  de alta. Ionel atinge prima pies ,
aceasta cade ³i poate antrena în c dere dup  ea ³i alte piese din ³ir. Dac  mai r mân piese în
picioare, el merge la prima pies  care nu a c zut ³i o atinge. Aceasta cade ³i poate antrena în
c dere dup  ea ³i alte piese. Continu  procedeul pân  când nu mai r mâne nicio pies  în picioare.

Cerinµe
Scrieµi un program care s  citeasc  num rul natural n de piese, poziµia pe rigl  ³i în lµimea
ec rei piese, în aceast  ordine, ³i care s  determine num rul minim necesar de atingeri ale pieselor
astfel încât s  cad  toate piesele de domino precum ³i num rul maxim de piese r sturnate la o
singur  atingere.

Date de intrare
Fi³ierul de intrare domino.in conµine:
- pe prima linie num rul natural n
- pe ecare dintre urm toarele n linii câte dou  numere naturale p ³i h, separate printr-un
spaµiu, p reprezentând pozitia piesei pe rigl  ³i h în lµimea piesei de domino, în acest  ordine.

Date de ie³ire
Fi³ierul de ie³ire domino.out va conµine o singur  linie pe care sunt scrise dou  numere
naturale a ³i b, în aceast  ordine, separate printr-un spaµiu, a reprezentând num rul minim necesar
de atingeri ale pieselor, iar b num rul maxim de piese ce sunt r sturnate la o singur  atingere a
unei piese.

Restricµii ³i preciz ri
a Numerele n, p ³i h sunt numere naturale nenule
a 1 & n & 1000; 1 & p & 5000; 1 & h & 5000
a O pies  de domino aat  pe pozitia p de în lµime h r stoarn  piese pân  la poziµia ph
inclusiv.
a În ³ierul de intrare datele sunt în ordinea cresc toare a poziµiei pieselor de domino.
a Pe o poziµie de pe rigl  se poate aa o singur  pies  de domino.
a Ionel începe întotdeauna cu piesa a³ezat  la poziµia cea mai mic 
a Se acord  50 din punctaj pentru rezolvarea corect  a ec rei cerinµe.
CAPITOLUL 22. ONI 2010 303

Figura 22.4: domino

Exemple:
domino.in domino.out Explicaµii
5 2 3 La atingerea primei piese vor c dea primele dou  piese;
10 10 Atingea piesei de pe poziµia 27 r stoarn  piesa de pe poziµia
14 10 28 iar aceasta o r stoarn  ³i pe ultima.
27 2 Num rul de atingeri este 2 iar num rul maxim de piese
28 10 doborâte la o atingere este 3.
37 5

Timp maxim de executare/test: 1.0 secunde

22.2.1 Indicaµii de rezolvare


prof. Adriana Simulescu, Liceul Grigore Moisil Timi³oara

Descrierea soluµiei
Soluµia propus  memoreaz  în variabila dist poziµia maxim  la care acµioneaz  o pies  care a
c zut, în variabila nd num rul de piese doborâte la o atingere ³i în nmax num rul maxim de piese
doborâte la o atingere.

Pentru ecare pies  de domino se veric  dac  este doborât  de o pies  anterioar , se ac-
tualizeaz  num rul de piese doborâte la atingerea curent  ³i poziµia pân  la care se doboar  în
continuare alte piese.
CAPITOLUL 22. ONI 2010 304

Figura 22.5: dominoIR

22.2.2 Cod surs 

Listing 22.2.1: domino_AS_1.CPP

1 // Simulescu Adriana -100p


2 #include<fstream>
3
4 using namespace std;
5
6 struct domino{int h,p;};
7
8 domino d[1001];
9 int n,nd,dmax,nmax,nr,dist;
10
11 ifstream f("domino.in");
12 ofstream g("domino.out");
13
14 int main()
15 { int i;
16
17 f>>n;
18 for(i=1;i<=n;i++)
19 f>>d[i].p>>d[i].h;
20
21 f.close();
22
23 dist=0;
24 for(i=1;i<=n;i++)
25 if(d[i].p>dist||nd==0)
26 {
27 nd++;
28 if(nr>nmax) nmax=nr;
29 dist=d[i].p+d[i].h;
30 nr=1;
31 }
32 else
33 {
34 nr++;
35 if(dist< d[i].p+d[i].h )
36 dist=d[i].p+d[i].h;
37 }
38
39 if(nr>nmax) nmax=nr;
CAPITOLUL 22. ONI 2010 305

40
41 g<<nd<<" "<<nmax;
42 g.close();
43 return 0;
44 }

Listing 22.2.2: domino_AS_2.CPP

1 //Simulescu Adriana -100p


2 #include<fstream>
3
4 using namespace std;
5
6 int n,nd,dmax,nmax,nr,dist,h,p;
7
8 ifstream f("domino.in");
9 ofstream g("domino.out");
10
11 int main()
12 {
13 int i;
14
15 f>>n;
16 dist=0;
17 nd=0;
18 for(i=1;i<=n;i++)
19 {
20 f>>p>>h;
21
22 if(p>dist)
23 {
24 nd++;
25 if(nr>nmax) nmax=nr;
26 dist=p+h;
27 nr=1;
28 }
29 else
30 {
31 nr++;
32 if(dist< p+h )
33 dist=p+h;
34 }
35 }
36
37 if(nr>nmax) nmax=nr;
38 g<<nd<<" "<<nmax;
39 g.close();
40
41 return 0;
42 }

Listing 22.2.3: domino_CM.CPP

1 // Carmen Minca -100p


2 #include<fstream>
3
4 using namespace std;
5
6 ifstream fi("domino.in");
7 ofstream fo("domino.out");
8
9 struct interval
10 {
11 int a, b, nr;
12 }
13 v[5000];
14
15
16 int comun(int a, int b, int c, int d)
17 { if ((b<c)||(d<a)) return 0;
18 return 1;
19 }
20
21 void rez(int a, int b, int c, int d, int &e, int &f)
CAPITOLUL 22. ONI 2010 306

22 { e=a;
23 if(e>c) e=c;
24 f=b;
25 if(f<d) f=d;
26 }
27
28 int main()
29 {
30 int N,p,h,i,k=0,j,max=1,ok;
31
32 fi>>N;
33 fi>>p>>h;
34 k++;
35 v[k].a=p;
36 v[k].b=p+h;
37 v[k].nr=1;
38
39 for(i=2;i<=N;i++)
40 {
41 fi>>p>>h;ok=0;
42 for(j=1;(j<=k)&&(ok==0);j++)
43 if(comun(v[j].a,v[j].b,p,p+h))
44 {
45 rez(v[j].a, v[j].b,p,p+h,v[j].a,v[j].b);
46 v[j].nr++;
47 if(max<v[j].nr)max=v[j].nr;
48 ok=1;
49 }
50
51 if(ok==0)
52 { k++;
53 v[k].a=p; v[k].b=p+h;
54 v[k].nr=1;
55 }
56 }
57
58 fo<<k<<’ ’<<max;
59 fi.close();
60 fo.close();
61
62 return 0;
63 }

Listing 22.2.4: domino_CS.CPP

1 // Cristina Sichim - 100p


2 # include <fstream>
3
4 using namespace std;
5
6 int main()
7 {
8 ifstream f("domino.in");
9 ofstream g("domino.out");
10
11 int N,p,h,a=1,b=1,nrb=1,i,unde;
12
13 f>>N;
14 f>>p>>h;
15 unde=p+h;
16
17 for(i=2;i<=N;i++)
18 {
19 f>>p>>h;
20 if(p<=unde)
21 {
22 nrb++;
23 if(p+h>unde) unde=p+h;
24 }
25 else
26 {
27 if (nrb>b) b=nrb;
28 nrb=1;a++;
29 unde=p+h;
30 }
CAPITOLUL 22. ONI 2010 307

31 }
32
33 if(nrb>b) b=nrb;
34
35 g<<a<<’ ’<<b;
36 f.close();
37 g.close();
38 return 0;
39 }

Listing 22.2.5: domino_SG.CPP

1 //Suzana Galatan - 100p


2 #include <fstream>
3
4 using namespace std;
5
6 ifstream fin("domino.in");
7 ofstream fout("domino.out");
8
9 int main()
10 {
11 int x[1000];
12 int p, h, smax = 1, pf, i, sfin = 1, buf = 1;
13 int n;
14
15 fin >> n;
16 fin >> p >> h;
17 pf = p + h;
18
19 for(i = 2; i <= n; i++)
20 {
21 fin >> p >> h;
22 if(pf >= p)
23 {
24 smax++;
25 if(p + h > pf)pf = p + h;
26 }
27 else
28 {
29 smax = 1;
30 buf++;
31 pf = p + h;
32 }
33
34 if(sfin < smax) sfin = smax;
35 }
36
37 fout << buf << " " <<sfin;
38 fout <<"\n";
39
40 return 0;
41 }

22.2.3 *Rezolvare detaliat 

22.3 max
Problema 3 - max 100 de puncte
Fie n un num r natural nenul ³i un ³ir de n numere naturale nenule, ecare num r din ³ir
având cel mult 3 cifre. “irul dat se maximizeaz  prin aplicarea urm toarelor transform ri:

T1: Fiecare num r y din ³ir este înlocuit cu cel mai mare num r care se poate obµine prin
aranjarea tuturor cifrelor lui y. De exemplu, pentru y 102, prin aranjarea cifrelor, se obµin
numerele: 12, 21, 102, 120, 201, 210, cel mai mare num r ind 210. Astfel, y se va înlocui în ³ir
cu num rul 210.
CAPITOLUL 22. ONI 2010 308

T2: Se schimb  ordinea numerelor din ³irul obµinut dup  aplicarea transform rii T1 astfel
încât num rul x obµinut prin alipirea tuturor numerelor din ³ir, în ordinea în care apar dup 
schimbare, s  e cel mai mare posibil.

De exemplu, pentru n 3 ³i ³irul: 12, 132, 102, dup  aplicarea transform rii T1 noul ³ir este
format din numerele: 21, 321, 210. Din acest ³ir, se pot obµine, prin schimbarea ordinii numerelor,
urm toarele 6 ³iruri: 1) 21, 321, 210; 2) 21, 210, 321; 3) 321, 21, 210; 4) 321, 210, 21; 5) 210, 21,
321; 6) 210, 321, 21.

Numerele care rezult  prin alipirea numerelor din ecare ³ir obµinut sunt:
1) 21321210; 2) 21210321; 3) 32121210; 4) 32121021; 5) 21021321; 6) 21032121.

Dup  aplicarea transform rii T 2, ³irul maximizat este: 321, 21, 210 deoarece cel mai mare
num r dintre cele 6 obµinute este x 32121210.

Cerinµe
Scrieµi un program care s  citeasc  num rul natural nenul n ³i cele n numere naturale nenule
din ³ir ³i care s  determine:

a) cel mai mare num r m din ³irul de numere obµinut în urma aplic rii transform rii T 1;
b) num rul x obµinut prin alipirea numerele din ³irul maximizat rezultat în urma aplic rii
transform rii T 2.

Date de intrare
Fi³ierul de intrare max.in conµine dou  linii. Pe prima linie este scris num rul natural nenul
n, iar pe a doua linie sunt scrise cele n numere naturale nenule din ³ir, separate prin câte un
spaµiu.

Date de ie³ire
Fi³ierul de ie³ire max.out va conµine:
- pe prima linie num rul natural m, reprezentând cel mai mare num r din ³irul de numere
obµinut în urma aplic rii transform rii T1
- pe a doua linie num rul natural x, reprezentând num rul obµinut prin alipirea numerelor din
³irul maximizat, rezultat în urma aplic rii transform rii T 2.

Restricµii ³i preciz ri
a Num rul n este num r natural 2 & n & 3500
a Cele n numere din ³irul citit sunt numere naturale nenule, ecare num r din ³ir având cel
mult 3 cifre
a Dac  un num r din ³ir are cel puµin o cifr  nul  iar prin aranjarea cifrelor acestui num r se
obµine un alt num r care are prima cifr  0, atunci aceast  cifr  se ignor 
a Num rul natural x determinat poate avea cel mult 10500 de cifre
a Se acord  punctaje parµiale: cerinµa a) 20% din punctaj, cerinµa b) 80% din punctaj

Exemple
max.in max.out Explicaµii
9 321 Dup  aplicarea transform rii T1, ³irul
34 23 9 43 21 67 121 79 213 9977643433232121211 devine: 43, 32, 9, 43, 21, 76, 211, 97,
321. Cel mai mare num r din acest ³ir
este m=321. Dup  aplicarea transfor-
m rii T2, ³irul maximizat este: 9, 97,
76, 43, 43, 32, 321, 21, 211 iar num rul
x 9977643433232121211

Timp maxim de executare/test: 1.0 secunde


CAPITOLUL 22. ONI 2010 309

22.3.1 Indicaµii de rezolvare


prof. Carmen Minc , Liceul Teoretic Ion Neculce - Bucure³ti

Descriere soluµie
O soluµie posibil  se poate obµine prin utilizarea a doi vectori v ³i p, ecare având maxim 3500
de componente întregi.

În vectorul v se vor memora numerele din ³irul obµinut în urma transform rii T 1, rezultate
din numerele din ³ierul de intrare. Acestea pot  citite succesiv într-o variabil  x.
Pentru ecare num r memorat în x se separ  cifrele, se ordoneaz  descresc tor aceste cifre
iar num rul obµinut se memoreaz  în v i. În acela³i timp se memoreaz  în componenta pi
k
valoarea pi 10 , unde k reprezint  num rul de cifre ale lui v i, pi ind util  în construirea
numerelor rezultate prin alipirea a dou  valori din vectorul v.
În timp ce se aplic  T 1, se determin  ³i valoarea maxim  din ³irul obµinut.

Pentru a obµine ³irul maximizat rezultat din T 2, se poate utiliza un algoritm de sortare, de
exemplu sortarea prin selectarea maximului.

Pentru ecare i 1, .., n  1 ³i j i  1.., n se construiesc cele dou  numere rezultate prin prin
alipirea, în aceast  ordine, a numerelor v i ³i v j , respectiv v j  ³i v i, adic  v i ˜ pj   v j 
³i v j  ˜ pi  v i. Se selecteaz  maximul dintre aceste valori.

Num rul x cerut se obµine prin alipirea tuturor numerelor din ³irul maximizat. Acest lucru se
realizeaz  prin scrierea în ³ierul de ie³ire a tuturor numerelor din ³irul maximizat, în ordinea din
acest ³ir, f r  spaµii între numere.

Figura 22.6: maxIR1


CAPITOLUL 22. ONI 2010 310

Descriere soluµie - prof. Cristina Sichim, C.N. Ferdinand I Bac u

O alt  soluµie posibil  pentru rezolvarea cerinµei b) utilizeaz  un vector caracteristic v cu 999
de elemente.

Pentru ecare cifr  x (de la 9 la 1) se a³eaz  mai întâi cifra de un num r de ori egal cu
valoarea v x din vectorul caracteristic.

În continuare, în ordine descresc toare se a³eaz  numerele y cu dou  cifre care au prima cifr 
x, dup  ecare dintre ele a³ându-se, în ordine descresc toarele numerele cu trei cifre ce au ca
prex num rul y.

Figura 22.7: maxIR2

22.3.2 Cod surs 

Listing 22.3.1: MAX_CM.CPP

1 //prof.Carmen Minca - 100p


2 #include <fstream>
3
4 using namespace std;
5
6 int main()
7 {
8 int n, v[3505], p[3505];
9 long d,e;
10 int i, max=0,x,a,b,c,j;
11
CAPITOLUL 22. ONI 2010 311

12 ifstream f("max.in");
13 ofstream g("max.out");
14
15 f>>n;
16 for(i=1;i<=n;i++)
17 { f>>x; v[i]=x;
18 if(x<10) p[i]=10;
19 else
20 if(x<100)
21 { a=x/10; b=x%10; p[i]=100;
22 if (a<b)v[i]=b*10+a;
23 }
24 else
25 { a=x/100; x=x%100; b=x/10; c=x%10;p[i]=1000;
26 if(a<b) { x=a; a=b; b=x;}
27 if(a<c) { x=a; a=c; c=x;}
28 if(b<c) { x=b; b=c; c=x;}
29 v[i]=100*a+10*b+c;
30 }
31 if(max<v[i])max=v[i];
32 }
33
34 g<<max<<endl;
35
36 for(i=1;i<n;i++)
37 for(j=i+1;j<=n;j++)
38 { d=v[i];d=d*p[j]+v[j];
39 e=v[j]; e=e*p[i]+v[i];
40 if (d<e)
41 {
42 x=v[i]; v[i]=v[j]; v[j]=x;
43 x=p[i]; p[i]=p[j]; p[j]=x;
44 }
45 }
46
47 for(i=1;i<=n;i++) g<<v[i];
48
49 g.close();
50 return 0;
51 }

Listing 22.3.2: MAX_CS.CPP

1 //prof. Cristina Sichim -100p


2
3 #include<fstream>
4
5 using namespace std;
6
7 int n,v[1001],i,x,aux,maxx,y,z,a,b,c;
8
9 int main()
10 {
11 ifstream f("max.in");
12 ofstream g("max.out");
13 f>>n;
14
15 for(i=1;i<=n;i++)
16 {
17 f>>x;
18 if(x>9 && x<100 && x/10<x%10) x=x%10*10+x/10;
19 if(x>99)
20 {
21 a=x%10;b=x/10%10;c=x/100;
22 if(a<b) {aux=a;a=b;b=aux;}
23 if(a<c) {aux=a;a=c;c=aux;}
24 if(b<c) {aux=b;b=c;c=aux;}
25 x=a*100+b*10+c;
26 }
27
28 v[x]++;
29 if(maxx<x) maxx=x;
30 }
31
32 g<<maxx<<’\n’;
CAPITOLUL 22. ONI 2010 312

33
34 for(x=9;x>0;x--)
35 {
36 //toate care incep cu cifra x
37 while(v[x]--) g<<x; //cele de o cifra
38 for(y=x*10+9;y>=x*10;y--)
39 {
40 while(v[y]--)g<<y;
41 for(z=y*10+x;z>=y*10;z--)
42 while(v[z]--)g<<z;
43 }
44 }
45
46 g<<’\n’;
47 f.close();
48 g.close();
49 return 0;
50 }

Listing 22.3.3: MAX_SG.CPP

1 //prof. Suzana Galatan -100p


2 #include <fstream>
3
4 using namespace std;
5
6 void Sorteaza();
7 int maxim(int nr);
8 void Afiseaza();
9
10 ifstream fin ("max.in");
11 ofstream fout("max.out");
12
13 int n, max2, m;
14 int c[1001];
15
16 int main()
17 {
18 int nr, m = 0, max2 = 0;
19 fin >> n;
20 for(int i = 1; i <= n; i++)
21 {
22 fin >> nr;
23 nr = maxim(nr);
24
25 c[nr]++;
26 if(nr > m) m = nr;
27 if(nr < 100 && nr > 9)
28 {
29 if(max2 < nr) max2 = nr;
30 }
31 }
32
33 fout << m;
34 fout << "\n";
35 // Sorteaza();
36 Afiseaza();
37
38 fin.close();
39 fout.close();
40 return 0;
41 }
42
43 int maxim(int nr)
44 {
45 int a[10] = {0};
46 while(nr)
47 {
48 a[nr%10]++;
49 nr/=10;
50 }
51 for(int i = 9; i >= 0; i--)
52 while(a[i])
53 {
54 nr = nr*10 + i;
CAPITOLUL 22. ONI 2010 313

55 a[i]--;
56 }
57 return nr;
58 }
59
60 void Afiseaza()
61 {
62 int i = 9, j, k;
63 /* for(i = 999; i >= 0; i--)
64 while(c[i])
65 {fout<< i<< " ";
66 c[i]--;
67 }*/
68
69 for(i = 9;i > 0; i--)
70 for(j = i*10 +9; j >= i*10; j--)
71 for(k = j*10+9; k >= j*10; k--)
72 {
73 while(c[i])
74 {
75 if(i >= j /10 || i >= k/100)
76 {
77 fout << i;
78 c[i]--;
79 }
80 }
81
82 while(c[j])
83 if(j >= k/10)
84 {
85 fout << j;
86 c[j]--;
87 }
88
89 while(c[k])
90 {
91 fout << k;
92 c[k]--;
93 }
94 }
95 }

22.3.3 *Rezolvare detaliat 


314
Anexa A

Un pic de matematic !

A.1 ...

A.1.1 Prezentare general 

...

A.1.2 Exemple

...

315
Anexa B

Un pic de programare!

B.1 ...

B.1.1 Prezentare general 

...

B.1.2 Exemple

...

316
Glosar

¶ ¶, 227, 233, 248 long long pz[], 17


'¯n', 242
(char)('A'+i), 242 matematic , 275

... ? ... : ..., 145 max, 17

&&, 234, 248 maximul, 230

³ir sortat, 266 memset, 233

³irul Fibonacci, 189 minimul, 230

18 cifre, 230
num r de divizori, 46, 212

algoritm de sortare, 309 num r prim, 220

alipirea numerelor, 309 num rul de cifre, 309

assert, 4 numere economice, 189


numere mari, 207, 230
baza 4, 292
bool prim(long long x), 17 ofstream, 12

break, 245 ordonare, 217, 266, 309

case, 245 p strare indicii elementelor ordonate, 217

cel mai mic palindrom, 72 palindrom, 291

char nrmin[40]=, 238 permut ri circulare, 46, 295

citire caracter, 241 precalcul, 266

ciurul lui Eratostene, 187, 190 prex, 310

concatenare, 230 printf, 4

contor, 3 printf(%llu ¯n,Y);, 234

default, 245 r sturnare num r, 72

dep ³ire valoare maxim , 71 reverse, 268

descompunere în factori primi, 212


scanf, 4
divizori, 46
scanf(%lld %lld ¯n,&x, &y);, 234

endl, 17 short int, 112


sizeof, 233
factor prim, 212 sort, 268, 271
frecvenµa de apariµie, 266 sortare, 217
freopen, 4, 234 strcmp, 238
strcpy, 238
generare în baza 4, 266 strlen, 238
structur  repetitiv , 9
I.d.k.: suma Gauss, 212
I don't know who the author is., v swap, 271
I64d, 286 switch, 245, 264
ifstream, 12 break, 264
int comp(...), 233 case, 264
int compar(int v1[],int v2[]), 237
int nrc(long long x), 17 tablou unidimensional, 254, 266
int v[40]=0;, 237 tipul întreg, 19
islower, 242 tipul caracter, 19
trage cu tunul, iv
list , 276
long long, 17 unsigned long long, 231, 287

317
GLOSAR 318

unsigned long long x, y, Y, X;, 234 void aduna(...), 233


void copie(int v1[], int v2[]), 237
vector, 214, 220, 221, 241, 292, 309
vector caracteristic, 126, 276, 310
vector de frecvenµ , 186, 187, 241 X=(x<y ? y-x: x-y);, 234
Bibliograe
[1] Aho, A., Hopcroft, J., Ullman, J.D.; Data strutures and algorithms, Addison Wesley, 1983

[2] Andreica M.I.; Elemente de algoritmic  - probleme ³i soluµii, Cibernetica MC, 2011

[3] Andonie R., Gârbacea I.; Algoritmi fundamentali, o perspectiv  C++, Ed. Libris, 1995

[4] Atanasiu, A.; Concursuri de informatic . Editura Petrion, 1995

[5] Bell D., Perr M.; Java for Students, Second Edition, Prentice Hall, 1999

[6] Calude C.; Teoria algoritmilor, Ed. Universit µii Bucure³ti, 1987

[7] Cerchez, E., “erban, M.; Informatic  - manual pentru clasa a X-a., Ed. Polirom, 2000

[8] Cerchez, E.; Informatic  - Culegere de probleme pentru liceu, Ed. Polirom, 2002

[9] Cerchez, E., “erban, M.; Programarea în limbajul C/C++ pentru liceu, Ed. Polirom, 2005

[10] Cori, R.; Lévy, J.J.; Algorithmes et Programmation, Polycopié, version 1.6;
http://w3.edu.polytechnique.fr/informatique/
[11] Cormen, T.H., Leiserson C.E., Rivest, R.L.; Introducere în Algoritmi, Ed Agora, 2000

[12] Cormen, T.H., Leiserson C.E., Rivest, R.L.; Pseudo-Code Language, 1994

[13] Cristea, V.; Giumale, C.; Kalisz, E.; Paunoiu, Al.; Limbajul C standard, Ed. Teora, Bucure³ti,
1992

[14] Erickson J.; Combinatorial Algorithms; http://www.uiuc.edu/~jeffe/

[15] Flanagan, D.; Java in a Nutshell, O'Reilly, 1997.

[16] Giumale C., Negreanu L., C linoiu S.; Proiectarea ³i analiza algoritmilor. Algoritmi de sortare,
Ed. All, 1997

[17] Halim S., Halim F., Competitive programming, 2013

[18] Knuth, D.E.; Arta program rii calculatoarelor, vol. 1: Algoritmi fundamentali, Ed. Teora,
1999.

[19] Knuth, D.E.; Arta programarii calculatoarelor, vol. 2: Algoritmi seminumerici, Ed. Teora,
2000.

[20] Knuth, D.E.; Arta programarii calculatoarelor, vol. 3: Sortare ³i c utare, Ed. Teora, 2001.

[21] Knuth, D.E.; The art of computer programming, vol. 4A: Combinatorial algorithms, Part 1,
Addison Wesley, 2011.

[22] Lambert,K. A., Osborne,M.; Java. A Framework for Programming and Problem Solving,
PWS Publishing, 1999

[23] Laaksonen A.; Guide to competitive programming, Springer, 2017

[24] Livovschi, L.; Georgescu H.; Analiza ³i sinteza algoritmilor. Ed. Enciclopedic , Bucure³ti,
1986.

[25] Niemeyer, P., Peck J.; Exploring Java, O'Reilly, 1997.

319
BIBLIOGRAFIE 320

[26] Od gescu, I., Smeureanu, I., “tef nescu, I.; Programarea avansat  a calculatoarelor personale,
Ed. Militar , Bucure³ti 1993

[27] Od gescu, I.; Metode ³i tehnici de programare, Ed. Computer Lobris Agora, Cluj, 1998

[28] Popescu Anastasiu, D.; Puncte de articulaµie ³i punµi în grafuri, Gazeta de Informatic  nr.
5/1993

[29] R bâea, A.;


https://math.univ-ovidius.ro/Doc/Admitere/CentruPregatire/
2007/Info/Lista_probleme_2000-2007.pdf
[30] R bâea, A.;
https://math.univ-ovidius.ro/Doc/Admitere/CentruPregatire/
2007/Info/Rezolvari_C09.pdf

[31] R bâea, A.;


https://math.univ-ovidius.ro/Doc/Admitere/CentruPregatire/
2007/Info/Rezolvari_C10.pdf
[32] R bâea, A.;
https://math.univ-ovidius.ro/Doc/Admitere/CentruPregatire/
2007/Info/Rezolvari_C11.pdf

[33] R bâea, A.;


https://math.univ-ovidius.ro/Doc/Admitere/CentruPregatire/
2007/Info/Rezolvari_Baraj.pdf
[34] Skiena S.S., Revilla M.A.; Programming challenges - The Programming Contest Training
Manual, Springer, 2003

[35] Tomescu, I.; Probleme de combinatoric  ³i teoria grafurilor, Editura Didactic  ³i Pedagogic ,
Bucure³ti, 1981

[36] Tomescu, I.; Leu, A.; Matematic  aplicat  în tehnica de calcul, Editura Didactic  ³i Pedago-
gic , Bucure³ti, 1982

[37] Tudor, S.; Informatic  - prolul real intensiv, varianta C++; Editura L&S, Bucure³ti, 2004

[38] Tudor, S.; Hutanu, V,; Informatic  intensiv; Editura L&S, Bucure³ti, 2006

[39] V duva, C.M.; Programarea in JAVA. Microinformatica, 1999

[40] Vi³inescu, R.; Vi³inescu, V.; Programare dinamic  - teorie ³i aplicaµii; GInfo nr. 15/4 2005

[41] Vlada, M.; Conceptul de algoritm - abordare modern , GInfo, 13/2,3 2003

[42] Vlada, M.; Grafuri neorientate ³i aplicaµii. Gazeta de Informatic , 1993

[43] Vlada, M.; Gândirea Algoritmic  - O Filosoe Modern  a Matematicii ³i Informaticii, CNIV-
2003, Editura Universit µii din Bucure³ti, 2003

[44] Weis, M.A.; Data structures and Algorithm Analysis, Ed. The Benjamin/Cummings Pu-
blishing Company. Inc., Redwoods City, California, 1995.

[45] Winston, P.H., Narasimhan, S.; On to JAVA, Addison-Wesley, 1996

[46] Wirth N.; Algorithms + Data Structures = Programs, Prentice Hall, Inc 1976

[47] *** - Gazeta de Informatic , Editura Libris, 1991-2005

[48] *** -
https://github.com/DinuCr/CS/blob/master/Info/stuff%20stuff/Re
zolvari_C09.pdf
[49] *** - https://dokumen.tips/documents/rezolvaric09.html

[50] *** - https://www.scribd.com/doc/266218102/Rezolvari-C09


[51] *** - https://www.scribd.com/document/396362669/Rezolvari-C10
[52] *** - https://www.scribd.com/document/344769195/Rezolvari-C11
[53] *** - https://www.scribd.com/document/364077679/Rezolvari-C11-pdf

[54] *** - https://needoc.net/rezolvari-c11-pdf


BIBLIOGRAFIE 321

[55] *** - https://vdocumente.com/algoritmi-i-structuri-de-date.html


[56] *** -
https://pdfslide.net/documents/algoritmi-si-structuri-de-date-
1-note-de-cuprins-1-oji-2002-clasa-a-ix-a-1-11.html
[57] *** - https://www.infoarena.ro/ciorna

[58] *** - https://infoarena.ro/olimpici


[59] *** - https://www.infogim.ro/
[60] *** - https://www.pbinfo.ro/

[61] *** - http://www.cplusplus.com/


[62] *** - http://www.cplusplus.com/doc/tutorial/operators/
[63] *** - http://www.info1cup.com/
[64] *** - http://www.olimpiada.info/

[65] *** - http://www.usaco.org/


[66] *** - http://algopedia.ro/
[67] *** - http://campion.edu.ro/
[68] *** - http://varena.ro/
[69] *** - http://rmi.lbi.ro/rmi_2019/
[70] *** - https://codeforces.com/
[71] *** - https://cpbook.net/
[72] *** - https://csacademy.com/
[73] *** - https://gazeta.info.ro/revigoram-ginfo/
[74] *** - https://oj.uz/problems/source/22
[75] *** - https://profs.info.uaic.ro/~infogim/2019/index.html
[76] *** - https://wandbox.org/
[77] *** - https://en.cppreference.com/w/cpp/language/operator_alternative
[78] *** - https://en.cppreference.com/w/cpp/algorithm

[79] *** - https://www.ejoi2019.si/


[80] *** - https://en.wikipedia.org/wiki/Algorithm
[81] *** - https://en.wikipedia.org/wiki/List_of_algorithms
[82] *** - https://en.wikipedia.org/wiki/List_of_data_structures
Lista autorilor
problemelor ³i indicaµiilor

Adriana Simulescu, 197, 282, 303 Flavius Boian, 46, 186


Ana Întuneric, 92, 292 Florentina Ungureanu, 261
Ana-Maria Ari³anu, 162, 212
Gavril Petru Florin, 289
Carmen Minc , 42, 99, 187, 279, 309 Gina Balacea, 286
Cerasela-Daniela Carda³, 53, 206
Cristian Frâncu, 71, 212 Jakab Irma-Tunde, 59
Cristina Iordaiche, 178
Cristina Sichim, 144, 310 Lucia Miron, 106

Dan Pracsiu, 216 Marinel “erban, 108


Dana Lica, 155, 292 Marius Nicoli, 66, 214
Daniela T taru, 184
Daniela Taras , 289 Nicoleta “andor, 190

Emanuela Cerchez, 190 Susana G l µan, 295, 299

322

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