Documente Academic
Documente Profesional
Documente Cultură
date la olimpiade
în
2020
2019 2018 2017 2016 2015
2014 2013 2012 2011 2010
la clasa a 5-a
9 decembrie 2020
Dedicaµie
1
to myself ...
in a time when ...
I will not be able ...
2
to be.
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 !
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.
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 ... !!!
https://stats.ioinformatics.org/halloffame/
https://stats.ioinformatics.org/tasks/
http://stats.ioinformatics.org/results/ROU
http://adrianrabaea.scienceontheweb.net/
https://www.scribd.com/user/243528817/Adrian-Rabaea
https://drive.google.com/drive/folders/1hC5PZuslCdS95sl37SW46H-qy59GRDGZ
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
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."
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
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
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
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
xiii
20.7 culoriIR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
20.8 culoriIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
20.9 culoriIR3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
20.10stele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
20.11steleIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
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
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 :
2) Num rul de cartona³e din cea mai lung secvenµ în care ecare dou cartona³e al turate
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
Exemple:
2
CAPITOLUL 1. OJI 2020 3
Cerinµa 1
- pentru ecare pereche de cartona³e al turate (s1, d1, s2, d2), veric m dac se potrivesc
(dac d1 s2)
Cerinµa 2
Cerinµa 3
- Num r m secvenµele de lungime egal cu L într-un alt contor care se reseteaz atunci când
se modic L.
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 }
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 }
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 }
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.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µele 2 ³i 3 dac în urma t ierilor nu se obµine niciun num r prim, se va a³a 0
Exemple:
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 #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
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 }
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 }
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
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 }
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 }
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.
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.
Gradul de dicultate
Cerinµa 1 - 2
Cerinta 2 - 3
Cerinta 3 - 4
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 }
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 }
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 }
Etapa nr. 0:
CAPITOLUL 2. OJI 2019 23
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:
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:
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:
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 }
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 }
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
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
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 }
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 }
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:
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:
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:
1 #include<iostream>
2 #include<fstream>
3
CAPITOLUL 2. OJI 2019 38
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 }
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:
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
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µ).
Descrierea soluµiei
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 }
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 }
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 }
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.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:
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
Descrierea soluµiei
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.
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 }
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 }
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 }
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 }
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.
Î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.
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
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 }
41 ultim+=i;
42 sum+=(ultim-(i-col));
43 }
44 fout<<sum<<’\n’;
45 }
46 fout.close();
47 return 0;
48 }
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 }
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 }
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.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 .
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
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 .
Punctul 1
Punctul 2
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.
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).
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.
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 }
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 }
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 }
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.
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.
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 }
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 }
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 }
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.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µ ).
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.
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 }
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 }
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 2N 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 .
Î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 2N 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 2N 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 2N
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.
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
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 }
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
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 }
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 }
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.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.
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
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.
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 }
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 }
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 }
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 }
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.
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.
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 }
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 }
51
52 f.close();
53 g.close();
54
55 return 0;
56 }
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 }
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.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.
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.
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.
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 }
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 }
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 }
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 }
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 }
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 }
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.
Pentru a determina lungimea initiala a betelor $L$ vom determina in $S$ suma
numerelor citite. Apoi evident
\hspace{7mm} L = S div N
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 }
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.2 chibrituri
Problema 2 - chibrituri 100 de puncte
CAPITOLUL 8. OJI 2013 108
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:
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
Retinerea valorilor o fac fie intr-un vector, fie in variabile fie ... pe hartie!
\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)
Asez tinand cont ca daca am doar o solutie, aceasta este si ora maxima
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 }
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 }
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
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 }
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
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;
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.
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 }
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 }
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 }
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 }
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.
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.
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 }
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
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 }
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 }
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.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
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
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 }
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 }
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 }
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
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 }
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 }
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 }
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 }
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
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
}
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--;
f.close();
g.close();
}
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 }
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 }
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 }
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
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 }
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 }
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:
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
12.3 ***
Problema 3 - ... 100 de puncte
Cerinµe
Date de intrare
Date de ie³ire
Restricµii ³i preciz ri
Exemple:
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
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 }
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 }
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 }
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
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).
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
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 }
Atenµie la enunµ: ... cel mai apropiat num r de X, diferit de X, ...
Exemplu pentru 3 cifre:
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:
1000 1630 16.. 1678 252. 3630 36.. 3678 492. 812. 9999
10000 16301 16... 16789 252.. 36301 36... 36789 492.. 812.. 99999
Pentru nc 5 zona
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
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
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
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
... ... ... ... ... ... ...
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
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
... ... ... ... ... ... ...
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
... ... ... ... ... ... ...
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
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
... ... ... ... ... ... ...
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 }
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
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
1 void nrcifrex(int x)
2 {
3 ncx=0;
CAPITOLUL 13. ONI 2019 171
80 if(vcifxs[i-1]%2==0) vcifxs[i]=9;
81 else vcifxs[i]=8;
82 }
444
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
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
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
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
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.
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 }
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 }
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 }
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 }
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
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:
.......
Cerinµe
Scrieµi un program care s citeasc num rul natural K ³i
s determine:
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.
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 22 1 2X 1
Cerinµa 2.
Se a³eaz în ordine invers valorile:
x1 K ©2, x2 x1 ©2, x3 x2 ©2, ..., xN 1
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:
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
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.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
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 ).
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
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.
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.
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
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 }
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.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.
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
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 }
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
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.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".
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.
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.
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 .
b1 b b b b b
a3 R a 3 = a3 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 .
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
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 }
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 }
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
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.
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
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
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).
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.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
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.
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 }
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.
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.
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
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 }
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 }
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 }
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 }
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 }
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.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
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
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 }
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
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 }
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 }
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 }
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 }
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.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.
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.
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 }
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 }
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 }
1 #include<fstream>
2 #include<iostream>
3
CAPITOLUL 17. ONI 2015 246
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 }
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 }
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 }
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
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 }
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:
- 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:
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
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.
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 }
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 }
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 }
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 }
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 }
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.2 babilon
Problema 2 - babilon 100 de puncte
Babilonienii au dezvoltat un sistem poziµional de scriere a numerelor, în care orice num r
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
Se codic scrierea babilonian a unui num r utilizând cifra 1 în locul semnului , cifra 2 în
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
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
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
57 g.close();
58 return 0;
59 }
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 }
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 }
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
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
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).
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.
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 }
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 }
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 }
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 }
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
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.
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
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.
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
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
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
a 2, 3 (pagina 2)
a 4, 5, 6 (pagina 3)
a 7, 8, 9, 10 (pagina 4)
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
a Se determin num rul T total de cifre utilizate în scrierea tuturor numerelor naturale nenule
cel mult egale cu nt, observând c :
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.
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 }
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.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
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.
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 }
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.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,
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 .
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.
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
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 }
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 }
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.
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.
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.
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.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.
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.
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.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.
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
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
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.
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.
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.
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.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
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
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
40
41 g<<nd<<" "<<nmax;
42 g.close();
43 return 0;
44 }
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 }
31 }
32
33 if(nrb>b) b=nrb;
34
35 g<<a<<’ ’<<b;
36 f.close();
37 g.close();
38 return 0;
39 }
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
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.
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.
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 }
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 }
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 }
Un pic de matematic !
A.1 ...
...
A.1.2 Exemple
...
315
Anexa B
Un pic de programare!
B.1 ...
...
B.1.2 Exemple
...
316
Glosar
18 cifre, 230
num r de divizori, 46, 212
317
GLOSAR 318
[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
[5] Bell D., Perr M.; Java for Students, Second Edition, Prentice Hall, 1999
[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
[16] Giumale C., Negreanu L., C linoiu S.; Proiectarea ³i analiza algoritmilor. Algoritmi de sortare,
Ed. All, 1997
[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
[24] Livovschi, L.; Georgescu H.; Analiza ³i sinteza algoritmilor. Ed. Enciclopedic , Bucure³ti,
1986.
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
[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
[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
[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.
[46] Wirth N.; Algorithms + Data Structures = Programs, Prentice Hall, Inc 1976
[48] *** -
https://github.com/DinuCr/CS/blob/master/Info/stuff%20stuff/Re
zolvari_C09.pdf
[49] *** - https://dokumen.tips/documents/rezolvaric09.html
322