PROBLEME DE INFORMATIC date la olimpiade în 2019 2018 2017 2016 2015 2014 2013 2012 2011 2010 la clasa a 5-a ... draft (ciorn ) ... Dr. Adrian R bâea 3 aprilie 2020 Prefaµ Stilul acestor c rµi este ... încercând împreun s ca ³i cum a³ vorbi cu nepoµii mei (³i chiar cu mine însumi!) 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 Ce te faci dac un elev, care ³tie c e³ti student ³i c rezolve ni³te probleme foarte simple): studiezi ³i informatic , te roag , din când în când, s -l ajuµi s rezolve câte o problem ³i simplu ca tem de cas , ³i tu, aproape de ecare dat , nu îl poµi ajuta? Eu cred c de informatic era ca un fel de ... zeu! Cu trecerea anilor am înµeles c înµeleg de ce, atunci când cineva nu poate s de clasa a 6-a, dat la olimpiada de informatic nu am f cut informatic Îmi doresc s obµin Sunt convins c cred c nu este chiar a³a! i înc rezolve corect o problem nu este prea sau ca tem ceva: nu am de informatic de cas , folose³te aceast scuz : eu în liceu! ³i acest cineva este zeul sau zeiµa despre care vorbeam!. prezint elemente simple ³i desene bune care s optime sau care s cauz la gimnaziu la olimpiad , sau pur ... te faci ... de râs! Pe vremea mea (!), când eram elev de gimnaziu, un student bine ³i poate c reu³it s dat ajute la descoperirea unei rezolv ri cât mai multe puncte la olimpiad . este util s studiem cu atenµie cât mai multe probleme rezolvate! Din aceast sunt utile ³i primele versiuni în care sunt prezentate chiar ³i numai enunµurile ³i indicaµiile "ociale" de rezolvare. Acestea se g sesc în multe locuri; aici încerc s le pun pe toate la un loc ! Limbajul de programare se alege în funcµie de problema pe care o avem de rezolvat. Cu ni³te ani în urm alegerea era mai simpl : dac o problem de prelucrarea masiv era o problem de calcul se alegea Fortran iar dac era a datelor atunci se alegea Cobol. Acum alegerea este ceva mai dicil ! :-) Vezi, de exemplu, IOI2019 1 2 ³i IOI2015 . Cred c , de cele mai multe ori, este foarte greu s atunci când caut m o rezolvare pentru o problem dat gândim "simplu" ³i s nu "ne complic m" 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 de rezolvare!). Am început câteva c rµi (pentru clasele de liceu) cu mai mulµi ani în urm , pentru perioada 2000-2007 ([28] - [32]), cu anii în ordine cresc toare!). A urmat o pauz mulµi!). Am observat c s ajung acolo unde am r mas ... plecând mereu din prezent ... pân a³a c , de aceast de câµiva ani (destul de acele cursuri s-au împr ³tiat un pic pe net ([44] - [49])! Încerc acum când nu va mai posibil ... dat , anii sunt în ordine ... descresc toare! :-) Acum voi continua ... cu Enunµuri , Indicaµii de rezolvare ³i Coduri surs ale problemelor date la olimpiadele judeµene ³i naµionale. Pentru liceu perioada acoperit pân este de azi (pân când va exista acest azi pentru mine!) î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 ... restricµiile de memorie, din enunµurile problemelor, par 'ciudate' acum!). Mai departe, va urma Rezolv ri detaliate ... pentru unele probleme numai (tot din cauza lipsei timpului necesar pentru toate!). Prioritate vor avea problemele de gimnaziu (nu pentru c 'u³oare' ci pentru c ... elevii de liceu se descurc sunt mai ³i singuri!). Totu³i, vor prezentate ³i Rezolv ri detaliate ale problemelor de liceu (pe care le-am considerat în mod subiectiv!) interesante ³i utile. Vom încerca ³i câteva probleme de ... IOI ... dar asta este o treab totu³i c 1 este mai bine s ... nu prea u³oar ! Cred prezint numai enunµuri ale problemelor date la IOI în ultimii câµiva ani! IOI2019 a permis utilizarea limbajelor de programare C++ ³i Java (https://ioi2019.az/en-content-14. html#CompetitionEquipment) 2 IOI2015 a permis utilizarea limbajelor de programare C++, Java, Pascal, Python ³i Rubi (http://ioi2015. kz/content/view/1/265) (asta a³a, ca s vedem cum sunt problemele la acest nivel!). Cei care ajung acolo sau vor s acolo (la IOI) nu au nevoie de ajutorul meu! Se descurc ajung singuri! La Indicaµii de rezolvare voi prezenta numai ... numele algoritmilor clasici folosiµi în rezolvare. ALGORITMI utili la olimpiadele de informatic , separat pentru gimnaziu ³i liceu, sper s e de folos! i un ultim gând: 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! Adrese utile: https://stats.ioinformatics.org/halloffame/ https://stats.ioinformatics.org/tasks/ http://stats.ioinformatics.org/results/ROU http://www.cplusplus.com/ http://www.info1cup.com/ https://www.infoarena.ro/ https://www.infogim.ro/ http://www.olimpiada.info/ https://www.pbinfo.ro/ http://www.usaco.org/ http://algopedia.ro/ http://campion.edu.ro/ https://codeforces.com/ https://cpbook.net/ https://csacademy.com/ https://gazeta.info.ro/revigoram-ginfo/ https://oj.uz/problems/source/22 https://profs.info.uaic.ro/~infogim/2019/index.html http://varena.ro/ https://wandbox.org/ https://en.cppreference.com/w/cpp/language/operator_alternative Despre ... Universitatea Tehnic din Cluj-Napoca, Centrul Universitar Nord din Baia-Mare, Facultatea de tiinµe, Departamentul de Matematic -Informatic (2018-2009) Universitatea "Ovidius" din Constanµa Facultatea de Matematic ³i Informatic , Departamentul de Informatic Centrul de Informatic ³i organizare CINOR, Bucure³ti, (1992-1979) Facultatea de matematic (2009-1992) ³i informatic , Bucure³ti (1979-1974) Despre ... http://adrianrabaea.scienceontheweb.net/ https://www.scribd.com/user/243528817/Adrian-Rabaea 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 Cuprins Lista gurilor ix Lista tabelelor xi Lista programelor xii I 1 OJI - Olimpiada judeµean de informatic 1 OJI 2019 1.1 1.2 2 Aur - OJI 2019 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1.2 Rezolvare detaliat 1.1.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Cartele - OJI 2019 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.2.2 Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2 OJI 2018 2.1 2.2 25 Patrate - OJI 2018 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 2.1.2 *Rezolvare detaliat 26 2.1.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 forus - OJI 2018 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 2.2.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 2.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 36 numere - OJI 2017 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 36 3.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 3.1.2 *Rezolvare detaliat 37 3.1.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 robot - OJI 2017 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 3.2.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 3.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 colier - OJI 2016 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 4.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 4.1.2 *Rezolvare detaliat 50 4.1.3 Cod surs 4 OJI 2016 4.1 25 2.1.1 3 OJI 2017 3.1 13 1.2.1 49 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Palindrom - OJI 2016 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 54 4.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 4.2.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 iv 5 OJI 2015 5.1 5.2 60 Cuart - OJI 2015 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 5.1.2 *Rezolvare detaliat 62 5.1.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 speciale - OJI 2015 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 5.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 5.2.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 5.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 6 OJI 2014 6.1 6.2 76 martisoare - OJI 2014 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 6.1.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 6.1.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 piramide - OJI 2014 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 6.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 6.2.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 6.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 90 bete - OJI 2013 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 7.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 7.1.2 *Rezolvare detaliat 91 7.1.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 chibrituri - OJI 2013 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 7.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 7.2.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 7.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 8 OJI 2012 8.1 8.2 98 alice - OJI 2012 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1.2 *Rezolvare detaliat 8.1.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2 98 99 101 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 porumb - OJI 2012 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 8.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 8.2.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 8.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 9 OJI 2011 9.1 76 6.1.1 7 OJI 2013 7.1 60 5.1.1 110 magic - OJI 2011 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 9.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 9.1.2 *Rezolvare detaliat 111 9.1.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . numerus - OJI 2011 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 116 9.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 9.2.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 9.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 10 OJI 2010 121 10.1 sir - OJI 2010 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 10.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 10.1.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 10.1.3 Cod surs 10.2 tren - OJI 2010 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 10.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 10.2.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 10.2.3 Cod surs II ONI - Olimpiada naµional de informatic 11 ONI 2019 135 136 11.1 Copii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 11.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 11.1.2 Rezolvare detaliat 137 11.1.3 Cod surs 11.2 Numere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 11.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 11.2.2 Rezolvare detaliat 145 11.2.3 Cod surs 11.3 Trio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 11.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 11.3.2 Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 11.3.3 Cod surs 12 ONI 2018 165 12.1 desen - ONI 2018 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 12.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 12.1.2 *Rezolvare detaliat 166 12.1.3 *Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.2 mostenire - ONI 2018 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 167 12.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 12.2.2 *Rezolvare detaliat 168 12.2.3 *Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 12.3 pyk - ONI 2018 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 12.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 12.3.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 12.3.3 *Cod surs 13 ONI 2017 171 13.1 prime - ONI 2017 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 13.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 13.1.2 *Rezolvare detaliat 173 13.1.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 13.2 robot - ONI 2017 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 13.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 13.2.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 13.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 13.3 roua - ONI 2017 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 13.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 13.3.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 13.3.3 Cod surs 14 ONI 2016 193 14.1 Norocos - ONI 2016 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193 14.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 14.1.2 *Rezolvare detaliat 194 14.1.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14.2 Oglinda - ONI 2016 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 195 14.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 14.2.2 *Rezolvare detaliat 197 14.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 14.3 Perechi - ONI 2016 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 14.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 14.3.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 14.3.3 Cod surs 15 ONI 2015 201 15.1 iepuras - ONI 2015 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 15.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 15.1.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 15.1.3 Cod surs 15.2 inventie - ONI 2015 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 15.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 15.2.2 *Rezolvare detaliat 212 15.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 15.3 mesaj - ONI 2015 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 15.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 15.3.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 15.3.3 Cod surs 16 ONI 2014 16.1 2048 - ONI 2014 215 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 16.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 16.1.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 16.1.3 Cod surs 16.2 babilon - ONI 2014 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 16.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 16.2.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 16.2.3 Cod surs 16.3 iepurasi - ONI 2014 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 16.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 16.3.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 16.3.3 Cod surs 17 ONI 2013 227 17.1 greieri - ONI 2013 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17.1.1 *Indicaµii de rezolvare 228 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 17.1.2 *Rezolvare detaliat 17.1.3 *Cod surs 17.2 Onigim - ONI 2013 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17.2.1 *Indicaµii de rezolvare 17.2.2 *Rezolvare detaliat 17.2.3 *Cod surs 17.3 Extraprime - ONI 2013 228 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17.3.1 *Indicaµii de rezolvare 229 229 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 17.3.2 *Rezolvare detaliat 17.3.3 *Cod surs 227 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 ONI 2012 231 18.1 culegere - ONI 2012 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 18.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 18.1.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 18.1.3 Cod surs 18.2 culori - ONI 2012 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 18.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 18.2.2 *Rezolvare detaliat 236 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18.2.3 *Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 18.3 stele - ONI 2012 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 18.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 18.3.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 18.3.3 *Cod surs 19 ONI 2011 239 19.1 Fagure - ONI 2011 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 19.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 19.1.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 19.2 Goe - ONI 2011 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 19.1.3 Cod surs 19.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 19.2.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 19.3 P pu³a - ONI 2011 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 19.2.3 Cod surs 19.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 19.3.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 19.3.3 Cod surs 20 ONI 2010 248 20.1 cluburi - ONI 2010 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 20.1.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 20.1.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 20.1.3 Cod surs 20.2 domino - ONI 2010 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 20.2.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 20.2.2 *Rezolvare detaliat 254 20.2.3 Cod surs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 20.3 max - ONI 2010 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 20.3.1 Indicaµii de rezolvare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 20.3.2 *Rezolvare detaliat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 20.3.3 Cod surs Index 264 Bibliograe 265 Lista gurilor 2.1 Patrate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 2.2 forus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.1 Numere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3.2 Robot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 5.1 Cuart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 5.2 speciale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 6.1 marti³oare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 6.2 Piramide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 7.1 chibrituri1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 7.2 chibrituri2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 8.1 alice 98 8.2 8.5 AliceIR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AliceIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AliceIR3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AliceIR4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.6 porumbi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 8.7 porumbIR1 P orumbIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 8.8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 9.1 Numerus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 9.2 Numerus - exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 10.1 sirir1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 10.2 sirir2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 10.3 sirir3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 10.4 sirir4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 10.5 sirir5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 11.1 Numere cu 3 cifre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 11.2 Numere cu 4 cifre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 11.3 Numere cu 5 cifre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 12.1 desen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 15.1 mesaj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 16.1 2048 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3 8.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 100 100 100 215 16.2 iepurasi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 17.1 greieri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 18.1 culegere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 18.2 culegereIR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 18.3 culegereIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 18.4 culegereIR3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 18.5 culegereIR4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 18.6 culori ix 18.7 culoriIR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 18.8 culoriIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 18.9 culoriIR3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 18.11steleIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 18.10stele 19.1 fagure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 19.3 papusa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 20.1 cluburiIR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 20.2 cluburiIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 19.2 Goe 20.3 cluburiIR3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 20.4 domino 253 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20.5 dominoIR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 20.6 maxIR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 20.7 maxIR2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 Lista tabelelor xi Lista programelor 1.1.1 Aur - Etapa nr. 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1.2 Aur - Etapa nr. 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.1.3 Aur - Etapa nr. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.1.4 Aur - Etapa nr. 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.1.5 Aur - Etapa nr. 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.1.6 Aur - Etapa nr. 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.1.7 aur_LC.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.1.8 aur_sol.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.1.9 aur_td.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.2.1 Cartele - Etapa nr. 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.2.2 Cartele - Etapa nr. 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.2.3 Cartele - Etapa nr. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.2.4 Cartele - Etapa nr. 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.2.5 cartele_LC.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.2.6 cartele_td.cpp 22 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 patrate_AS.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 2.1.2 patrate_cpp_CM.cpp 27 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.3 patrate_FB.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 2.1.4 patrate_VG.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 2.2.1 forus_CM_100.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 2.2.2 forus_nvl_100.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.2.3 forus_VG_100.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 2.2.4 ocial_FB_100.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 3.1.1 numere_cardas.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 3.1.2 numere_cerchez.cpp 38 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.3 numere_jakab.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 3.1.4 numere_sandor.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 3.1.5 numere_vladescu.cpp 3.2.1 robot_cerchez.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 3.2.2 robot_cerchez_ok.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 3.2.3 robot_jakab.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 4.1.1 colier_gina.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 4.1.2 colier_Marius.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4.1.3 colier_Miana.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4.1.4 colier_sanda.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 4.2.1 palindrom_Marius.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.2.2 palindrom_Sanda.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 5.1.1 cuart_dl.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 5.1.2 cuart_dt.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 5.1.3 cuart_la.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 5.1.4 cuartAI.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 5.1.5 cuartAI_ecuatie.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 5.2.1 speciale_dc.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 5.2.2 speciale_n_dt.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 5.2.3 speciale_SJ.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 5.2.4 specialedl.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 6.1.1 mAna.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 6.1.2 mCarmen.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 6.1.3 mCristina.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 xii 6.1.4 mMarilena.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 6.1.5 mRaluca.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 6.2.1 p_s_CM.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 6.2.2 p_v_CM.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 6.2.3 pAna.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 6.2.4 pCristina.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 6.2.5 pGina.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 6.2.6 pMarilena.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 6.2.7 pRaluca.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 7.1.1 bete_OFICIAL.cpp 7.1.2 bete_vectori.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 7.2.1 chibrituri_OFICIAL.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 7.2.2 chibrituri_v.cpp 96 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1.1 alice_CM2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 8.1.2 alice_CS.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 8.1.3 alice_SJ.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 8.2.1 p100_AS.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 8.2.2 p100_CL.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 8.2.3 p100_CM1.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 8.2.4 p100_CM2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 8.2.5 p100_CS.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 8.2.6 p100_DT.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 8.2.7 p100_JIT.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 9.1.1 CARACTER.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 9.1.2 magic_DM.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 9.1.3 MAGIC_S.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 9.1.4 magicAna.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 9.1.5 MAGICDT3.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 9.2.1 A1_Numer.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 9.2.2 D_NUMERU.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 9.2.3 S_Numeru.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 10.1.1 sir.CPP 124 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.1.2 sirana.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 10.1.3 SIRcris.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 10.1.4 SIRcris2.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 10.1.5 SIRcris2.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 10.1.6 SIRVECT.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 10.2.1 Ana.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 10.2.2 Carmen.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 10.2.3 Cris1.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 10.2.4 Cris2.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 10.2.5 Cris3.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 10.2.6 Dana.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 11.1.1 Copii - Etapa nr. 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 11.1.2 Copii - Etapa nr. 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 11.1.3 Copii - Etapa nr. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 11.1.4 copii_cpp.cpp 141 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2.1 Numere - Etapa nr. 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 11.2.2 Numere - Etapa nr. 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 11.2.3 Numere - Etapa nr. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 11.2.4 Numere - Etapa nr. 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 11.2.5 Numere - Etapa nr. 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 11.2.6 Numere - Etapa nr. 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 11.2.7 numere_cpp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 11.3.1 Trio - Etapa nr. 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 11.3.2 Trio - Etapa nr. 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 11.3.3 Trio - Etapa nr. 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 11.3.4 Trio - Etapa nr. 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 11.3.5 trio_cpp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 13.1.1 prime_cp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 13.1.2 prime_em.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.1.3 prime_fara_ciur_sn.cpp 175 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 13.2.1 robot_adriana.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 13.2.2 robot_cp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 13.2.3 robot_ema.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 13.2.4 robot-JT.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 13.3.1 roua_cardas.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 13.3.2 roua_cp.cpp 190 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.3.3 roua_jt.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 14.1.1 norocos.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 14.2.1 oglinda.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 14.3.1 perechi.cpp 199 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.1.1 iepuras_1.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 15.1.2 iepuras_2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 15.1.3 iepuras_3.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 15.1.4 iepuras_4.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 15.1.5 iepuras_5.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 15.1.6 iepuras_6.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 16.1.1 2048.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 16.1.2 2048A.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 16.1.3 2048F.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 16.1.4 2048G.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 16.1.5 2048L.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 16.1.6 2048R.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 18.1.1 culegere_2.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 18.1.2 culegere_3.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 19.1.1 fagure.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 19.2.1 GOE.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 19.3.1 papusa.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 20.1.1 cluburi_CS.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 20.1.2 cluburi_fara_vectori.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 20.1.3 cluburi_SG.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 20.2.1 domino_AS_1.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 20.2.2 domino_AS_2.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 20.2.3 domino_CM.CPP 255 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20.2.4 domino_CS.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 20.2.5 domino_SG.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 20.3.1 MAX_CM.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 20.3.2 MAX_CS.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 20.3.3 MAX_SG.CPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 Partea I OJI - Olimpiada judeµean de informatic 1 Capitolul 1 OJI 2019 1.1 Aur - OJI 2019 Problema 1 - Aur Dup 90 de puncte ce au mers împreun de aur, iar acum îi r stoarn b nuµii din ecare gr mad s prin lume, P cal ³i Tândal au strâns o c ruµ pe toµi în curtea casei ³i îi împart în ³i îi dicteaz le scrie în ordine pe o t bliµ . Dup lui Tândal plin N gr mezi. P cal de b nuµi num r N numere naturale pe care acesta trebuie 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 ; 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 2. ce-a de-a î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 a 1 & N & 100000 ³i 1 & K & 900000; Se garanteaz c exist cel puµin K cifre scrise pe t bliµ . & P & 18; Se garanteaz ca exist cel puµin P cifre scrise pe t bliµ . a toate numere dictate de P cal a Pentru rezolvarea corect a celei de-a doua cerinµe se acord cerinµe se acord sunt nenule ³i au cel mult 9 cifre ecare; a primei cerinµe se acord 20 de puncte, pentru rezolvarea corect 30 de puncte, iar pentru rezolvarea corect 40 de puncte. 2 a celei de-a treia CAPITOLUL 1. 3 OJI 2019 Exemple aur.in 1 aur.out Explicaµii 12 Se rezolv 7 Tândal 25 9 13 459 2 79 9 cerinµa 1. a scris pe t bliµ : 259134592799. Num rul cifrelor scrise de Tândal este 12. 7 10 N are valoarea 7 ³i K are valoarea 10. Pe t bliµ este scris: 259134592799 25 9 13 459 2 79 9 Cea de-a zecea cifr 2 7 3 Se rezolv 9279 Se rezolv cerinµa 2. este 7. cerinµa 3. N are valoarea 7 ³i P are valoarea 4. 92799. 7 4 Tândal a scris pe t bliµ : 2591345 25 9 13 459 2 79 9 Cel mai mare num r format din patru cifre este 9279. Timp maxim de executare/test: 0.5 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 15 KB Sursa: aur.cpp, aur.c sau aur.pas va salvat 1.1.1 în folderul care are drept nume ID-ul t u. Indicaµii de rezolvare Descriere a unei soluµii posibile Cerinµa1 : - pentru ecare num r citit din ³ier identic m cifrele sale; - utiliz m o variabil de tip contor pentru num rarea cifrelor tuturor numerelor. Cerinµa 2: - pentru ecare num r citit din ³ier determin m cifrele sale în ordine, de la stânga la dreapta; - num r m cifrele pân în momentul în care variabila care le contorizeaz ajunge la valoare K . Cerinµa 3 - consider m toate secvenµele posibile formate din P cifre al turate; - cu cifrele ec rei secvenµe construim un num r natural; - calcul m cea mai mare valoare a unui num r natural construit anterior. Tipuri de date folosite - tipul întreg ³i/sau tipul caracter Gradul de dicultate Cerinµa 1 - 2 Cerinta 2 - 3 Cerinta 3 - 4 1.1.2 Rezolvare detaliat Etapa nr. 0: Listing 1.1.1: Aur - Etapa nr. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include<iostream> #include<fstream> using namespace std; ifstream fin("aur.in"); ofstream fout("aur.out"); int C, N, K, P; int nr; // cate un numar pe randul 3 (din cele N numere) int nc; // numarul cifrelor scrise pe tablita int ck; // cifra K scrisa pe tablita int nrmaxp; // nr max format cu P cifre void rezolva1() { } CAPITOLUL 1. 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 4 OJI 2019 void rezolva2() { } void rezolva3() { } int main() { fin>>C; cout<<"C = "<<C<<"\n"; if(C==1) {rezolva1(); return 0;} if(C==2) {rezolva2(); return 0;} if(C==3) {rezolva3(); return 0;} return 0; } Etapa nr. 1: Listing 1.1.2: Aur - Etapa nr. 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include<iostream> #include<fstream> using namespace std; ifstream fin("aur.in"); ofstream fout("aur.out"); int C, N, K, P; int nr; // cate un numar pe randul 3 (din cele N numere) int nc; // numarul cifrelor scrise pe tablita int ck; // cifra K scrisa pe tablita int nrmaxp; // nr max format cu P cifre void rezolva1() { fin>>N; cout<<"N = "<<N<<"\n"; nc=0; unsigned char ch; while(fin>>ch) { if(ch>=’0’ && ch<=’9’) nc++; } cout<<"nc = "<<nc<<"\n"; fout<<nc<<’\n’; fout.close(); } void rezolva2() { } void rezolva3() { } int main() { fin>>C; cout<<"C = "<<C<<"\n"; if(C==1) {rezolva1(); return 0;} if(C==2) {rezolva2(); return 0;} if(C==3) {rezolva3(); return 0;} CAPITOLUL 1. 50 51 52 5 OJI 2019 return 0; } Etapa nr. 2: Listing 1.1.3: Aur - Etapa nr. 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #include<iostream> #include<fstream> using namespace std; ifstream fin("aur.in"); ofstream fout("aur.out"); int C, N, K, P; int nr; // cate un numar pe randul 3 (din cele N numere) int nc; // numarul cifrelor scrise pe tablita int ck; // cifra K scrisa pe tablita int nrmaxp; // nr max format cu P cifre void rezolva1() { fin>>N; cout<<"N = "<<N<<"\n"; nc=0; unsigned char ch; while(fin>>ch) { if(ch>=’0’ && ch<=’9’) nc++; } cout<<"nc = "<<nc<<"\n"; fout<<nc<<’\n’; fout.close(); } void rezolva2() { fin>>N; cout<<"N = "<<N<<"\n"; fin>>K; cout<<"K = "<<K<<"\n"; nc=0; unsigned char ch; while(nc < K) { fin>>ch; if(ch>=’0’ && ch<=’9’) nc++; } cout<<"ch = "<<ch<<"\n"; fout<<ch<<’\n’; fout.close(); } void rezolva3() { } int main() { fin>>C; cout<<"C = "<<C<<"\n"; if(C==1) {rezolva1(); return 0;} if(C==2) {rezolva2(); return 0;} if(C==3) {rezolva3(); return 0;} return 0; CAPITOLUL 1. 68 6 OJI 2019 } Etapa nr. 3: Listing 1.1.4: Aur - Etapa nr. 3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 #include<iostream> #include<fstream> using namespace std; ifstream fin("aur.in"); ofstream fout("aur.out"); int C, N, K, P; int nr; int nc; int ck; long long nrmaxp; // cate un numar pe randul 3 (din cele N numere) // numarul cifrelor scrise pe tablita // cifra K scrisa pe tablita // nr max format cu P cifre void rezolva1() { fin>>N; cout<<"N = "<<N<<"\n"; nc=0; unsigned char ch; while(fin>>ch) { if(ch>=’0’ && ch<=’9’) nc++; } cout<<"nc = "<<nc<<"\n"; fout<<nc<<’\n’; fout.close(); } void rezolva2() { fin>>N; cout<<"N = "<<N<<"\n"; fin>>K; cout<<"K = "<<K<<"\n"; nc=0; unsigned char ch; while(nc < K) { fin>>ch; if(ch>=’0’ && ch<=’9’) nc++; } cout<<"ch = "<<ch<<"\n"; fout<<ch<<’\n’; fout.close(); } void rezolva3() { fin>>N; cout<<"N = "<<N<<"\n"; fin>>P; cout<<"P = "<<P<<"\n"; // nr1 = c_1 c_2 ... c_p ---> nrnou = c_2 c_3 ...c_p c_{p+1} // c_2 c_3 ... c_p = restul impartirii lui nr1 la prod10p_1 // = 10*10*...*10 de p-1 ori long long prod10p_1=1; for(int i=1; i<=P-1; i++) prod10p_1=prod10p_1*10; cout<<"prod10p_1 = "<<prod10p_1<<"\n"; long long nr1=0LL; CAPITOLUL 1. 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 7 OJI 2019 unsigned char ch; for(int i=1; i<=P; i++) { fin>>ch; nr1=nr1*10+(ch-’0’); } cout<<"nr1 = "<<nr1<<"\n"; nrmaxp=nr1; while(fin>>ch) { if(ch>=’0’ && ch<=’9’) { nr1=(nr1 % prod10p_1)*10 + (ch-’0’); if(nr1 > nrmaxp) nrmaxp=nr1; } } cout<<"nrmaxp = "<<nrmaxp<<"\n"; fout<<nrmaxp<<’\n’; fout.close(); } int main() { fin>>C; cout<<"C = "<<C<<"\n"; if(C==1) {rezolva1(); return 0;} if(C==2) {rezolva2(); return 0;} if(C==3) {rezolva3(); return 0;} return 0; } Etapa nr. 4 FINALA1 comentat mesajele ajutatoare: Listing 1.1.5: Aur - Etapa nr. 4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include<iostream> #include<fstream> using namespace std; ifstream fin("aur.in"); ofstream fout("aur.out"); int C, N, K, P; int nr; int nc; int ck; long long nrmaxp; // cate un numar pe randul 3 (din cele N numere) // numarul cifrelor scrise pe tablita // cifra K scrisa pe tablita // nr max format cu P cifre void rezolva1() { fin>>N; //cout<<"N = "<<N<<"\n"; nc=0; unsigned char ch; while(fin>>ch) { if(ch>=’0’ && ch<=’9’) nc++; } //cout<<"nc = "<<nc<<"\n"; fout<<nc<<’\n’; fout.close(); } void rezolva2() { fin>>N; //cout<<"N = "<<N<<"\n"; fin>>K; CAPITOLUL 1. 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 8 OJI 2019 //cout<<"K = "<<K<<"\n"; nc=0; unsigned char ch; while(nc < K) { fin>>ch; if(ch>=’0’ && ch<=’9’) nc++; } //cout<<"ch = "<<ch<<"\n"; fout<<ch<<’\n’; fout.close(); } void rezolva3() { fin>>N; //cout<<"N = "<<N<<"\n"; fin>>P; //cout<<"P = "<<P<<"\n"; // nr1 = c_1 c_2 ... c_p ---> nrnou = c_2 c_3 ...c_p c_{p+1} // c_2 c_3 ... c_p = restul impartirii lui nr1 la prod10p_1 // = 10*10*...*10 de p-1 ori long long prod10p_1=1; for(int i=1; i<=P-1; i++) prod10p_1=prod10p_1*10; //cout<<"prod10p_1 = "<<prod10p_1<<"\n"; long long nr1=0LL; unsigned char ch; for(int i=1; i<=P; i++) { fin>>ch; nr1=nr1*10+(ch-’0’); } //cout<<"nr1 = "<<nr1<<"\n"; nrmaxp=nr1; while(fin>>ch) { if(ch>=’0’ && ch<=’9’) { nr1=(nr1 % prod10p_1)*10 + (ch-’0’); if(nr1 > nrmaxp) nrmaxp=nr1; } } //cout<<"nrmaxp = "<<nrmaxp<<"\n"; fout<<nrmaxp<<’\n’; fout.close(); } int main() { fin>>C; //cout<<"C = "<<C<<"\n"; if(C==1) {rezolva1(); return 0;} if(C==2) {rezolva2(); return 0;} if(C==3) {rezolva3(); return 0;} return 0; } Etapa nr. 5 FINALA2 sters mesajele ajutatoare: Listing 1.1.6: Aur - Etapa nr. 5 1 2 3 4 5 #include<iostream> #include<fstream> using namespace std; CAPITOLUL 1. 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 OJI 2019 ifstream fin("aur.in"); ofstream fout("aur.out"); int C, N, K, P; int nr; int nc; int ck; long long nrmaxp; // cate un numar pe randul 3 (din cele N numere) // numarul cifrelor scrise pe tablita // cifra K scrisa pe tablita // nr max format cu P cifre void rezolva1() { fin>>N; nc=0; unsigned char ch; while(fin>>ch) { if(ch>=’0’ && ch<=’9’) nc++; } fout<<nc<<’\n’; fout.close(); } void rezolva2() { fin>>N; fin>>K; nc=0; unsigned char ch; while(nc < K) { fin>>ch; if(ch>=’0’ && ch<=’9’) nc++; } fout<<ch<<’\n’; fout.close(); } void rezolva3() { fin>>N; fin>>P; // nr1 = c_1 c_2 ... c_p ---> nrnou = c_2 c_3 ...c_p c_{p+1} // c_2 c_3 ... c_p = restul impartirii lui nr1 // la prod10p_1 = 10*10*...*10 de p-1 ori long long prod10p_1=1; for(int i=1; i<=P-1; i++) prod10p_1=prod10p_1*10; long long nr1=0LL; unsigned char ch; for(int i=1; i<=P; i++) { fin>>ch; nr1=nr1*10+(ch-’0’); } nrmaxp=nr1; while(fin>>ch) { if(ch>=’0’ && ch<=’9’) { nr1=(nr1 % prod10p_1)*10 + (ch-’0’); if(nr1 > nrmaxp) nrmaxp=nr1; } } fout<<nrmaxp<<’\n’; fout.close(); } int main() { fin>>C; if(C==1) {rezolva1(); return 0;} 9 CAPITOLUL 1. 82 83 84 85 10 OJI 2019 if(C==2) {rezolva2(); return 0;} if(C==3) {rezolva3(); return 0;} return 0; } 1.1.3 Cod surs Listing 1.1.7: aur_LC.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #include <iostream> #include <fstream> #include <cmath> using namespace std; ifstream fin("aur.in"); ofstream fout("aur.out"); int main() { int p; fin>>p; if(p==1) { int n,nr=0; char c; fin>>n; while(fin>>c) if(c!=’ ’) nr++; fout<<nr; } if(p==2) { int n,k,nr=0; char c,a; fin>>n>>k; while(fin>>c) { if(c!=’ ’) nr++; if(nr==k) a=c; } fout<<a; } if(p==3) { unsigned long long n, k, maxx=0, v, y=0, nr=0; char c; fin>>n>>k; unsigned long long f1=1; for(int i=1;i<k;i++) f1=f1*10; while(fin>>c) { if(c!=’ ’) { v=(int)c-48; y=y*10+v; } nr++; if(nr==k) { if(y>maxx) maxx=y; y=y%f1; nr--; } CAPITOLUL 1. 66 67 68 69 70 71 72 11 OJI 2019 } fout<<maxx; } return 0; } Listing 1.1.8: aur_sol.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <fstream> using namespace std; ifstream f("aur.in"); ofstream g("aur.out"); long long nr_max,p=1,nou,nr; int main() { char c,cifraK; int nr_cif=0,cerinta,K,N,i,P; f>>cerinta>>N; if (cerinta==2) f>>K; else if (cerinta==3) f>>P; if (cerinta==1) { while(f>>c) nr_cif++; g<<nr_cif<<’\n’; } else if (cerinta==2) while(f>>c) { nr_cif++; if (nr_cif==K) { g<<c<<’\n’; break; } } else { for(i=1; i<P; i++) { f>>c; nr=nr*10+(c-’0’); p=p*10; } nr_max=nr; while(f>>c) { nou=(nr%p)*10+(c-’0’); if(nou>nr_max) nr_max=nou; nr=nou; } g<<nr_max<<’\n’; } return 0; } Listing 1.1.9: aur_td.cpp 1 2 #include <fstream> CAPITOLUL 1. 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 OJI 2019 using namespace std; ifstream f("aur.in"); ofstream g("aur.out"); long long c, i, N, K, P, cif, nr, y, p, x, aux, cate, q, t, maxf; int main() { f>>c; if(c==1) { f>>N; cate=0; for(i=1; i<=N; i++) { f>>x; while(x) { cate++; x /= 10; } } g<<cate<<" \n"; } else if(c==2) { f>>N>>K; nr=0; for (i=1; i<=N; i++) { f>>x; y=x; p=1; while (p<=y) p *= 10; p /= 10; y=x; while(p>=1) { nr++; cif = y / p %10; p /= 10; if(nr == K) { g<<cif<<"\n"; return 0; } } } } else { f>>N>>P; q=1; for(i=1; i<P; i++) q=q*10; nr=0; t=0; maxf=0; for(i=1; i<=N; i++) { f>>x; y=x; p=1; while(p<=y) p *= 10; 12 CAPITOLUL 1. 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 13 OJI 2019 p /= 10; y=x; while(p>=1) { nr++; cif = y / p %10; t = t % q; t= t*10 + cif; p /= 10; if(nr == K) { maxf=t; } else if(nr>K) { if(t > maxf) maxf=t; } } } g<<maxf; } return 0; } 1.2 Cartele - OJI 2019 Problema 2 - cartele Într-o ³coal o imprimant . sistemul imprim - Caracterul un spaµiu; - Caracterul exist 90 de puncte un sistem de acces cu ajutorul cartelelor, conectat la un calculator ³i Fiecare elev al ³colii are câte o cartel . Într-o zi, la utilizarea ec rei cartele, urm toarele informaµii pe hârtie, pe câte o linie, dup regula urm toare: i dac a ie³it din ³coal . b dac elevul este b iat sau caracterul f dac este fat . Caracterul va urmat de elevul a intrat în ³coal e dac sau caracterul 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 2. dup cele N acµiuni imprimate de sistem. 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 a³eaz în momentul utiliz rii ultimei cartele. Dac 3. Care este num rul maxim de secunde în care, în ³coal , pân cartele, s-au aat neîntrerupt un num r impar de b ieµi. Dac a³eaz nu exist aceast situaµie se 0. în momentul utiliz rii ultimei nu exist o astfel de situaµie se 0. Date de intrare Fi³ierul de intrare cartele.in conµine pe prima linie un num r natural C reprezentând num rul N, iar pe urm toarele cerinµei care poate avea valorile 1, 2 sau 3, pe a doua linie num rul natural 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 num r natural ce reprezint cartele.out va conµine pe prima linie un singur rezultatul determinat conform cerinµei. CAPITOLUL 1. 14 OJI 2019 Restricµii ³i preciz ri a 1 & N & 10000 a La momentul utiliz rii primei cartele, în ³coal nu se a a Sistemul de acces nu permite folosirea simultan a dou niciun elev cartele 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 a Pentru orice linie imprimat spaµiu. a Pentru rezolvarea corect a primei cerinµe se acord a celei de-a doua cerinµe se acord cerinµe se acord 20 de puncte, pentru rezolvarea corect 30 de puncte iar pentru rezolvarea corect a celei de-a treia 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 b i 0 0 24 0 0 29. O fat f i 0 0 26 Dup b e 0 0 29 Num rul cifrelor scrise de Tândal 2 3 ora 0, minutul 0 ³i secunda 24) ³i ie³it la momentul a intrat la momentul 0 0 26. cele 3 acµiuni, în ³coal Se rezolv ³coal b i 0 0 24 în ³coal f i 0 0 26 egal de fete ³i b ieµi. 2 este 12. cerinµa 2. Între momentul 0 0 24 ³i 0 0 26 în 3 b e 0 0 29 a r mas o fat . este doar un b iat. Între momentul 0 0 26 ³i 0 0 29 se a un b iat ³i o fat adic un num r nenul Deci, num rul de secunde determinat este 3. 47 Se rezolv cerinµa 2. 8 Între momentele 8 19 12 ³i 8 19 15 în ³coal 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 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 b e 8 20 4 fat , deci durata este 40 de secunde se a 1 b iat ³i 1 se a 1 b iat ³i 1 se a 1 b iat ³i 1 se a 1 b iat, deci se a 1 b iat, deci 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 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 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 b i 8 20 0 deci durata este 2 secunde se a 3 b ieµi, b e 8 20 1 b i 8 20 10 Durata maxim cerut este de 3 secunde b i 8 20 12 b i 8 20 13 Timp maxim de executare/test: 0.5 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 15 KB Sursa: cartele.cpp, cartele.c sau cartele.pas va salvat în folderul care are drept nume ID-ul t u. 1.2.1 Indicaµii de rezolvare Descrierea soluµiei Se vor citi datele în formatul specicat ³i se vor transforma în secunde momentele ec rei acµiuni. Cerinµa 1: CAPITOLUL 1. 15 OJI 2019 - 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 de acµiune (intrare sau ie³ire). proprietatea cerut num rul de b ieµi ³i fete prezenµi în ³coal , în funcµie Vom determina durata neîntrerupt de timp curent care are ³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.2.2 Rezolvare detaliat Etapa nr. 0: Listing 1.2.1: Cartele - Etapa nr. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include<iostream> #include<fstream> using namespace std; ifstream fin("cartele.in"); ofstream fout("cartele.out"); int C, N; char elev; char inout; int ora, minut, sec; // ’b’ sau ’f’ // ’i’ sau ’e’ int nrb, nrf; int nrtotsec; int nrmaxsec; // nr_baieti, nr_fete // nr total secunde // nr maxim secunde void rezolva1() { } void rezolva2() { } void rezolva3() { } int main() { fin>>C; cout<<"C = "<<C<<"\n"; if(C==1) {rezolva1(); return 0;} if(C==2) {rezolva2(); return 0;} if(C==3) {rezolva3(); return 0;} return 0; } CAPITOLUL 1. 16 OJI 2019 Etapa nr. 1: Listing 1.2.2: Cartele - Etapa nr. 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #include<iostream> #include<fstream> using namespace std; ifstream fin("cartele.in"); ofstream fout("cartele.out"); int C, N; unsigned char elev; unsigned char inout; int ora, minut, sec; int nrb, nrf; int nrtotsec; int nrmaxsec; // ’b’ sau ’f’ // ’i’ sau ’e’ // nr_baieti, nr_fete // nr total secunde // nr maxim secunde void citesteCartela() { fin>>elev; fin>>inout; fin>>ora; fin>>minut; fin>>sec; cout<<elev<<" "<<inout<<" "<<ora<<" "<<minut<<" "<<sec<<"\n"; } void rezolva1() { fin>>N; cout<<"N = "<<N<<"\n"; nrb=0; nrf=0; for(int i=1; i<=N; i++) { citesteCartela(); if(elev==’b’) { if(inout==’i’) nrb=nrb+1; else nrb=nrb-1; } else if(elev==’f’) { if(inout==’i’) nrf=nrf+1; else nrf=nrf-1; } } cout<<"nrb = "<<nrb<<" nrf = "<<nrf<<"\n"; fout<<nrb<<" "<<nrf<<’\n’; fout.close(); } void rezolva2() { } void rezolva3() { } int main() { fin>>C; cout<<"C = "<<C<<"\n"; if(C==1) {rezolva1(); return 0;} if(C==2) {rezolva2(); return 0;} CAPITOLUL 1. 73 74 75 76 17 OJI 2019 if(C==3) {rezolva3(); return 0;} return 0; } Etapa nr. 2: Listing 1.2.3: Cartele - Etapa nr. 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 #include<iostream> #include<fstream> using namespace std; ifstream fin("cartele.in"); ofstream fout("cartele.out"); int C, N; unsigned char elev; unsigned char inout; int ora, minut, sec; int nrb, nrf; int nrtotsec; int nrmaxsec; // ’b’ sau ’f’ // ’i’ sau ’e’ // nr_baieti, nr_fete // nr total secunde // nr maxim secunde void citesteCartela() { fin>>elev; fin>>inout; fin>>ora; fin>>minut; fin>>sec; cout<<elev<<" "<<inout<<" "<<ora<<" "<<minut<<" "<<sec<<"\n"; } void rezolva1() { fin>>N; cout<<"N = "<<N<<"\n"; nrb=0; nrf=0; for(int i=1; i<=N; i++) { citesteCartela(); if(elev==’b’) { if(inout==’i’) nrb=nrb+1; else nrb=nrb-1; } else if(elev==’f’) { if(inout==’i’) nrf=nrf+1; else nrf=nrf-1; } } cout<<"nrb = "<<nrb<<" nrf = "<<nrf<<"\n"; fout<<nrb<<" "<<nrf<<’\n’; fout.close(); } void rezolva2() { nrtotsec=0; fin>>N; cout<<"N = "<<N<<"\n"; nrb=0; nrf=0; bool adunTimp=false; CAPITOLUL 1. 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 18 OJI 2019 int timp1, timp2; timp1=0; // moment vechi for(int i=1; i<=N; i++) { citesteCartela(); if(elev==’b’) { if(inout==’i’) nrb=nrb+1; else nrb=nrb-1; } else if(elev==’f’) { if(inout==’i’) nrf=nrf+1; else nrf=nrf-1; } timp2=ora*60*60+minut*60+sec; // moment actual if(adunTimp) nrtotsec=nrtotsec+(timp2-timp1); timp1=timp2; if(nrb==nrf && nrb>0) adunTimp=true; else adunTimp=false; } cout<<"nrtotsec = "<<nrtotsec<<"\n"; fout<<nrtotsec<<’\n’; fout.close(); } void rezolva3() { } int main() { fin>>C; cout<<"C = "<<C<<"\n"; if(C==1) {rezolva1(); return 0;} if(C==2) {rezolva2(); return 0;} if(C==3) {rezolva3(); return 0;} return 0; } Etapa nr. 3: Listing 1.2.4: Cartele - Etapa nr. 3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include<iostream> #include<fstream> using namespace std; ifstream fin("cartele.in"); ofstream fout("cartele.out"); int C, N; unsigned char elev; unsigned char inout; int ora, minut, sec; int nrb, nrf; int nrtotsec; int nrmaxsec; void citesteCartela() { fin>>elev; fin>>inout; fin>>ora; fin>>minut; fin>>sec; // ’b’ sau ’f’ // ’i’ sau ’e’ // nr_baieti, nr_fete // nr total secunde // nr maxim secunde CAPITOLUL 1. 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 19 OJI 2019 cout<<elev<<" "<<inout<<" "<<ora<<" "<<minut<<" "<<sec<<"\n"; } void rezolva1() { fin>>N; cout<<"N = "<<N<<"\n"; nrb=0; nrf=0; for(int i=1; i<=N; i++) { citesteCartela(); if(elev==’b’) { if(inout==’i’) nrb=nrb+1; else nrb=nrb-1; } else if(elev==’f’) { if(inout==’i’) nrf=nrf+1; else nrf=nrf-1; } } cout<<"nrb = "<<nrb<<" nrf = "<<nrf<<"\n"; fout<<nrb<<" "<<nrf<<’\n’; fout.close(); } void rezolva2() { nrtotsec=0; fin>>N; cout<<"N = "<<N<<"\n"; nrb=0; nrf=0; bool adunTimp=false; int timp1, timp2; timp1=0; // moment vechi for(int i=1; i<=N; i++) { citesteCartela(); if(elev==’b’) { if(inout==’i’) nrb=nrb+1; else nrb=nrb-1; } else if(elev==’f’) { if(inout==’i’) nrf=nrf+1; else nrf=nrf-1; } timp2=ora*60*60+minut*60+sec; // moment actual if(adunTimp) nrtotsec=nrtotsec+(timp2-timp1); timp1=timp2; if(nrb==nrf && nrb>0) adunTimp=true; else adunTimp=false; } cout<<"nrtotsec = "<<nrtotsec<<"\n"; fout<<nrtotsec<<’\n’; fout.close(); } void rezolva3() { nrmaxsec=0; CAPITOLUL 1. 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 20 OJI 2019 fin>>N; cout<<"N = "<<N<<"\n"; nrb=0; int timp1, timp2; timp1=0; // moment inainte de citire cartela for(int i=1; i<=N; i++) { citesteCartela(); if(elev==’b’) // s-a schimbat paritatea numarului de baieti { timp2=ora*60*60+minut*60+sec; //moment actual(dupa citire cartela) if(inout==’i’) nrb=nrb+1; else nrb=nrb-1; if(nrb%2==1) // a fost nr par de baieti si a venit acum un baiat ... { // ... incepe timp !!! // impar este oricum diferit de zero ... deci ... // ... nu verific nrb==0 timp1=timp2; cout<<" nrb = "<<nrb<<" timp1 = "<<timp1<<"\n"; } else // a fost nr impar de baieti si ... a venit acum un baiat { if(nrmaxsec < (timp2-timp1)) nrmaxsec = timp2-timp1; cout<<" nrb = "<<nrb<<" timp2 = "<<timp2<<"\n"; } } } cout<<"nrmaxsec = "<<nrmaxsec<<"\n"; fout<<nrmaxsec<<’\n’; fout.close(); } int main() { fin>>C; cout<<"C = "<<C<<"\n"; if(C==1) {rezolva1(); return 0;} if(C==2) {rezolva2(); return 0;} if(C==3) {rezolva3(); return 0;} return 0; } Etapa nr. 4 FINALA1 comentat mesajele ajutatoare: Tema !!! Etapa nr. 5 FINALA2 sters mesajele ajutatoare: Tema !!! 1.2.3 Cod surs Listing 1.2.5: cartele_LC.cpp 1 2 3 4 5 6 7 8 9 10 11 12 #include<iostream> #include<fstream> #include<cstdlib> using namespace std; int main() { ifstream f("cartele.in"); ofstream g("cartele.out"); short int C; CAPITOLUL 1. 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 OJI 2019 f>>C; if(C==1) { int nr_Fete=0,nr_Baieti=0; char c,c1; int nr,h,m,s; f>>nr; for(int i=1; i<=nr; i++) { f>>c>>c1>>h>>m>>s; if(c==’f’) { if(c1==’e’) nr_Fete--; else nr_Fete++; } else { if(c1==’e’) nr_Baieti--; else nr_Baieti++; } } g<<nr_Baieti<<" "<<nr_Fete; } if(C==2) { int nr_Fete=0,nr_Baieti=0; char c,c1; int nr,s1,s2,h,m,s,timp_total=0; f>>nr; for(int i=1; i<=nr; i++) { f>>c>>c1>>h>>m>>s; bool era_egal=false; if(nr_Fete!=0 && nr_Fete==nr_Baieti) era_egal=true; if(c==’f’) { if(c1==’e’) nr_Fete--; else nr_Fete++; } else { if(c1==’e’) nr_Baieti--; else nr_Baieti++; } if(i==1) { s1=0; s1+=h*3600; s1+=m*60; s1+=s; } else { s2=0; 21 CAPITOLUL 1. 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 22 OJI 2019 s2+=h*3600; s2+=m*60; s2+=s; if(era_egal) timp_total+=s2-s1; s1=s2; } } g<<timp_total; } if(C==3) { int nr_Baieti=0,nr,s1=0,s2,timp_maxim=0; char c,c1; int h,m,s; f>>nr; for(int i=1; i<=nr; i++) { f>>c>>c1>>h>>m>>s; bool era_impar=false; if(nr_Baieti%2==1) era_impar=true; if(c==’b’) { if(c1==’e’) nr_Baieti--; else nr_Baieti++; } if(nr_Baieti%2==1&&s1==0) { s1+=h*3600; s1+=m*60; s1+=s; } else { s2=0; s2+=h*3600; s2+=m*60; s2+=s; if(era_impar&&nr_Baieti%2==0) { if(s2-s1>timp_maxim) timp_maxim=s2-s1; s1=0; } } } g<<timp_maxim; } } Listing 1.2.6: cartele_td.cpp 1 2 3 4 5 6 7 8 9 10 11 12 #include <fstream> using namespace std; ifstream f("cartele.in"); ofstream g("cartele.out"); int maxim,sec1,sec,p,h,m,s,h1,m1,s1,i,N,max1,cb,cf,suma; char c,a; int main() { CAPITOLUL 1. 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 OJI 2019 f>>p; f>>N; if (p==1) { cb=0; cf=0; for (i = 1; i <= N; i++) { f>>c>>a>>h>>m>>s; if (c==’b’) if (a==’i’) cb++; else cb--; else if (a==’i’) cf++; else cf--; } g<<cb<<" "<<cf<<"\n"; } else if (p==2) { f>>c>>a>>h1>>m1>>s1; sec1=h1*3600+m1*60+s1; if (c==’b’) cb=1,cf=0; else cb=0,cf=1; suma=0; for (i = 2; i <= N; i++) { f>>c>>a>>h>>m>>s; sec=h*3600+m*60+s; if (cb==cf && cb>0) suma += (sec-sec1); if (c==’b’) if (a==’i’) cb++; else cb--; else if (a==’i’) cf++; else cf--; sec1=sec; } g<<suma<<"\n"; } else { f>>c>>a>>h1>>m1>>s1; if (c==’b’) {cb=1; cf=0; sec1=h1*3600+m1*60+s1;} else cb=0,cf=1; maxim=0; for (i = 2; i <= N; i++) { f>>c>>a>>h>>m>>s; sec=h*3600+m*60+s; if (c==’b’) { if (cb%2!=0 && sec-sec1 > maxim) maxim=sec-sec1; if (a==’i’) cb++; else cb--; sec1=sec; } else if (a==’i’) cf++; else cf--; } g<<maxim<<"\n"; } return 0; 23 CAPITOLUL 1. 89 } OJI 2019 24 Capitolul 2 OJI 2018 2.1 Patrate - OJI 2018 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 p tratul P 1 este egal 1 $ P ³i cel mai mare num r din cu 1. Primele patru p trate sunt: Figura 2.1: Patrate Astfel, primul p trat conµine numerele naturale distincte consecutive de la 1 la 8, dispuse câte trei pe ecare latur a p tratului. Al doilea p trat conµine urm toarele 16 numere naturale distincte consecutive, dispuse câte cinci pe ecare latur . Al treilea p trat conµine urm toarele 24 de numere naturale distincte consecutive, dispuse câte ³apte pe ecare latur . Al patrulea p trat conµine urm toarele 32 de numere naturale distincte consecutive, dispuse câte nou latur pe ecare etc. Cerinµe Scrieµi un program care rezolv urm toarele dou 1. cite³te un num r natural M ³i determin cerinµe: 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 din problem patrate.in conµine pe prima linie un num r natural C reprezentând cerinµa (1 sau 2). Dac C 1, atunci ³ierul conµine pe a doua linie 2, atunci ³ierul conµine pe a doua linie num rul natural N . care trebuie rezolvat num rul natural M . Dac C Date de ie³ire 25 CAPITOLUL 2. 26 OJI 2018 1, atunci ³ierul de ie³ire patrate.out conµine pe prima linie num rul K , reprezenC 2, atunci ³ierul de ie³ire patrate.out conµine pe prima linie num rul natural T , reprezentând r spunsul la cerinµa 2. Dac C tând r spunsul la cerinµa 1 a problemei. Dac Restricµii ³i preciz ri a 1 a 7 & M & 260000000 & 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 cerinµei 1 se acord 10 puncte; pentru rezolvarea corect 2 se acord 80 de puncte. Se acord 10 puncte din ociu. a Pentru rezolvarea corect Exemple patrate.in 1 a cerinµei patrate.out Explicaµii Cerinµa este 1. P tratul numerotat cu M 3 conµine 24 de numere naturale (vezi gura din enunµ). Cerinµa este 2. Num rul N 73 este conµinut de p tratul K 24 numerotat cu T 4 (vezi gura din enunµ). 24 K 3 2 4 73 Timp maxim de executare/test: 0.3 secunde Memorie: 8M B Dimensiune maxim a sursei: 5KB 2.1.1 Indicaµii de rezolvare Descrierea soluµiei Autor prof. Carmen Minc Colegiul Naµional de Informatic "Tudor Vianu" - Bucure³ti P tratele conµin numere naturale distincte consecutive. Primul p trat are pe latur L 3 2 1 1 numere ³i conµine în total K 4L4 81 numere Al doilea p trat are pe latur L 5 2 2 1 numere ³i conµine în total K 4L4 28 L 7 2 3 1 numere ³i conµine în total K 4L4 38 L 2 T 1 numere ³i conµine în total 4 L 4 numere Al treilea p trat are pe latur numere ........... Al T -lea p trat are pe latur T 8 numere Cerinµa 1. Pe laturile p tratului M sunt scrise 8 M numere naturale distincte. Cerinµa 2. Num rul de numere folosite în primele T 1 p trate este: 8 1 8 2 8 3 ... 8 T 1 8 1 2 3 ... T 1 4 T T 1 4 T T 1 1, 4 T T 1 2, 4 T T 1 3, ..., 4 T T 1 8 T 4 T T 1 Num rul N este în p tratul T dac este adev rat relaµia: 4 T T 1 1 & N & 4 T T 1 Numerele din p tratul T sunt: 2.1.2 *Rezolvare detaliat 2.1.3 Cod surs Listing 2.1.1: patrate_AS.cpp 1 2 3 4 5 //#include <iostream> #include <fstream> #include<cmath> using namespace std; CAPITOLUL 2. 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 27 OJI 2018 int N,C,K,M,T; int main() { ifstream in("patrate.in"); ofstream out("patrate.out"); in>>C; if(C==1) { in>>M; out<<8*M<<endl; } else { in>>N; T=sqrt(N); if(T%2)T++; out<<T/2<<endl; } return 0; } Listing 2.1.2: patrate_cpp_CM.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <fstream> using namespace std; ifstream f("patrate.in"); ofstream g("patrate.out"); int main() { int N,C,M,T,K,nr=0; f>>C; if(C==1) { f>>M; K=8*M; g<<K<<endl; } else { f>>N; T=0; nr=0; while(8*(T+1)<=N-nr) { ++T; K=8*T; nr=nr+K; } if(N>nr){ ++T; } g<<T<<endl; } return 0; } Listing 2.1.3: patrate_FB.cpp 1 2 3 4 5 6 7 8 9 //#include <iostream> #include <fstream> using namespace std; ifstream f("patrate.in"); ofstream g("patrate.out"); long long c,N,x,k,T,M; CAPITOLUL 2. 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 28 OJI 2018 int main() { f>>c; if(c==1) { f>>M; g<<8*M; } else { f>>N; k=8; T=1; while(N-k>0) { N=N-k; k=k+8; T++; } g<<T; } return 0; } Listing 2.1.4: patrate_VG.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <fstream> using namespace std; int main() { int m, cer, n; long long t,x; ifstream f("patrate.in"); ofstream g("patrate.out"); f>>cer>>n; if(cer==1) g<<8*n<<endl; else { if(n<8) g<<1<<endl; else { m=1; t=0; x=0; while(t<n) { t=8*(m+x); x+=m; m++; } g<<m-1<<endl; } } return 0; } 2.2 forus - OJI 2018 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 între dou cifre ³i s lipeasc partea stâng taie o singur la nalul p rµii drepte. Elevul dat cartonul NU are voie s fac î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 o t ietur 29 CAPITOLUL 2. OJI 2018 divizori, iar dac poate obµine mai multe astfel de numere, îl alege pe cel mai mic dintre ele. La sfâr³itul orei, profesorul strânge cartoanele cu numerele alese, în ordinea distribuirii lor. De exemplu, dac iniµial elevul prime³te cartonul cu num rul 25082 atunci el are doar urm - toarele trei variante de t iere ³i lipire: Figura 2.2: forus Cerinµe Scrieµi un program care cite³te num rul natural N ³i cele N numere scrise pe cartoanele aduse de profesorul Forus, apoi rezolv 1. determin urm toarele dou cerinµe: num rul de cartoane pe care elevii au voie s în faµa c rora NU au voie s le taie de oriunde (NU conµin cifre 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 din problem forus.in conµine pe prima linie un num r natural C reprezentând cerinµa 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 a 1 & N & 30 & num rul natural de pe carton $ 1000000000 a cerinµei 1 se acord 20 de puncte; pentru rezolvarea corect 70 de puncte. Se acord 10 puncte din ociu. a Pentru rezolvarea corect cerinµei 2 se acord a 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 5 51 1234 50822 345 150 15 2341 25082 453 501 Cerinµa este 2. Pentru cartonul cu num rul 51 se pot obµine numerele 15 ³i 51. Ambele 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 2. 30 OJI 2018 Timp maxim de executare/test: 0.5 secunde Memorie: 8M B Dimensiune maxim a sursei: 10KB 2.2.1 Indicaµii de rezolvare Descrierea soluµiei Autor prof. FLAVIUS BOIAN Colegiul Naµional "SPIRU HARET" TG-JIU Cerinµa 1. Pentru ecare num r citit, se veric dac conµine cel puµin o cifr de 0 în scrierea sa. Se vor contoriza numerele citite care nu conµin cifra 0. Cerinµa 2. Pentru ecare num r citit se construiesc prin permut ri circulare la dreapta cu o poziµie toate numerele posibile. divizori, cu observaµia c (nu am voie s Dintre acestea se va alege num rul cu un num r minim de num rul ales trebuie s aib acela³i num r de cifre ca ³i num rul iniµial 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. 2.2.2 *Rezolvare detaliat 2.2.3 Cod surs Listing 2.2.1: forus_CM_100.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 ///#include <iostream> #include <fstream> using namespace std; ifstream f("forus.in"); ofstream g("forus.out"); int nrdiv(int N) { int d, nrd=1; for(d=1;d*d<N;d++) if(N%d==0)nrd+=2; if(d*d==N) ++nrd; return nrd; } int main() { int C,N,nr; f>>C>>N; if(C==1) { int r=0,ok; for(int i=1; i<=N; i++) { f>>nr; //cout<<nr<<" "; ok=1; while(nr && ok) { if (nr%10==0)ok=0; nr=nr/10; } r=r+ok; } g<<r<<endl; } else { CAPITOLUL 2. 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 31 OJI 2018 int y,p,nrc,x,pr,ult,pu,xmin,nrdm,nrd,z; for(int i=1; i<=N; i++) { f>>nr; p=1;nrc=1;pu=10; xmin=nr; nrdm=nrdiv(nr); x=nr; while(x>0) { x=x/10; p=p*10; nrc++; } p=p/10;z=p; for(int i=1; i<nrc; i++) { pr=nr/p; ult=nr%p; x=ult*pu+pr; if(x/z>0) { nrd=nrdiv(x); if(nrd<nrdm) { xmin=x; nrdm=nrd; } else if(nrd==nrdm) xmin=min(xmin,x); } pu=pu*10; p=p/10; } g<<xmin<<" "; } g<<endl; } return 0; } Listing 2.2.2: forus_nvl_100.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 /// Nicu Vlad-Laurentiu #include <bits/stdc++.h> using namespace std; ifstream fin("forus.in"); ofstream fout("forus.out"); int nr_div(int x) { int p,d=2,N=1; while(x>1) { p=0; while(x%d==0) { p++; x/=d; } if(p)N*=(p+1); if(d*d<x) d++; else d=x; } return N; } int pow10(int nc) { int P=1; for(int i=1; i<=nc; ++i) P*=10; CAPITOLUL 2. 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 32 OJI 2018 return P; } int main() { int n,x,cer; fin>>cer>>n; if(cer==1) { int nr=0,nc,n0; for(; n; n--) { fin>>x; nc=0,n0=0; if(x==0) nr++; while(x) { if(x%10==0) n0++; nc++; x/=10; } if(n0==0) nr++; } fout<<nr; } else { int nc; long long put,nrmax=0,val,nrc; for(; n; n--) { fin>>x; nc=log10(x); put=pow10(nc); nrmax=nr_div(x); val=x; for(int i=1; i<=nc; ++i) { x=x%put*10+x/put; if(x/put!=0) { nrc=nr_div(x); if(nrc<nrmax) { nrmax=nrc; val=x; } else if(nrc==nrmax &&val>x) val=x; } } fout<<val<<" "; } } return 0; } Listing 2.2.3: forus_VG_100.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <fstream> using namespace std; int main() { ifstream f("forus.in"); ofstream g("forus.out"); long long x,mx; int c, n, a,b, r,i,ok,nd,d,y,nc,p,j,nz; f>>c; if(c==1) { CAPITOLUL 2. 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 OJI 2018 f>>n; r=0; for(i=1;i<=n;i++) { f>>x; ok=1; while(x>0 && ok) if(x%10==0) ok=0; else x/=10; if(ok) r++; } g<<r; } else { f>>n; for(i=1;i<=n;i++) { f>>x; if(x<10) g<<x<<’ ’; else { y=x; mx=1000000000; nc=0; p=1; while(x) { nc++; x/=10; p=p*10; } p=p/10; x=y; do { nd=0; for(d=1;d*d<x;d++) if(x%d==0) nd+=2; if(d*d==x) nd++; // g<<x<<’ ’<<nd<<’ ’<<’\n’; if(nd<mx) { r=x; mx=nd; } else if(nd==mx) if(x<r) r=x; if(x/(p/10)%10==0) { nz=0; y=p/10; while(x/y%10==0 && y>1) { y=y/10; nz++; } a=x/p; x=x*10+a; x=x%p; for(j=1;j<=nz;j++) x=x*10; nc=nc-nz; } else { a=x/p; b=x%p; x=b*10+a; } 33 CAPITOLUL 2. 92 93 94 95 96 97 98 99 100 101 102 34 OJI 2018 nc--; } while(nc>0); g<<r<<’ ’; } } } return 0; } Listing 2.2.4: ocial_FB_100.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 #include <iostream> #include <fstream> #include <cmath> using namespace std; ifstream f("forus.in"); ofstream g("forus.out"); int N,P,i,u,x,ok,k,t,cifre,minim,numar,pf,ps,p,ajt; int main() { f>>P>>N; if(P==1) { for(i=1; i<=N; i++) { f>>x; ok=1; while(x) { u=x%10; if(u==0) { ok=0; break; } x=x/10; } if(ok==1) k++; } g<<k; } if(P==2) { for(i=1; i<=N; i++) { f>>x; t=x; cifre=0; while(t) { t=t/10; cifre++; } t=x; int prod=1,d,putere=0; while(t%2==0) { t=t/2; putere++; } if(putere>0) prod=prod*(putere+1); d=3; while(t>1) { putere=0; while(t%d==0) { t=t/d; putere++; CAPITOLUL 2. 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 OJI 2018 } if(putere>0) prod=prod*(putere+1); d=d+2; if(d*d>t) d=t; } minim=prod; t=x; numar=x; k=cifre-1; p=1; while(k) { p*=10; k--; } k=cifre-1; while(k) { if(t%10!=0) { pf=t%10; ps=t/10; t=pf*p+ps; prod=1,putere=0; ajt=t; while(t%2==0) { t=t/2; putere++; } if(putere>0) prod=prod*(putere+1); d=3; while(t>1) { putere=0; while(t%d==0) { t=t/d; putere++; } if(putere>0) prod=prod*(putere+1); d=d+2; if(d*d>t) d=t; } if(prod<minim) { minim=prod; numar=ajt; } if(prod==minim and ajt<numar) { numar=ajt; } t=ajt; } else { pf=t%10; ps=t/10; t=pf*p+ps; } k--; } g<<numar<<" "; } } return 0; } 35 Capitolul 3 OJI 2017 3.1 numere - OJI 2017 Problema 1 - numere 90 de puncte Un copil construie³te un triunghi cu numerele naturale nenule astfel: - în vârful triunghiului scrie valoarea 1; - completeaz liniile triunghiului de sus în jos, iar c suµele de pe aceea³i linie de la stânga la dreapta cu numere naturale consecutive, ca în gurile urm toare. Figura 3.1: Numere În gura 1 este ilustrat un astfel de triunghi având 5 linii, conµinând numerele naturale de la 1 la 15. În acest triunghi copilul începe s construiasc drumuri, respectând urm toarele reguli: - orice drum începe din 1; - din orice c suµ codicat se poate deplasa e în c suµa situat cu 1), e în c suµa situat pe linia urm toare în stânga sa (deplasare 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 din problem numere.in conµine pe prima linie un num r natural C reprezentând cerinµa care trebuie rezolvat (1 sau 2). 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 . Dac Date de ie³ire 36 CAPITOLUL 3. Fi³ierul de ie³ire natural. Dac Dac C 37 OJI 2017 C numere.out va conµine o singur linie pe care va scris un singur num r 1, va scris num rul cu care se termin 2, va scris suma maxim drumul descris în ³ierul de intrare. a numerelor aate pe un drum care se termin cu num rul K. Restricµii ³i preciz ri a 1 a 1 & N & 10000 & K & 10001 10002©2 a cerinµei 1 se acord 40 de puncte; pentru rezolvarea corect 50 de puncte. 10 puncte se acord din ociu. a Pentru rezolvarea corect cerinµei 2 se acord Exemple numere.in 1 a numere.out Explicaµii 13 Cerinµa este 1. Drumul descris are lungimea 4 ³i trece prin numerele 1, 2, 5, 8, 13 . 4 1 2 1 2 2 19 Cerinµa este 2. Suma maxim se obµine pe drumul care trece prin numerele 1, 3, 6, 9 1 3 6 9 9 19. Timp maxim de executare/test: 0.2 secunde Memorie: 2 MB din care 1 MB pentru stiv Dimensiune maxim a sursei: 10 KB 3.1.1 Indicaµii de rezolvare prof. Cerasela-Daniela Cardas, Colegiul Naµional A.T.Laurian Boto³ani 1.Initializam casuta curenta si numarul liniei de pornire cu 1. Pentru fiecare din cei n pasi din descriere: - o alegere de tip 1 presupune actualizarea casutei curente cu valoarea casuta_cure - o alegere de tip 2 conduce la actualizarea casutei curente cu casuta_curenta+lini - incrementam numarul liniei curente. 2. Daca linia pe care se afla numarul K este l si numarul de ordine al numarului K pe linia l este c, se observa ca suma maxima se obtine din insumarea ultimelor valo de pe liniile 1,2,...,c si a valorilor de pe pozitia c din liniile c+1,c+2...,l. Fie ultim - valoarea ultimului element de pe fiecare linie si l valoarea liniei cur Initial ultim=1, l=0. Cat timp ultim < K,incrementam linia, actualizam ultim cu ultim<-ultim+l, calculam numerelor de linie. Cand ultim>=K, elemc<-K Repetat -eliminam din suma s ultimul element de pe linia l si adunam elementul de pe poziti -elemc<-elemc-l+1 -decrementam linia l pana cand l=c 3.1.2 *Rezolvare detaliat 3.1.3 Cod surs CAPITOLUL 3. 38 OJI 2017 Listing 3.1.1: numere_cardas.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ///autor prof. Cerasela-Daniela Cardas, Colegiul National A.T.Laurian Botosani #include <fstream> using namespace std; ifstream fin("numere.in"); ofstream fout("numere.out"); unsigned C,N,K,pas,curent,linie,rest,s,ultim; int main() { fin>>C; if(C==1) { fin>>N;curent=1; for(linie=1;linie<=N;linie++) { fin>>pas; curent+=linie; if(pas==2) curent++; } fout<<curent<<’\n’; return 0; } ///C=2 fin>>K; while(ultim<K) { ultim+=++linie; s+=ultim; } rest=ultim-K; s-=rest*(rest+1)/2; fout<<s<<’\n’; return 0; } Listing 3.1.2: numere_cerchez.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 //Emanuela Cerchez 90 puncte #include <fstream> using namespace std; ifstream fin("numere.in"); ofstream fout("numere.out"); int c, n, K, nr, sum; int main() { int lin, col, i, j, d, ultim; fin>>c; if (c==1) { fin>>n; col=1; for (i=0; i<n; i++) { fin>>d; col+=d-1; } lin=n+1; nr=lin*(lin-1)/2;//1+2+...lin-1 nr+=col; fout<<nr<<’\n’; } else { fin>>K; for (lin=1; K>lin*(lin+1)/2; lin++); col=K-lin*(lin-1)/2; sum=ultim=0; CAPITOLUL 3. 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 39 OJI 2017 for (i=1; i<=col; i++) { ultim+=i; sum+=ultim; } for (i=col+1; i<=lin; i++) { ultim+=i; sum+=(ultim-(i-col)); } fout<<sum<<’\n’; } fout.close(); return 0; } Listing 3.1.3: numere_jakab.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 #include <iostream> #include <fstream> #include <stdlib.h> using namespace std; int main() { ifstream in("numere.in"); ofstream out("numere.out"); int p,a,b,n,i,nr=1,lin,col; in>>p; if(p==1) { in>>n; for(i=2;i<=n+1;i++) { in>>a; if(a==1) nr=nr+i-1; else nr=nr+i; } out<<nr<<endl; } if(p==2) { in>>nr; a=1;lin=1; while(a<nr) { lin++; a=a+lin; } col=(a+nr)%lin; a=1; b=1; for(i=2;i<=col;i++) { b=b+i; a=a+b; } for(i=col;i<lin;i++) { b=b+i; a=a+b; } out<<a; } in.close(); out.close(); return 0; } CAPITOLUL 3. 40 OJI 2017 Listing 3.1.4: numere_sandor.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <fstream> using namespace std; ifstream fin("numere.in"); ofstream fout("numere.out"); int main() { int C,N,nr,i,x; fin>>C; if(C==1) { fin>>N;nr=1; for(i=1;i<=N;i++) { fin>>x; if(x==1) nr=nr+i; else nr=nr+i+1; } fout<<nr; } else { int n,S; fin>>N; n=1; while(n*(n+1)/2<N) n++; S=N; while(n*(n+1)/2!=N) { n--; N=N-n; S=S+N; } n--; while(n>=1) { S=S+n*(n+1)/2; n--; } fout<<S; } return 0; } Listing 3.1.5: numere_vladescu.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <fstream> using namespace std; ifstream fin("numere.in"); ofstream fout("numere.out"); int n,c,nr,i,k,x,s,a,b,j; int main() { fin>>c; if (c==1) { fin>>n; nr=1; for (i=1;i<=n;i++) { fin>>x; if (x==1) nr=nr+i; else CAPITOLUL 3. 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 41 OJI 2017 nr=nr+i+1; } fout<<nr; } else { fin>>k; i=1; a=1; while (a<k) { a=i*(i+1)/2; if (k>a) i=i+1; } b=0; a=(i-1)*i/2; while (a<k) { a=a+1; b=b+1; } for (j=1;j<=b;j++) s=s+j*(j+1)/2; for (j=b+1;j<=i-1;j++) s=s+j*(j-1)/2+b; s=s+k; fout<<s; } return 0; } 3.2 robot - OJI 2017 Problema 2 - robot Paul dore³te s înveµe cum s 90 de puncte programeze un robot. Pentru început s-a gândit s construiasc un robot format dintr-un mâner, 10 butoane aranjate circular ³i un ecran. Pe butoane sunt scrise, în ordine cresc toare, cifrele de la 0 la 9, ca în gur . Figura 3.2: Robot Un roboprogram va format dintr-o secvenµ de instrucµiuni. Instrucµiunile pot : Instrucµiune Explicaµii Dp Mânerul robotului se deplaseaz spre dreapta cu p poziµii (p este o cifr ). Sp Mânerul robotului se deplaseaz spre stânga cu p poziµii (p este o cifr ). A Este ap sat butonul în dreptul c ruia se a apare cifra scris T mânerul robotului ³i pe ecran pe buton. 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 1. cite³te un roboprogram ³i determin roboprogramului; urm toarele cerinµe: num rul de cifre a³ate pe ecran dup executarea CAPITOLUL 3. 42 OJI 2017 2. cite³te un roboprogram ³i determin cifrele a³ate pe ecran dup executarea roboprogra- mului; 3. cite³te un num r natural N ³i construie³te un roboprogram de lungime minim tarea c ruia pe ecran se va obµine num rul N ; deoarece robotului îi place s spre dreapta, dac exist prin execu- se deplaseze în special mai multe roboprograme de lungime minim , se va a³a roboprogramul cu num r maxim de instrucµiuni D. Date de intrare Fi³ierul de intrare care urmeaz a s robot.in conµine pe prima linie un num r natural C , reprezentând cerinµa (1, 2 sau 3). Dac e rezolvat un roboprogram. Dac C C 1 sau C 2, pe a doua linie a ³ierului se 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 C linie. Dac 1, pe prima linie se va scrie un num r natural reprezentând num rul de cifre a³ate pe ecran dup executarea roboprogra- 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. mului din ³ierul de intrare. Dac C 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 c tre butonul 1; dac a Pentru rezolvarea corect 10 de puncte, pentru rezolvarea corect 30 de puncte, iar pentru rezolvarea corect a celei de a treia a primei cerinµe se acord a celei de a doua cerinµe se acord cerinµe se acord spre dreapta, se va îndrepta deplasarea este spre stânga, se va îndrepta c tre butonul 9. 50 de puncte. 10 puncte se acord din ociu. Exemple robot.in robot.out Explicaµii 1 3 D1AD2AS1AT 2 C 1, pentru acest test se rezolv cerinµa 1. pe ecran 3 cifre (132) . 2, pentru acest test se rezolv cerinµa 2. Se a³eaz 3 S0AD2AS1AT C 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 1 unitate la stânga ³i ajunge în dreptul butonului 1 ³i apas acest buton 021. C 3, pentru acest test se rezolv cerinµa 3. Pentru a a³a cifra 1, mânerul robotului se deplaseaz 1 unitate 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 se deplaseaz 3 3 19332 r mâne în poziµia curent 2, din poziµia curent ³i apas butonul. Pentru a a³a cifra mânerul robotului se deplaseaz tate la stânga dup care apas instrucµiunea T D1AS2AD4AAS1AT . Timp maxim de executare/test: 0.2 secunde Memorie: total 2 MB din care pentru stiv 1 MB Dimensiune maxim a sursei: 10 KB 1 uni- (S1A). Programul se termin cu CAPITOLUL 3. 3.2.1 43 OJI 2017 Indicaµii de rezolvare prof. Jakab Irma-Tunde, Liceul Teoretic "Bolyai Farkas" Punctul 1 Numarul de cifre afisate pe ecran dupa executarea roboprogramului inseamna de cate apasa robotul un anumit buton, adica de cate ori trebuie sa se execute instructiune Astfel, se citeste roboprogramul caracter cu caracter si se numara caracterele ’A’. Punctul 2 Determinarea cifrelor afisate pe ecran dupa executarea roboprogramului inseamna det cifrei in dreptul careia se va pozitiona manerul robotului la executarea instructiu Se citesc datele caracter cu caracter, se identifica directia si pozitia iar in fun directia indicata se determina cifra care trebuie afisata. Pentru stabilirea pozitiei, caracterele cifre din roboprogram trebuie transformate cifre numerice. Daca directia indicata este dreapta si deoarece manerul robotului se deplaseaza cir numarul de pozitii efectuate va fi suma dintre pozitia (cifra curenta) si cifra ind in program modulo 10 (avand in total 10 cifre). Daca directia indicata este dreapta din cauza deplasarii circulare din pozitia curenta se scade cifra din roboprogram, rezultatul este negativ, se aduna 10. Trebuie sa se tina cont de faptul ca instructiunile pot sa indice cifre 0 chiar la respectiv cifrele pot aparea de mai multe ori datorita prezentei repetate a instruc Punctul 3 Pentru numarul citit, instructiunile trebuie asociate incepand de la cifra cea mai semnificativa spre cifra unitatilor si trebuie acordat atentie cifrelor 0 de la sfa numarului dat (se determina oglinditul numarului si se retine numarul de zerouri de sfarsitul numarului citit). Numarul citit se prelucreaza cifra cu cifra, se calculeaza numarul de deplasari nec spre stanga si spre dreapta, se alege directia in care deplasarea se va face intr-u minim de pasi. In calcularea numarului de deplasari se tine cont de miscarea circulara a manerului In cazul in care cele doua numere sunt egale, se alege directia dreapta. Daca numarul citit avea zerouri la sfarsitul numarului, se determina numarul de dep necesare afisarii acestora si se introduc in roboprogram un numar de instructiuni A numarul de zerouri calculate. 3.2.2 *Rezolvare detaliat 3.2.3 Cod surs Listing 3.2.1: robot_cerchez.cpp 1 2 //Em. Cerchez 90 puncte #include <fstream> CAPITOLUL 3. 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 OJI 2017 using namespace std; ifstream fin("robot.in"); ofstream fout("robot.out"); int cerinta, n; int main() { char c; int nr, st, dr, poz, zero, cat, cifra; fin>>cerinta; if(cerinta==1) { c=’*’; nr=0; while (c!=’T’) { fin>>c; if (c==’A’) nr++; } fout<<nr<<’\n’; fout.close(); return 0; } if(cerinta==2) { c=’*’; nr=0; poz=0; while (c!=’T’) { fin>>c; if (c==’A’) fout<<poz; else if (c==’D’) { fin>>c; cat=c-’0’; poz=(poz+cat)%10; } else if (c==’S’) { fin>>c; cat=c-’0’; poz-=cat; if(poz<0) poz+=10; } } fout<<’\n’; fout.close(); return 0; } fin>>n; if (n==0){fout<<"AT\n"; fout.close(); return 0; } zero=0; while (n%10==0) {zero++;n/=10;} nr=0; while (n) {nr=nr*10+n%10; n/=10;} //obtin nr poz=0; while (nr) { cifra=nr%10; nr/=10; if (cifra!=poz) { if (cifra<poz) { st=poz-cifra; dr=10+cifra-poz; } 44 CAPITOLUL 3. 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 45 OJI 2017 else { dr=cifra-poz; st=10+poz-cifra; } if (st<dr) fout<<"S"<<st; else fout<<"D"<<dr; } poz=cifra; fout<<"A"; } if (zero) { if (poz) { dr=10-poz; st=poz; if (st<dr) fout<<"S"<<st; else fout<<"D"<<dr; } while (zero) {fout<<"A"; zero--;} } fout<<"T\n"; fout.close(); return 0; } Listing 3.2.2: robot_cerchez_ok.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 //Em. Cerchez 90 puncte #include <fstream> using namespace std; ifstream fin("robot.in"); ofstream fout("robot.out"); int cerinta, n; int main() { char c; int nr, st, dr, poz, zero, cat, cifra; fin>>cerinta; if (cerinta==1) { c=’*’; nr=0; while (c!=’T’) { fin>>c; if (c==’A’) nr++; } fout<<nr<<’\n’; fout.close(); return 0; } if (cerinta==2) { c=’*’; nr=0; poz=0; while (c!=’T’) { fin>>c; if (c==’A’) fout<<poz; else if (c==’D’) { fin>>c; cat=c-’0’; poz=(poz+cat)%10; } CAPITOLUL 3. 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 46 OJI 2017 else if (c==’S’) { fin>>c; cat=c-’0’; poz-=cat; if(poz<0) poz+=10; } } fout<<’\n’; fout.close(); return 0; } fin>>n; if (n==0){fout<<"AT\n"; fout.close(); return 0; } zero=0; while (n%10==0) {zero++;n/=10;} nr=0; while (n) {nr=nr*10+n%10; n/=10;} //obtin nr poz=0; while (nr) { cifra=nr%10; nr/=10; if (cifra!=poz) { if (cifra<poz) { st=poz-cifra; dr=10+cifra-poz; } else { dr=cifra-poz; st=10+poz-cifra; } fout<<"D"<<dr; } poz=cifra; fout<<"A"; } if (zero) { if (poz) { dr=10-poz; st=poz; fout<<"D"<<dr; } while (zero) {fout<<"A"; zero--;} } fout<<"T\n"; fout.close(); return 0; } Listing 3.2.3: robot_jakab.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //Jakab Tunde #include <iostream> #include <fstream> #include <stdlib.h> using namespace std; int main() { ifstream in("robot.in"); ofstream out("robot.out"); char c; int a=0,b=0,n=0,m=0,z=0,e,d,p; in>>p; CAPITOLUL 3. 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 OJI 2017 if(p==1) { while(!in.eof()) { in>>c; if (c==’A’)a++; } out<<a<<endl; } if(p==2) { in>>c; b=0; while(c!=’T’) { if (c==’D’) { in>>c; a=c-48; b=(b+a)%10; } else if (c==’S’) { in>>c; a=c-48; b=(b+10-a)%10; } if(c==’A’) out<<b; in>>c; } } if(p==3) { in>>a; if(a==0)out<<"A"; else if(a<10) { if(10-a<a) out<<’S’<<10-a<<’A’; else out<<’D’<<a<<’A’; } else { z=0; while(a%10==0) { z++; a=a/10; } while(a!=0) { b=b*10+a%10; a=a/10; } a=b; b=a%10; if(10-b<b) out<<’S’<<10-b<<’A’; else out<<’D’<<b<<’A’; a=a/10; while(a!=0) { if(b==a%10) out<<’A’; else if(b>a%10) if(10-b+a%10<=b-a%10) out<<’D’<<10-b+a%10<<’A’; else 47 CAPITOLUL 3. 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 OJI 2017 out<<’S’<<b-a%10<<’A’; else if(10-a%10+b<a%10-b) out<<’S’<<10-a%10+b<<’A’; else out<<’D’<<a%10-b<<’A’; b=a%10; a=a/10; } if(z!=0) { if(10-b<b) out<<’D’<<b; else out<<’S’<<b; while(z!=0) { out<<’A’; z--; } } } out<<’T’; } in.close(); out.close(); return 0; } 48 Capitolul 4 OJI 2016 4.1 colier - OJI 2016 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 m rgelele sunt de dou tipuri, în funcµie de num rul de dou au cifra zecilor mai mic decât cifra unit µilor) ³i tipul 2 (celelalte). dore³te ca prin eliminarea unora dintre ele (dar f r un colier s c cifre scris pe ele: tipul 1 (cele care Folosind m rgelele, fetiµa le schimbe ordinea celorlalte) s obµin 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 prima m rgea este vecin eliminare se consider c 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 ie³ire Dac ie³ire valoarea lui T este 1, se va rezolva numai punctul 1) din cerinµe. În acest caz, ³ierul de colier.out va conµine pe prima linie un num r natural reprezentând r spunsul la cerinµa 1). valoarea lui T este 2, se va rezolva numai punctul 2) din cerinµe. În acest caz, ³ierul de 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 ³i 987654321; 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 au dou 1 ³i toate numerele scrise iniµial pe m rgele cifre; a Pentru teste în valoare de 30 de puncte avem T m rgele sunt ³i unele cu mai mult de dou 1 ³i dintre numerele scrise iniµial pe cifre; a Pentru teste în valoare de 50 de puncte avem T 49 2. CAPITOLUL 4. 50 OJI 2016 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 2 4 doar cerinµa 1). Numerele scrise de Maria pe m rgele vor , în ordine: 12 68 31 5 24 93. 12 678 312 24 938 poziµia 2 ³i a³ezându-le pe celelalte circular obµinem un colier cu Eliminând m rgeaua de pe poziµia 1 sau pe cea de pe 4 m rgele în care oricare dou ind 2 se rezolv vecine sunt de tipuri diferite. (T doar cerinµa 2). Maria este obligat una din cele dou s elimine m rgele, altfel ar exista m rgele vecine de acela³i tip. Timp maxim de executare/test: 0.5 secunde Memorie: total 32 MB Dimensiune maxim a sursei: 15 KB 4.1.1 Indicaµii de rezolvare prof. Marius Nicoli, C.N. Fratii Buze³ti, Craiova Prima cerinµ se rezolv prin aplicarea pentru ecare num r a algoritmului de parcurgere a cifrelor sale, identicând cifra maxim si cea minim a sa, precum ³i poziµiile lor. Pentru cerinµa a doua, determin m câte secvenµe maximale formate din valori de acela³i tip exist . Dac prima ³i ultima secvenµ valoarea dererminat sunt formate din acela³i tip de m rgele, sc dem 1 din anterior. Ambele cerinµe se rezolv procesând numerele în momentul citirii, deci f r de memorie. 4.1.2 *Rezolvare detaliat 4.1.3 Cod surs Listing 4.1.1: colier_gina.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include<fstream> using namespace std; ifstream f("colier.in"); ofstream g("colier.out"); int main() { int x,P,M,p,m,poz=0,n,t,s=0,a,b,k=1; f>>t>>n; f>>x; poz=0; m=10; M=-1; while(x) { poz++; if(x%10>M) { M=x%10; P=poz; } a necesare tablouri CAPITOLUL 4. 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 51 OJI 2016 if(x%10<m) { m=x%10; p=poz; } x=x/10; } s+=(1+(p<P))==1; a=1+(p<P); for(int i=2;i<=n;i++) { f>>x; poz=0; m=10; M=-1; while(x) { poz++; if(x%10>M) { M=x%10; P=poz; } if(x%10<m) { m=x%10; p=poz; } x=x/10; } s+=(1+(p<P))==1; b=1+(p<P); if(a!=b) { k++; a=b; } } if(k%2)k--; if(t==1) g<<s<<’\n’; else g<<k<<’\n’; f.close(); g.close(); return 0; } Listing 4.1.2: colier_Marius.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <fstream> using namespace std; int n, i, x, c, maxim, minim, nr, pmaxim, pminim, tip, tipa, sol1, sol2, first, t; int main () { ifstream fin ("colier.in"); ofstream fout("colier.out"); fin>>t>>n; sol2 = 1; for(i=1;i<=n;i++) { fin>>x; maxim = 0; minim = 9; nr = 0; while(x != 0) { c = x % 10; CAPITOLUL 4. 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 52 OJI 2016 nr++; if(c > maxim) { maxim = c; pmaxim = nr; } if(c < minim) { minim = c; pminim = nr; } x /= 10; } if(pmaxim < pminim) { tip = 1; sol1++; } else { tip = 2; } if(i == 1) first = tip; else { if (tip != tipa) { sol2++; } } tipa = tip; } if (tip == first) sol2--; if (t == 1) fout<<sol1<<"\n"; else { if (sol1 == n || sol1 == 0) fout<<"1\n"; else fout<<sol2<<"\n"; } return 0; } Listing 4.1.3: colier_Miana.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include<fstream> using namespace std; ifstream f("colier.in"); ofstream g("colier.out"); int main() { int n, nr=1, tip1=0, tip2=0,x,c,u,k=0,cmin=10,cmax=0,pcmin,pcmax,p,i,t; f>>t>>n>>x; while (x) { c=x%10; k++; if (c<cmin) { cmin=c; pcmin=k; } if (c>cmax) { cmax=c; pcmax=k; } x/=10; } if (pcmin>pcmax) { tip1++; u=p=1; } else { tip2++; u=p=2; } CAPITOLUL 4. 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 53 OJI 2016 for (i=2; i<=n; i++) { f>>x; k=0; cmin=10; cmax=0; while (x) { c=x%10; k++; if (c<cmin) { cmin=c; pcmin=k; } if (c>cmax) { cmax=c; pcmax=k; } x/=10; } if (pcmin>pcmax) { tip1++; if (u!=1) {nr++; u=1;} } else { tip2++; if (u!=2) {nr++; u=2;} } } if (u==p) nr--; if (t==1) g<<tip1<<’\n’; else g<<nr<<’\n’; return 0; } Listing 4.1.4: colier_sanda.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <iostream> #include <fstream> using namespace std; ifstream f("colier.in"); ofstream out("colier.out"); int main() { int n,m,x,y,a,b,c,T,maxim,minim,maxi,mini,tipa,tipb,tipul,tip1=0,i,k; ifstream in("colier.in"); in>>T; in>>n;m=n; in>>a; y=a; maxim=0; maxi=0; minim=999999999; mini=0, k=0; while(y) { c=y%10;k++; if(c>maxim) maxim=c,maxi=k; if(c<minim) minim=c,mini=k; y/=10; } if(mini>maxi) tip1++,tipa=1; else tipa=2; tipul=tipa; // cout<<"a="<<a<<endl; // cout<<"*"<<n<<" "<<tip1<<" "<<tipa<<endl; CAPITOLUL 4. 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 54 OJI 2016 for(i=2;i<=m;i++) { in>>b; // cout<<"b="<<b<<endl; y=b;maxim=0;maxi=0;minim=999999999; mini=0;k=0; while(y) { c=y%10;k++; if(c>maxim) maxim=c, maxi=k; if(c<minim) minim=c, mini=k; y/=10; } if(mini>maxi) tip1++,tipb=1; else tipb=2; if(tipa==tipb) n--; //cout<<"!"<<n<<" "<<tip1<<" "<<tipb<<endl; a=b,tipa=tipb; } if(tipb==tipul) n--; // cout<<"*"<<n<<" "<<tip1<<" "<<tipb<<" "<<tipul<<endl; if(T==1) out<<tip1; else out<<n; return 0; } 4.2 Palindrom - OJI 2016 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 De exemplu numerele 500, 1411, ca un palindrom, mai puµin o pereche în care cifrele difer . 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 % x). De exemplu palindromul asociat al lui 5442 este 5445, palindromul strict mai mare decât x (p 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 din ³ir C 1, va conµine un singur num r natural reprezentând num rul de numere palindrom CAPITOLUL 4. C C a dac a dac 55 OJI 2016 2, va conµine num rul de numere din ³ir care sunt aproape palindrom 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 a 1 & n & 10000 & numerele din ³ir & 2000000000 a Pentru rezolvarea corect cerinµe se acord 20 de puncte, pentru rezolvarea corect 30 de puncte, iar pentru rezolvarea corect a celei de a treia a primei cerinµe se acord a celei de a doua cerinµe se acord 50 de puncte. Exemple palindrom.in palindrom.out 1 5 7 1221 500 53635 505 7 4004 1410 Explicaµie: Cele 5 numere palindrom sunt 1221, 53635, 505, 7 ³i 4004 (C ind 1, se rezolv doar prima cerinµ ). 2 3 4 5442 2445 545 39995 Explicaµie: Cele 3 numere aproape palindrom sunt 5442, 2445 ³i 39995 (C ind 2, se rezolv doar a doua cerinµ ). 3 7 1441 2552 1331 515 1221 53635 22 4114 1441 33 11 6 1411 2444 1221 505 1220 53625 14 4014 1410 22 Explicaµie: Palindromul asociat lui 6 este 7, al lui 1411 este 1441, al lui 2444 este 2552 etc. (C ind 3, se rezolv doar a treia cerinµ ). Timp maxim de executare/test: 0.5 secunde Memorie: total 32MB Dimensiune maxim a sursei: 15 KB 4.2.1 Indicaµii de rezolvare Problema Palindrom - (autor Cristian Francu) Cerinta 1 Punctul 1 al problemei este relativ banal, cerand sa spunem cate numere palindrom e intr-un sir de numere. Cu toate acestea trebuie avut grija deoarece algoritmul stan calculeaza rasturnatul numarului, care poate sa depaseasca valoarea maxima a unui i de circa doua miliarde (de exemplu numarul 1234554327). Pentru a nu depasi intregul proceda in mai multe moduri: 1. Putem sa extragem cifrele din capetele opuse ale numarului, spre a le compara, i le eliminam. Pentru aceasta vom calcula p10, puterea maxima a lui 10 care este mai 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 c algoritmul clasic, adaugand cifrele de la coada lui x la coada lui y, cu diferenta ne vom opri atunci cand x<=y. CAPITOLUL 4. 56 OJI 2016 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 i si apoi extragem pe rand cifre din coada ambelor numere calculand cate perechi dife avem. Daca numarul de perechi diferite este 0, numarul este palindrom, iar daca est atunci numarul este aproape palindrom. Avem aceeasi problema insa, ca si la punctul anume pe anumite numere vom depasi intregul. Pentru a nu depasi putem iar aplica me descrise la punctul 1. Cerinta 3 Punctul 3 al problemei se reduce la a calcula pentru un numar x cel mai mic palindr strict mai mare ca x. Putem rezolva direct, incrementand x si testand daca este pal avand grija la depasire. Aceasta metoda este destul de lenta si va depasi timpul la 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 c Pentru aceasta calculam y, simetrizarea lui x, ca fiind copierea primei jumatati in de-a doua, rasturnata. De exemplu pentru 123456 vom calcula 123321, iar pentru 4066 vom calcula 4066604. Daca palindromul calculat, y, este mai mare sau egal cu x, atu 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. Dac simetrizam z vom obtine raspunsul. 4.2.2 *Rezolvare detaliat 4.2.3 Cod surs Listing 4.2.1: palindrom_Marius.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <fstream> #include <cstring> using namespace std; char s[12]; int t, n, i, j, k, t1, t2, nr; int main () { ifstream fin("palindrom.in"); ofstream fout("palindrom.out"); fin>>t>>n; for (i=1;i<=n;i++) { fin>>s; int nr = 0; for (j=0, k=strlen(s)-1; j<k; j++, k--) { if (s[j] != s[k]) nr++; } if (nr == 0) t1++; if (nr == 1) t2++; if (t == 3) { int number = 0; int noua = 1; for (j=0;s[j]!=0;j++) { if (s[j] != ’9’) { noua = 0; } number = number*10 + s[j] - ’0’; CAPITOLUL 4. 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 OJI 2016 } if (noua) { fout<<1; for (j=0;s[j+1]!=0;j++) fout<<0; fout<<"1 "; continue; } if (strlen(s) % 2 == 0) { int left = 0; for (j=0;j<strlen(s)/2;j++) left = left * 10 + s[j] - ’0’; int auxleft = left; int rez = left; while (left != 0) { rez = rez * 10 + left % 10; left /= 10; } if (rez > number) { fout<<rez<<" "; continue; } else { left = auxleft + 1; rez = left; while (left != 0) { rez = rez * 10 + left % 10; left /= 10; } fout<<rez<<" "; continue; } } else { int left = 0; for (j=0;j<=strlen(s)/2;j++) left = left * 10 + s[j] - ’0’; int auxleft = left; int rez = left; left /= 10; while (left != 0) { rez = rez * 10 + left % 10; left /= 10; } if (rez > number) { fout<<rez<<" "; continue; } else { left = auxleft + 1; rez = left; left /= 10; while (left != 0) { rez = rez * 10 + left % 10; left /= 10; } fout<<rez<<" "; continue; } } } } if (t == 1) fout<<t1<<"\n"; if (t == 2) fout<<t2<<"\n"; 57 CAPITOLUL 4. 112 113 58 OJI 2016 return 0; } Listing 4.2.2: palindrom_Sanda.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 #include <iostream> #include <fstream> using namespace std; ifstream in("palindrom.in"); ofstream out("palindrom.out"); int main() { int c,n,i,j,k,d=1, nrap=0,nrpal=0; long long x,y,z=0,a,b; in>>c; in>>n; for(i=1;i<=n;i++) { in>>x; y=x; z=k=0; while(y) { z=z*10+y%10; k++; y/=10; } if(c==1) { if(x==z) nrpal++; } else if(c==2) { a=x,b=z,d=0; while(a && d<=2){ if(a%10!=b%10) d++; a/=10,b/=10; } if(d==2) nrap++; } else { int m=1,prim,ultim; for(j=1;j<=k/2;j++) m*=10; y=x/m*m+z%m; if(y<=x) { if(k%2==0) a=b=(x/m+1); else a=b=(x/m+1)/10; z=0; while(b) { z=z*10+b%10; b=b/10; } y=(x/m+1)*m+z; } out<<y<<’ ’; } } if(c==1) out<<nrpal; else if(c==2) out<<nrap; return 0; CAPITOLUL 4. 71 } OJI 2016 59 Capitolul 5 OJI 2015 5.1 Cuart - OJI 2015 Problema 1 - Cuart Gina ³i Mihai joac 100 de puncte împreun jocul Cuart. Ei au la dispoziµie un ³ir de 2 N cartona³e ce conµin numere naturale. Primele N cartona³e, de la stânga la dreapta, sunt ale Ginei, iar urm toarele N ale lui Mihai. Gina travereseaz ³irul, de la stânga la dreapta ³i scrie pe o foaie de hârtie, pe primul rând, un ³ir de numere obµinut din numerele de pe cartona³ele sale, din care a ³ters toate cifrele pare. La fel procedeaz Mihai care scrie pe foaia sa de hârtie, pe primul rând, ³irul de numere obµinut din numerele de pe cartona³ele sale, din care a ³ters toate cifrele impare. Dac dintr-un num r s-au ³ters toate cifrele, sau au r mas doar cifre egale cu 0, atunci num rul este ignorat, deci pe hârtie nu se scrie nimic. Fiecare copil, noteaz pe hârtia sa, pe al doilea rând, un alt ³ir de numere obµinut astfel: pentru ecare num r X scris pe primul rând, copilul va scrie cel mai mare num r natural K cu 1 5 9 13 ... K & X . În jocul copiilor, num rul X se nume³te cuarµ dac 1 5 9 13 ... K X . proprietatea c Figura 5.1: Cuart În exemplul de mai sus, Gina nu a scris niciun num r cuarµ pe primul rând, iar Mihai a scris unul singur (6=1+5). Regulile de câ³tig ale jocului sunt urm toarele: a Câ³tig acel copil care are scrise pe primul rând cele mai multe numere cuarµ. În acest caz, valoarea de câ³tig a jocului este egal a Dac cu num rul de numere cuarµ scrise de copilul câ³tig tor. 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 câ³tig nici Gina ³i nici Mihai nu au scris niciun num r pe hârtie, se consider egalitate ³i nu niciunul. Cerinµe Scrieµi un program care s citeasc num rul N reprezentând num rul de cartona³e ale unui copil ³i cele 2 N numere de pe cartona³e, în ordine de la stânga la dreapta ³i care s determine: 1) Cel mai mare num r de pe cele 2 N catona³e, pentru care nu s-a scris niciun num r pe primul rând (a fost omis), nici pe hârtia Ginei, nici pe hârtia lui Mihai; dac nu a fost omis niciun num r, se va scrie 0; 2) Câ³tig torul jocului ³i a³eaz num rul 1 dac a câ³tigat Gina, 2 pentru Mihai sau 0 în caz de egalitate. 3) Valoarea de câ³tig a jocului, sau 0, în caz de egalitate. Date de intrare 60 CAPITOLUL 5. 61 OJI 2015 Fi³ierul de intrare cuart.in conµine pe prima linie un num r natural P . Pentru toate testele de intrare, num rul P poate avea doar valoarea 1, valoarea 2 sau valoarea 3. Pe a doua linie a ³ierului de intrare cuart.in se g se³te num rul natural N reprezentând num rul de cartona³e ale ec rui copil ³i pe a treia linie, în ordine de la stânga la dreapta, numerele de pe cele 2 N cartona³e, separate prin câte un spaµiu. Date de ie³ire Dac ie³ire Dac ie³ire valoarea lui P este 2, se va rezolva numai punctul 2) din cerinµe. În acest caz, ³ierul de cuart.out va conµine pe prima linie un num r natural reprezentând r spunsul la cerinµa 2). Dac ie³ire valoarea lui P este 1, se va rezolva numai punctul 1) din cerinµe. În acest caz, ³ierul de cuart.out va conµine pe prima linie un num r natural reprezentând r spunsul la cerinµa 1). valoarea lui P este 3, se va rezolva numai punctul 3) din cerinµe. În acest caz, ³ierul de 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 a 1 & N & 1000 & numerele de pe cartona³e $ 100000000 a Pentru rezolvarea corect se acord 20 de puncte, pentru rezolvarea corect 30 de puncte, pentru rezolvarea corect a celei de a treia cerinµe a primei cerinµe se acord a celei de a doua cerinµe se acord 50 de puncte. Exemple cuart.in 1 cuart.out Explicaµii 284260 P = 1, pentru acest test, se rezolv 4 Gina a scris pe hârtia sa, pe dou 1234 48 284260 75 756 1232515 153 98 rele: cerinµa 1). rânduri nume- 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 4 P = 2, pentru acest test, se rezolv cerinµa 2). A câ³tigat Mihai deoarece are un num r cuarµ, iar 1234 48 284260 75 756 1232515 153 98 3 Gina niciunul. 28 P = 3, pentru acest test, se rezolv 1 Gina a scris pe hârtia sa, pe dou 154 2181 rele: cerinµa 3). rânduri nume- 15 9 Mihai a scris pe hârtie numerele: 28 13 Ambii copii au scris câte un num r cuarµ, îns a câ³tigat Mihai care are primul num r scris pe primul rând mai mare decât al Ginei. Valoarea de câ³tig a jocului este 28. Timp maxim de executare/test: 1.0 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 5 KB 5.1.1 Indicaµii de rezolvare Cuart-descriere Pentru primele N cartonase: * se citeste, pe rand, cate un numar (cartonas) si se sterg cifrele sale pare. Daca CAPITOLUL 5. 62 OJI 2015 ramas X este diferit de 0, atunci: o daca este primul, il salvez intr-o variabila o caut kmax cu proprietatea ca 1+5+9+...+k <= X. Cautarea lui k 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 o daca obtinem egalitate in relatia anterioara, atunci marim numarul de numere cuar ale Ginei cu 1 Pentru urmatoarele N cartonase se repeta pasii anteriori cu modificarea aferenta. 5.1.2 *Rezolvare detaliat 5.1.3 Cod surs Listing 5.1.1: cuart_dl.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <cstdio> #include <algorithm> #include <cassert> #define MRD 99999999 using namespace std; int K, N, A, B, N1, N2, Nr, P, first1, first2, cuart1, cuart2, Max, i, Sum, t, p, x,X, cx, d, u, nr; bool ok; int main() { freopen("cuart.in", "r",stdin); freopen("cuart.out","w",stdout); scanf("%d\n%d",&P, &N); assert(N<=1000 && N>=1 && P>0 && P<4); first1=cuart1=0; for(int i=1; i<=N; i++) { scanf("%d",&X); assert(X<100000000 && X>0); p=1; x=0; cx=X; while(cx) { if(cx%2) {x=x + cx%10 *p; p*=10;} cx/=10; } if(x) { if(!first1) first1=x; Sum=0; t=1; while (Sum + t <= x) { Sum+=t; t+=4; } if(Sum==x) cuart1++; } else Max=max(X, Max); } CAPITOLUL 5. 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 63 OJI 2015 first2=cuart2=0; for(int i=1; i<=N; i++) { scanf("%d",&X); assert(X<100000000 && X>0); p=1; x=0; cx=X; while(cx) { if(cx%2==0) {x=x + cx%10 *p; p*=10;} cx/=10; } if(x) { if(!first2) first2=x; Sum=0; t=1; while (Sum + t <= x) { Sum+=t; t+=4; } if(Sum==x) cuart2++; } else Max=max(X, Max); } if(P==1) printf("%d\n", Max); else { if(cuart1>cuart2) { if (P==2) printf("1\n"); else printf("%d\n",cuart1); } else if(cuart1<cuart2) { if (P==2) printf("2\n"); else printf("%d\n", cuart2); } else if(first1==0 && first2 ==0) { if (P==2) printf("0\n"); else printf("%d\n", 0); } else if (first1>first2) { if (P==2) printf("1\n"); else printf("%d\n",first1); } else { if (P==2) printf("2\n"); else printf("%d\n",first2); } } return 0; } Listing 5.1.2: cuart_dt.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <fstream> #include<math.h> using namespace std; ifstream f("cuart.in"); ofstream g("cuart.out"); int n,x; int main() { int i,max1=0,p=1,nr=0,y,q1=0,q2=0,k,s, prim1=0, prim2=0,max2=0,nr1=0,nr2=0,P; CAPITOLUL 5. 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 OJI 2015 f>>P>>n; for(i=1; i<=n; i++) { f>>x; y=x; while(x!=0) { if(x%10%2) { nr=nr+x%10*p; p=p*10; } x=x/10; } if(nr==0&&max1<y) max1=y; if(nr) { nr1++; if(prim1==0) prim1=nr; k=1; s=0; while (s<nr) { s=s+k; k=k+4; } if(s==nr) q1++; } nr=0; p=1; } for(i=1; i<=n; i++) { f>>x; y=x; while(x!=0) { if(x%10%2==0) { nr=nr+x%10*p; p=p*10; } x=x/10; } if(nr==0&&max2<y) max2=y; if(nr) { nr2++; if(prim2==0) prim2=nr; k=1; s=0; while (s<nr) { s=s+k; k=k+4; } if(s==nr) q2++; } nr=0; p=1; } if(P==1) if(max1>max2) g<<max1<<’\n’; else g<<max2<<’\n’; else { if(nr1==0&&nr2==0) g<<0<<’\n’; else { if(q1>q2) if(P==2) g<<1<<’\n’; else g<<q1<<’\n’; if(q1<q2) if(P==2) g<<2<<’\n’; else g<<q2<<’\n’; if(q1==q2) { 64 CAPITOLUL 5. 92 93 94 95 96 97 98 99 100 101 65 OJI 2015 if(prim1>prim2) if(P==2) g<<1<<’\n’; else g<<prim1<<’\n’; else if(P==2) g<<2<<’\n’; else g<<prim2<<’\n’; } } } f.close(); g.close(); return 0; } Listing 5.1.3: cuart_la.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #include<fstream> using namespace std; int main() { int pp,n,nr1=0,nr2=0,p1=0,p2=0,max1=0, nrcuart1=0,nrcuart2=0,c,y,x,p,i,k,s; ifstream f("cuart.in"); ofstream g("cuart.out"); f>>pp>>n; for (i=1; i<=n; i++) { f>>c; x=c; p=1; y=0; while (x) { if (x%2==1) { y=y+x%10*p; p=p*10; } x=x/10; } if (y!=0) { nr1++; if (nr1==1) p1=y; s=1; k=5; while (s+k<=y) { s=s+k; k=k+4; } if (s==y) nrcuart1++; } else if (c>max1) max1=c; } for (i=1; i<=n; i++) { f>>c; x=c; p=1; y=0; while (x) { if (x%2==0) { y=y+x%10*p; p=p*10; } x=x/10; } CAPITOLUL 5. 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 66 OJI 2015 if (y!=0) { nr2++; if (nr2==1) p2=y; s=1; k=5; while (s+k<=y) { s=s+k; k=k+4; } if (s==y) nrcuart2++; } else if (c>max1) max1=c; } if (pp==1) g<<max1<<’\n’; else if (pp==2) { if (nrcuart1>nrcuart2) g<<"1\n"; else if (nrcuart2>nrcuart1) g<<"2\n"; else { if (p1>p2) g<<"1\n"; else if(p2>p1) g<<"2\n"; else g<<"0\n"; } } else { if (nrcuart1>nrcuart2) g<<nrcuart1; else if (nrcuart2>nrcuart1) g<<nrcuart2; else { if (p1>p2) g<<p1<<"\n"; else if (p2>p1) g<<p2<<"\n"; else g<<"0\n"; } } return 0; } Listing 5.1.4: cuartAI.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <fstream> #include <math.h> using namespace std; ifstream f("cuart.in"); ofstream g("cuart.out"); int N,P,B,C,m1,m2,maxo,K,M,q1,q2, primul1,primul2,k,i,x,p,q,nr1,nr2; int main() { //citire-prelucrare CAPITOLUL 5. 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 67 OJI 2015 f>>P>>N; //Gina for(i=1;i<=N;i++) { f>>K;x=K;p=1;q=0; while(x>0) { if(x%2==1){q+=p*(x%10);p*=10;} x/=10; } if(q==0){if(K>maxo)maxo=K;} else { nr1++; if(primul1==0)primul1=q; //1+5+9+...+(4M+1)=(M+1)(2M+1) //k=M*4+1; M=0; while(2*M*M+3*M+1<q) M++; if(q==(M+1)*(2*M+1)) q1++; } } //Mihai for(i=1;i<=N;i++) { f>>K;x=K;p=1;q=0; while(x>0) { if(x%2==0){q+=p*(x%10);p*=10;}x/=10; } if(q==0){if(K>maxo)maxo=K;} else { nr2++; if(primul2==0)primul2=q; //k=M*4+1; M=0; while(2*M*M+3*M+1<q )M++; if(q==(M+1)*(2*M+1))q2++; } } //afisare a) if(P==1)g<<maxo<<’\n’; //afisare b) si c) if(q1<q2) B=2,C=q2; else if(q1>q2) B=1,C=q1; else if(primul1>primul2) B=1,C=primul1; else if(primul1<primul2) B=2,C=primul2; else B=C=0; if(P==2)g<<B<<’\n’; if(P==3)g<<C<<’\n’; f.close(); g.close(); return 0; } Listing 5.1.5: cuartAI_ecuatie.cpp CAPITOLUL 5. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 OJI 2015 #include <fstream> #include <math.h> using namespace std; ifstream f("cuart.in"); ofstream g("cuart.out"); int P,N,m1,m2,maxo,A,B,C,M,q1,q2, primul1,primul2,k,i,x,q,p,nr1,nr2; int main() { //citire-prelucrare f>>P>>N; //Gina for(i=1;i<=N;i++) { f>>A;x=A;p=1;q=0; while(x>0) { if(x%2==1) { q+=p*(x%10); p*=10; } x/=10; } if(q==0) { if(A>maxo) maxo=A; } else { nr1++; if(primul1==0)primul1=q; //1+5+9+...+(4M+1)=(M+1)(2M+1) M=(-3+sqrt(1+8*q))/4; //k=M*4+1; if(q==(M+1)*(2*M+1))q1++; } } //Mihai for(i=1;i<=N;i++) { f>>A; x=A; p=1; q=0; while(x>0) { if(x%2==0) { q+=p*(x%10); p*=10; } x/=10; } if(q==0){if(A>maxo)maxo=A;} else { nr2++; if(primul2==0)primul2=q; M=(-3+sqrt(1+8*q))/4; //k=M*4+1; if(q==(M+1)*(2*M+1))q2++; } } //afisare a) if(P==1)g<<maxo<<’\n’; //afisare b) si c) if(q1<q2) B=2,C=q2; 68 CAPITOLUL 5. 76 77 78 79 80 81 82 83 84 85 86 87 69 OJI 2015 else if(q1>q2) B=1,C=q1; else if(primul1>primul2)B=1,C=primul1; else if(primul1<primul2)B=2,C=primul2; else B=C=0; if(P==2)g<<B<<’\n’; if(P==3)g<<C<<’\n’; f.close(); g.close(); return 0; } 5.2 speciale - OJI 2015 Problema 2 - speciale Maria a aat c 100 de puncte numerele naturale care încep cu cifra 1 ³i au toate cifrele ordonate strict cresc tor ³i consecutive sau încep cu cifra consecutive se numesc numere 9 ³i au toate cifrele ordonate strict descresc tor ³i speciale. Interesat s descopere leg tura dintre numerele speciale cu acela³i num r de cifre, a observat c poate construi tabelul al turat. Figura 5.2: speciale Cerinµe Scrieµi un program care citind patru numere naturale K , N , A ³i B determin : special situat în tabel pe linia K ; 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 }. 1) cel mai mare num r 2) num rul 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 ie³ire valoarea lui P este 1, se va rezolva numai punctul 1) din cerinµe. În acest caz, ³ierul de 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 de ie³ire valoarea lui P este 2, se va rezolva numai punctul 2) din cerinµe. În acest caz, ³ierul 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 Dac ie³ire un astfel de num r nu se poate obµine; valoarea lui P este 3, se va rezolva numai punctul 3) din cerinµe. În acest caz, ³ierul de 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 CAPITOLUL 5. 70 OJI 2015 &K&9 & N & 999999999 a 1 & A & B & 999999999 a 1 a 1 a Pentru rezolvarea corect 20 de puncte, pentru rezolvarea corect 40 de puncte, pentru rezolvarea corect a celei de a treia cerinµe a primei cerinµe se acord a celei de a doua cerinµe se acord 40 de puncte. se acord Exemple speciale.in speciale.out Explicaµii 13 125345 320 888888 987 P = 1, pentru acest test, se rezolva cerinµa 1). Numerele speciale de pe linia a treia a tabelului sunt 123 ³i 987, cel mai mare ind 987. 23 125345 320 888888 12345 P = 2, pentru acest test, se rezolva cerinµa 2). tergând cifra 5 aat pe poziµia a treia în 125345 se obµine num rul special 12345. 33 125345 320 888888 6 P = 3, pentru acest test, se rezolva cerinµa 3). Sunt 6 numere speciale în mulµimea {320, 321,..., 888888} ³i anume 987, 1234, 9876, 12345, 98765, 123456. Timp maxim de executare/test: 0.5 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 5 KB 5.2.1 Indicaµii de rezolvare Problema - speciale Cerinta 1 Se formeaza numarul special care incepe cu cifra 9 si contine k cifre cu ajutorul u structuri repetitive. Cerinta 2 O solutie posibila: numaram cifrele numarului N (nr); construim numarul special cu numar de cifre egal cu nr-1; comparam cifrele numarului N cu cifrele numarului spec construit (cifra cu cifra de la dreapta la stanga); daca toate sunt egale (pe aceea pozitie) si numai una difera, atunci afisam numarul special construit, altfel afisam valoarea 0. Cerinta 3 O solutie posibila: Calculam cate cifre are numÄČrul A. Construim numerele speciale sa contina tot atatea cifre cate contine numarul A. Comparam valoarea numerelor spe 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. 5.2.2 *Rezolvare detaliat 5.2.3 Cod surs Listing 5.2.1: speciale_dc.cpp 1 2 3 4 #include <fstream> using namespace std; CAPITOLUL 5. 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 OJI 2015 ifstream fin("speciale.in"); ofstream fout("speciale.out"); int main() { unsigned P,N,K,A,B,x,special,i,p,NN,Ncif; x=special=Ncif=0; fin>>P>>K>>N>>A>>B; NN=N; if(P==1) { for(i=9;i>=10-K;i--) fout<<i; fout<<’\n’; return 0; } if(P==2) { ///cerinta 2 while(NN) { NN/=10; special=special*10+Ncif; Ncif++; } if(N%10==Ncif-1||N/10%10==Ncif-1)///verific daca N este de forma 1234... { NN=N;i=Ncif-1;p=1; while(NN) { if(NN%10!=i) { if(N/(p*10)*p+N%p==special) x=special; break; } else {i--;p*=10;NN/=10;} } if(NN==0)x=special; } //verific daca N este de forma 987... if(x==0&&(N%10==11-Ncif||N/10%10==11-Ncif)) { NN=N;i=11-Ncif;p=1; while(NN) { if(NN%10!=i) { if(N/(p*10)*p+N%p==special*8+Ncif-1) x=special*8+Ncif-1; break; } else {i++;p*=10;NN/=10;} } if(NN==0) x=special*8+Ncif-1; } fout<<x<<’\n’; return 0; } if(P==3) { ///cerinta 3 for(x=special=0,i=1;special<=B;i++) { special=special*10+i; if(special>=A&&special<=B) x++; if(special*8+i>=A&&special*8+i<=B) x++; } fout<<x<<’\n’; return 0; } 71 CAPITOLUL 5. 81 82 72 OJI 2015 return 0; } Listing 5.2.2: speciale_n_dt.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 #include <fstream> using namespace std; ifstream f("speciale.in"); ofstream g("speciale.out"); int main() { int k,n,a,b,x=0,i,pr,nr=0,nr1=0,p1,fin_nr,ok=0,nr2,p; f>>p>>k>>n>>a>>b; if(p==1) { x=0; for(i=9;i>9-k;i--) x=i+x*10; g<<x<<’\n’; } //cerinta 2 if(p==2) { pr=n; while(pr) { pr=pr/10; nr++; } nr--; for(i=1;i<=nr;i++) nr1=i+nr1*10; p1=0; pr=n; fin_nr=nr1; while(pr) { if(pr%10==nr1%10) {pr=pr/10;nr1=nr1/10;} else {p1++;pr=pr/10;} } if(p1==1) {g<<fin_nr<<’\n’;ok=1;} else { nr1=0; for(i=9;i>9-nr;i--) nr1=i+nr1*10; p1=0; pr=n; fin_nr=nr1; while(pr) { if(pr%10==nr1%10) {pr=pr/10;nr1=nr1/10;} else {p1++;pr=pr/10;} } if(p1==1) {g<<fin_nr<<’\n’;ok=1;} } if(ok==0) g<<0<<’\n’; } //cerinta 3 if(p==3) { nr=0; pr=a; CAPITOLUL 5. 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 73 OJI 2015 nr1=0; while(pr){pr=pr/10;nr++;} for(i=1;i<=nr;i++) nr1=i+nr1*10; nr2=0; for(i=9;i>9-nr;i--) nr2=i+nr2*10; x=0; if(nr1>=a) x++; if(nr2>=a&&nr2<=b) x++; nr++; pr=nr2%10-1; while(nr2<b && nr1<b) { nr2=nr2*10+pr; nr1=nr1*10+nr; nr++;pr--; if(nr1<=b) x++; if(nr2<=b) x++; } g<<x<<’\n’; } f.close(); g.close(); return 0; } Listing 5.2.3: speciale_SJ.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <iostream> #include <fstream> using namespace std; ifstream in("speciale.in"); ofstream out("speciale.out"); int main() { int P,k,n,A,B,m,nr=0,nrm=0,mr=0,i,l,sw1,sw2; in>>P; in>>k>>n>>A>>B; if(P==1) { //a for(i=1;i<=k;i++) nrm=nrm*10+10-i; out<<nrm<<’\n’; } else if(P==2) { //b nr=0; m=n,l=0; while(m) l++,m/=10; for(i=1;i<l;i++) nr=nr*10+i; mr=nr,sw1=0,m=n; while(n) { if(n%10!=nr%10) n/=10, sw1++; else n/=10,nr/=10; CAPITOLUL 5. 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 74 OJI 2015 } n=m; if(sw1==1&&nr==0) out<<mr<<’\n’; else if(sw1==0 && n/10==0) out<<mr<<’\n’; else { nr=0; for(i=9;i>10-l;i--) nr=nr*10+i; mr=nr,sw2=0,m=n; while(n) { if(n%10!=nr%10) n/=10, sw2++; else n/=10,nr/=10; } if(sw2==1&&n==0) out<<mr<<’\n’; else if(sw2==0 && n/10==0) out<<mr<<’\n’; if(sw1!=1 && sw2!=1) out<<0<<’\n’; } } else { //c m=A,l=0,nr=0,k=0; while(m) l++,m/=10; for(i=1;i<=l;i++) nr=nr*10+i; if(nr<A) { m=nr*8+l; if(m>=A && m<=B) k++; l++, nr=nr*10+l; } i=l; while(nr>=A && nr<=B) { k++; if(nr*8+i>=A && nr*8+i<=B) k++; i++; nr=nr*10+i; } out<<k; } return 0; } Listing 5.2.4: specialedl.cpp 1 2 3 4 5 6 #include <cstdio> #include <cctype> #include <algorithm> #include <cassert> #define MRD 999999999 CAPITOLUL 5. 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 OJI 2015 using namespace std; int K, N, A, P, B, N1, N2, Nr, Na1, Na2, Special, i, p, x, d, u, nr; bool ok; int main() { freopen("speciale.in", "r",stdin); freopen("speciale.out","w",stdout); scanf("%d\n",&P); scanf("%d%d%d%d",&K, &N, &A, &B); assert(P>0 && P<=3 && K<10 && K>0 && N<=MRD && A<=MRD && B<=MRD && N>0 && A>0 && B>0 && A<=B); if(P==1) { for(int i=1; i<=K; i++) N2=N2*10 + 10 - i; printf("%d\n", N2); } else if(P==2) { p = 1; Special=0; while(N/p>0 && !Special) { Nr=N/(p*10)*p + N%p; int cn=Nr; while(cn>9) cn/=10; if(Nr==1 ||Nr == 9) Special = Nr; else { d=(cn==9? 1: -1); u=Nr%10; ok=true; while (Nr>0) { if ( u != Nr % 10 ) ok=false; Nr/=10; u += d; } if (ok && (d==1 && u==10 || d==-1 && u==0)) Special=N/(p*10)*p + N%p; } p*=10; } printf("%d\n", Special); } else { Na1=Na2=nr=0; for(int i=1; i<=9 ; i++ ) { Na1=Na1*10 + i; if(Na1>=A&&Na1<=B ) nr++; Na2=Na2*10 + 10 - i; if(Na2>=A&&Na2<=B) nr++; } printf("%d\n", nr); } return 0; } 75 Capitolul 6 OJI 2014 6.1 martisoare - OJI 2014 Problema 1 - martisoare Gic ³i Lic lucreaz bricii a hot rât s 100 de puncte la o fabric de juc rii, în schimburi diferite. Anul acesta patronul fa- 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 Gic apoi s trebuie s le pun ia, în ordine, ecare cutie, s a numerelor de pe acestea. lege la ecare m rµi³or câte un ³nur alb-ro³u ³i 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 cutiile cu numerele de pe tabl când, dou cifre de pe tabl în schimbul urm tor, vine ³i ambaleaz ³i le trimite la magazine. Totul merge ca pe roate, pân se demagnetizeaz ³i cad, r mânând dou acest lucru, le ia de jos ³i le pune la întâmplare pe tabl , în cele dou de care µine cont este acela c cifra 0 nu poate prima cifr locuri goale. Lic într-o zi, observ locuri goale. Singurul lucru a unui num r. Figura 6.1: marti³oare Cerinµe Scrieµi un program care s citeasc numerele naturale N (reprezentând num rul de numere scrise pe tabl ) ³i c1 , c2 , ..., cN (reprezentând numerele scrise, în ordine, pe tabl , dup completat cele dou a) cele dou locuri goale cu cifrele c zute) ³i care s ce Lic a determine: 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 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 , num rul de numere de 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 în cazul în care cele dou cifre care au fost schimbate între ele sau 0 0 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 76 de Gic pe tabl . CAPITOLUL 6. 77 OJI 2014 Restricµii ³i preciz ri a 4 a 1 & N & 100000 & 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 5 martisoare.out Explicaµii 2 629 Gic 65 22 27 28 29 a scris pe tabl , în ordine, numerele: 25 26 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 4 8 998 95 96 97 89 este 29. . Gic a scris pe tabl , în ordine, numerele: 95 96 97 98 Au fost schimbate între ele cifrele ultimului num r. Cel mai mare num r scris de Gic 5 0 039 Gic 35 36 37 38 39 pe tabl este 98. a scris pe tabl , în ordine, numerele: 35 36 37 38 39 ³irul numerelor nu a fost schimbat, cel mai mare num r ind 39. Timp maxim de executare/test: 0.5 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 5 KB 6.1.1 Indicaµii de rezolvare P1- martisoare Solutie - complexitate O(N) - prof. Ana Intuneric Solutia se bazeaza pe observatia ca este suficient sa determinam primul numar modificat. Sunt doua cazuri clare a) primele doua numere sunt nemodificate, caz in care se calculeaza imediat numarul maxim si se cauta primul numar modificat comparand cifrele sale cu cifrele numarului care trebuia sa fie pe respectiva pozitie in fisier b) unul dintre primele doua numere sau amandoua sunt modificate. In acest caz se citesc doar primele 4 numere si se trateaza combinatiile posibile de numere modificate 6.1.2 *Rezolvare detaliat 6.1.3 Cod surs Listing 6.1.1: mAna.cpp 1 2 3 4 5 // sursa oficiala - prof.Ana Intuneric #include <fstream> using namespace std; pe tabl CAPITOLUL 6. 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 OJI 2014 ifstream f("martisoare.in"); ofstream g("martisoare.out"); int N,i,c1,c2,c3,c4,x,y,maxi,gasit; int main() { f>>N; f>>c1>>c2; //caut primul numar modificat if(c2-c1==1) { maxi=c1+N-1; for(i=3;i<=N && !gasit;i++) { f>>c3; if(c3-c2!=1) { x=c2+1;y=c3;gasit=1; while(x!=0 && y!=0) { if(x%10!=y%10) { if(x%10<y%10) g<<x%10<<’ ’<<y%10<<endl; else g<<y%10<<’ ’<<x%10<<endl; break; } else x/=10,y/=10; } } else c2=c3; } } else { f>>c3>>c4; //c1 modificat if(c3-c2==1) { x=c2-1; y=c1; gasit=1; maxi=c2+N-2; } else if(c4-c2==2) { x=c2-1; y=c1; gasit=1; maxi=c4+N-4; } //c2 este modificat else if(c4-c3==1) { x=c2; y=c3-1; gasit=1; maxi=c3+N-3; } else if(c3-c1==2) { x=c2; y=c3-1; gasit=1; maxi=c3+N-3; }//c2 modificat si c3 este bun else 78 CAPITOLUL 6. 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 79 OJI 2014 { x=c2; y=c4-2; gasit=1; maxi=c4+N-4; }//c2 modificat si c4 este bun while(x!=0 && y!=0) { if(x%10!=y%10) { if(x%10<y%10) g<<x%10<<’ ’<<y%10<<endl; else g<<y%10<<’ ’<<x%10<<endl;break; } else x/=10,y/=10; } } if(!gasit) g<<"0 0\n"; g<<maxi<<endl; f.close(); g.close(); return 0; } Listing 6.1.2: mCarmen.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <iostream> #include <fstream> using namespace std; ifstream f("martisoare.in"); ofstream g("martisoare.out"); int v[100001]; int main() { int i,x,k=1,y,n, a=0,b=0; f>>n>>x; v[1]=x; y=x; for(i=2;i<=n;i++) { f>>v[i]; x=max(x,v[i]); y=min(y,v[i]); } if(y+n-1==x) { for(i=1; i<=n;i++,y++) if(v[i]!=y) { a=v[i]; b=y; break; } } else { int i=1; if(v[1]!=y && v[2]==y) { if(v[3]==y+1) { a=v[1]; b=y-1; x=b+n-1; CAPITOLUL 6. 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 80 OJI 2014 } else { x=v[3]+n-3; a=v[3]-1; b=y; } } else { i=2; while(y+1==v[i] && i<=n) { i++; y++; } a=v[i]; b=y+1; x=y+(n-i+1); } } if(a*b) { while(a%10==b%10) { a=a/10; b=b/10; } a=a%10; b=b%10; if(a>b) swap(a,b); } g<<a<<" "<<b<<endl<<x<<endl; return 0; } Listing 6.1.3: mCristina.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 //martisoare - Cristina Sichim #include <fstream> using namespace std; ifstream f("martisoare.in"); ofstream g("martisoare.out"); int n,a,b,c,d,u; void cifre(int b, int c) { while(b%10==c%10) b/=10,c/=10; (b%10 < c%10) ? g<<b%10<<’ ’<<c%10<<’\n’ : g<< c%10<<’ ’<<b%10<<’\n’; } int main() { f>>n>>a>>b>>c; if(a+1==b && b+1==c) { u=a+n-1; n-=3; while(n && b+1==c) f>>c,++b,--n; if(b+1!=c) cifre(b+1,c), g<<u<<’\n’; else g<<"0 0\n"<<u<<’\n’; } else // cifre schimbate in primele 3 numere if(a+1==b) cifre(b+1,c), g<<a+n-1<<’\n’; CAPITOLUL 6. 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 81 OJI 2014 else if(b+1==c) cifre(a,b-1), g<<b+n-2<<’\n’; else if(a+2==c) cifre(a+1,b), g<<a+n-1<<’\n’; else { f>>d; if(a+3==d) cifre(a+1,b), g<<a+n-1<<’\n’; else if(b+2==d) cifre(a,b-1), g<<b+n-2<<’\n’; else cifre(b,c-1), g<<c+n-3<<’\n’; } f.close(); g.close(); return 0; } Listing 6.1.4: mMarilena.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <fstream> using namespace std; ifstream f("martisoare.in"); ifstream g("martisoare.in"); ofstream h("martisoare.out"); int n,vmin,vmax,t,x,x1,y,y1,a,b,c,d,i,poz; int main() { f>>n>>a>>b>>c>>d; // gasesc primul numar corect din sir si // calculez extremitatile sirului [vmin, vmax] if(b-a==1){vmin=a; vmax=a+n-1;} else if(c-b==1){vmin=b-1; vmax=b+n-2;} else if(d-c==1){vmin=c-2; vmax=c+n-3;} else if(c-a==2){vmin=a; vmax=a+n-1;} else if(d-b==2){vmin=b-1; vmax=b+n-2;} else if(d-a==3){vmin=a; vmax=a+n-1;} f.close(); // caut cele 2 numere gresite g>>n; x=x1=vmin; t=0; for(i=1;i<=n;i++) { x=x1; g>>y; if(x!=y) { while(x!=0 && y!=0) //caut cifrele incurcate { if (x%10!=y%10) { t++; if(t==1) a=x%10; else b=x%10; } CAPITOLUL 6. 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 82 OJI 2014 x=x/10;y=y/10; } } if (t==2) i=n; x1++; } if(t==0) h<<0<<’ ’<<0<<endl<<vmax; else { if(a>b){t=a ;a=b; b=t;} h<<a<<’ ’<<b<<endl<<vmax; } g.close(); h.close(); return 0; } Listing 6.1.5: mRaluca.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #include <fstream> using namespace std; ifstream f("martisoare.in"); ofstream g("martisoare.out"); int main() { int v[4], n, i, max=0, r, c, x, j, nr1=0, p1, nr2=0, p2, nr, c1=0, c2=0, cc; f>>n; for(i=0;i<4;i++) f>>v[i]; for(i=0; i<3; i++) { x=v[i]-i;c=1; for(j=i+1;j<4; j++) if(v[j]-j==x)c++; if(c>max) max=c, r=x; } for(i=0;i<4;i++) if(v[i]-i!=r) if(nr1==0) nr1=v[i], p1=i; else if(nr2==0) nr2=v[i],p2=i; for(i=4;i<n and nr2==0; i++) { f>>nr; if(nr-i!=r) if(nr1==0) nr1=nr, p1=i; else if(nr2==0) nr2=nr,p2=i; } if(nr1) { x=r+p1; while(nr1) { c=nr1%10; cc=x%10; if(c!=cc) if(c<cc) c1=c, c2=cc; else c1=cc, c2=c; nr1/=10; x/=10; CAPITOLUL 6. 52 53 54 55 56 57 58 59 60 61 83 OJI 2014 } } g<<c1<<’ ’<<c2<<’\n’<<r+n-1<<’\n’; f.close(); g.close(); return 0; } 6.2 piramide - OJI 2014 Problema 2 - piramide 100 de puncte Fascinat de Egiptul Antic, Rare³ vrea s construiasc cât mai multe piramide din cartona³e p tratice identice. El are la dispoziµie N cartona³e numerotate de la 1 la N , albe sau gri, a³ezate în ordinea strict cresc toare a numerelor. a Prima piramid o va construi folosind primele trei cartona³e. Baza piramidei va format din cartona³ele 1 ³i 2 a³ezate al turat, peste care va a³eza cartona³ul 3 (vârful piramidei). a A doua piramid va avea baza format din cartona³ele 4, 5 ³i 6 a³ezate al turat, deasu- pra c rora se vor a³eza cartona³ele 7 ³i 8, al turate, peste care se va a³eza cartona³ul 9 (vârful piramidei). a Mai departe, va construi în ordine piramidele complete cu bazele formate din 4 cartona³e (cu numerele de la 10 la 13), respectiv 5 cartona³e (cu numerele de la 20 la 24), 6 cartona³e (cu numerele de la 35 la 40) etc., cât timp va putea construi o piramid complet . De exemplu, dac Rare³ are N 75 cartona³e atunci el va construi piramidele complete 1, 2, 3, 4 ³i 5 din imaginile urm toare. Din cele 75 de cartona³e el va folosi doar primele 55 de cartona³e, deoarece ultimele 20 cartona³e nu sunt suciente pentru a construi piramida 6, cu baza format din 7 cartona³e. Figura 6.2: Piramide Cerinµe Scrieµi un program care s citeasc numerele naturale N (reprezentând num rul de cartona³e), X (reprezentând num rul unui cartona³), K (reprezentând num rul de cartona³e albe), numerele celor K cartona³e albe c1 , c2 , ..., cK ³i care s determine: a) num rul P al piramidei complete ce conµine cartona³ul numerotat cu X ; b) num rul M maxim de piramide complete construite de Rare³; c) num rul C de cartona³e nefolosite; d) num rul A al primei piramide complete care conµine cele mai multe cartona³e albe. Date de intrare Fi³ierul de intrare piramide.in conµine pe prima linie cele trei numere N , X ³i K , separate prin câte un spaµiu, cu semnicaµia din enunµ. A doua linie a ³ierului conµine, în ordine, cele K numere c1 , c2 , ..., cK , separate prin câte un spaµiu, reprezentând numerele celor K cartona³e albe din cele N . Date de ie³ire Fi³ierul de ie³ire dac piramide.out va conµine pe prima linie num rul P sau valoarea 0 (zero) 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 . patra linie va conµine num rul A sau valoarea 0 (zero) dac cel puµin un cartona³ alb. nicio piramid complet Cea de-a nu conµine CAPITOLUL 6. 84 OJI 2014 Restricµii ³i preciz ri a 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 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) se acord 20% din punctaj, pentru cerinµa b) 20% din punctaj, c) 20% din punctaj ³i pentru cerinµa d) 40% din punctaj. a Pentru rezolvarea cerinµei pentru cerinµa 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 construi doar M 5 piramide complete, r mânând nefolosite 20 cartona³e (C 15. Rare³ poate 20) insuciente pentru construirea piramidei 6. Num rul maxim de cartona³e albe dintr-o piramid complet este egal cu 6. Piramidele 4 ³i 5 conµin ecare un num r maxim de cartona³e albe (6), prima dintre acestea ind piramida 4 (A 4). Ultimele 7 cartona³e albe (cu numerele: 60, 65, 68, 69, 70, 71, 72) nu sunt folosite în construirea piramidelor complete. Timp maxim de executare/test: 0.5 secunde Memorie: total 2MB din care pentru stiv 2MB Dimensiune maxim a sursei: 15KB 6.2.1 Indicaµii de rezolvare Descriere soluµie autor prof. Carmen Minc O soluµie posibil se poate obµine f r a datelor din ³ier combinat Se observ c Colegiul Naµional de Informatic Tudor Vianu, Bucure³ti a utiliza tablouri unidimensionale, prin citirea succesiv cu prelucrarea acestora. 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 curent ³i veric m apartenenµa cartona³ului X la piramida 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 numerele 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 cartona³elor albe din piramida curent . Se compar moment. Se actualizeaz acest maxim dac acest num r cu cel maxim obµinut pµn în acest 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 b 1 dac nefolosite, altfel se încheie procesul de construire a piramidei. 6.2.2 *Rezolvare detaliat avem suciente cartona³e CAPITOLUL 6. 6.2.3 85 OJI 2014 Cod surs Listing 6.2.1: p_s_CM.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 //sursa oficiala - prof. Carmen Minca - C.N.I.T.Vianu- Bucuresti #include <fstream> using namespace std; /*a) numarul P al piramidei ce conÈŻine cartonasul numerotat cu X; b) numarul M maxim de piramide construite de Gigel; c) numarul C de cartonaÈŹe nefolosite; d) numarul A al primei piramide care contine cele mai multe cartonaÈŹe albe. */ int n, x, k; ifstream f("piramide.in"); ofstream g("piramide.out"); int main() { int p=0, a=0, m=0, c=0,i,ca,b=1,cfol=0,cp,nra, maxnra=0; f>>n>>x>>k; i=1; f>>ca; do //caut piramida ce contine cartonasul alb cu numarul ca { b++;//nr cartonase din baza piramida curenta nra=0;//caut in piramida curenta cartonasele albe cp=b*(b+1)/2; //nr cartonase din care e formata piramida curenta if(cp+cfol<=n) //daca am cele cp cartoane atunci pot construi piramida { m++; //numar piramida construita if(cfol<x && x<=cp+cfol) p=m; //verif daca contine cartonasul x cfol+=cp; while(ca<=cfol && i<=k) { nra++;f>>ca;i++;} //numar cartonasele albe din piramida if(nra>maxnra) { a=m; maxnra=nra; } } else break; } while (cfol<n); c=n-cfol; g<<p<<endl<<m<<endl<<c<<endl<<a<<endl; return 0; } Listing 6.2.2: p_v_CM.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 //prof.Carmen Minca C.N.I.T.Vianu - Bucuresti #include <fstream> using namespace std; /*a) numarul P al piramidei ce conÈŻine cartonasul numerotat cu X; b) numarul M maxim de piramide construite de Gigel; c) numarul C de cartonaÈŹe nefolosite; d) numarul A al primei piramide care contine cele mai multe cartonaÈŹe albe. */ int n, x, k, cart[100]; ifstream f("piramide.in"); ofstream g("piramide.out"); int main() { int p=0, a=0, m=0, c,i,ca,b,nra, maxnra=0,j; CAPITOLUL 6. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 86 OJI 2014 f>>n>>x>>k; b=1; cart[1]=3; m=0; b++; while(cart[m]+b*(b+1)/2<=n) { m++; cart[m]=b*(b+1)/2+cart[m-1]; b++; if(x>cart[m-1] && x<=cart[m])p=m; } c=n-cart[m]; j=1; i=1; f>>ca; while(i<=k && j<=m) { while(ca>cart[j] && j<=m) j++; if(j<=m) { nra=0; while(ca<=cart[j] && i<=k) { nra++; f>>ca; i++; } if(nra>maxnra){a=j; maxnra=nra;} } } g<<p<<endl<<m<<endl<<c<<endl<<a; return 0; } Listing 6.2.3: pAna.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <fstream> using namespace std; ifstream f("piramide.in"); ofstream g("piramide.out"); int N,X,K,i,ls,ld,P,nrpc,nrc,nrca,maxca,nrpmax,c,S,nr; int main() { //citire f>>N>>X>>K; //a) ls=1;ld=3;nrpc=1; while(X>ld){nrpc++;ls=ld+1;ld+=(nrpc+1)*(nrpc+2)/2;} if(N>=ld)g<<nrpc<<endl; else g<<0<<endl; //b) S=0;nrpc=0;nr=1; while(N>S){nrpc++;nr++;S+=nr*(nr+1)/2;} if(N<S){S-=nr*(nr+1)/2;nrpc--;} g<<nrpc<<endl; //c) g<<N-S<<endl; //d) ls=1;ld=3;nrpc=1;nrc=3; f>>c;K--;//cartonasul alb curent do { while(c>ld) { nrpc++;ls=ld+1;ld+=(nrpc+1)*(nrpc+2)/2;nrca=0; } nrca++;f>>c;K--;if(K==0)nrca++; if(nrca>maxca && ld<=N){maxca=nrca;nrpmax=nrpc;} CAPITOLUL 6. 40 41 42 43 44 45 46 47 48 49 87 OJI 2014 } while(K>0); //afisare g<<nrpmax<<endl; f.close(); g.close(); return 0; } Listing 6.2.4: pCristina.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 //piramide - Cristina Sichim #include <fstream> using namespace std; ifstream f("piramide.in"); ofstream g("piramide.out"); int n,x,k,p=1,l=2,amax,a,y,pmax=1,prim=1,ultim=3,px; int main() { f>>n>>x>>k>>y; while(ultim<=n) { if(x>=prim && x<=ultim)px=p; while(k && y>=prim && y<=ultim) {a++,k--;if(k)f>>y;} if(a>amax) amax=a,pmax=p; ++p;++l;a=0; prim=ultim+1; ultim+=l*(l+1)/2; } if(n<ultim)p--,ultim=prim-1; g<<px<<’\n’<<p<<’\n’<<n-ultim<<’\n’; if(amax) g<<pmax<<’\n’;else g<<"0\n"; f.close(); g.close(); return 0; } Listing 6.2.5: pGina.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <fstream> using namespace std; ifstream f("piramide.in"); ofstream g("piramide.out"); long N,X,K,c,k,S,i,A,maxa,P,M,piramida,nca,C; int main() { f>>N>>X>>K;k=1; while(S<=N) { if(P==0 && X<S) P=k-1; S+=(k+1)*(k+2)/2; k++; } g<<P<<endl; k--; S=S-(k+1)*(k+2)/2; k=k-1; C=N-S; CAPITOLUL 6. 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 88 OJI 2014 g<<k<<endl<<C<<endl; // g<<S<<" k="<<k<<" "<<M<<endl; maxa=0;A=0;nca=0;piramida=0;long cf=N-C;S=0;k=1; for(i=1;i<=N;i++) { f>>c; if(S>=c) nca++; else { if(maxa<nca){maxa=nca;A=k-1;} while(S<=cf && S<=c) { S+=(k+1)*(k+2)/2; k++;} if(c<=S) nca=1; else nca=0; } } g<<A<<endl; return 0; } Listing 6.2.6: pMarilena.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <fstream> using namespace std; int N,K,S,S1,c,nr,ok,pmax,ppmax,vmin,vmax,np,nrc,i,ok1,x; ifstream f("piramide.in"); ofstream g("piramide.out"); int main() { f>>N>>x>>K>>c; for(i=2;i<=N;i++) { S1=i*(i+1)/2; // piramida i-1 are numerele in intervalul [vmin,vmax] vmin=S+1;vmax=S+S1; S=S+S1; //verifica daca se formeaza piramida i-1 if(N>=vmin&&N<=vmax){ np=i-2; nrc=N-vmin+1;i=N;ok1=1;} if(ok1==0)//daca se formeaza piramida i-1 { //verifica daca numarul x este in piramida i-1 if(x>=vmin&&x<=vmax)ok=i-1; nr=0; //numaram cartonasele albe din piramida i-1 while(c>=vmin&&c<=vmax&& !f.eof()){ nr++; f>>c;} if (nr>pmax) {pmax=nr; ppmax=i-1;} } } g<<ok<<endl<<np<<endl<<nrc <<endl<<ppmax; f.close(); g.close(); return 0; } Listing 6.2.7: pRaluca.cpp 1 2 3 4 #include <fstream> using namespace std; CAPITOLUL 6. 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 OJI 2014 ifstream f("piramide.in"); ofstream g("piramide.out"); int n, x, k, c; int main() { f>>n>>x>>k; int cp=0, cc=3, pas=3, cn=n, pc=1, uc=3,px=0,c1; while(cn>=cc) { cn-=cc; cp++; if(x>=pc and x<=uc) px=cp; cc+=pas; pas++; pc=uc+1; uc=pc+cc-1; } g<<px<<’\n’<<cp<<’\n’<<cn<<’\n’; f>>c1; pc=1;uc=3;cc=3;pas=3; int cpp=1; while(c1>uc) { cpp++; cc+=pas; pas++; pc=uc+1; uc=pc+cc-1; } int max=0, ca=1, pir=0,i; for(i=2;i<=k and cpp<=cp;i++) { f>>c1; if(c1<=uc)ca++; else { if(ca>max and cpp<=cp)max=ca, pir=cpp; ca=1; while(c1>uc) { cpp++; cc+=pas; pas++; pc=uc+1; uc=pc+cc-1; } } } if(ca>max and cpp<=cp) max=ca, pir=cp; g<<pir<<’\n’; f.close(); g.close(); return 0; } 89 Capitolul 7 OJI 2013 7.1 bete - OJI 2013 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. minute de joac urmeaz cearta. Bunicul le-a propus s rup Dup cele N beµe ³i apoi Ana s câteva 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 a) lungimea iniµial se scrie un program care s determine: 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 & N & 1000 & 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 1 a 1 a Odat lipite dou fragmente, acestea nu se pot dezlipi. a Pentru determinarea corect corect a valorii K se acord acord 40% din punctaj. a valorii L se acord 30% din punctaj, pentru determinarea 30% din punctaj, iar pentru determinarea corect 90 a valorii P se CAPITOLUL 7. OJI 2013 Exemple bete.in 91 bete.out Explicaµii 6 10 Lungimea iniµial este 10, 2 6 7 1 3 5 16 lungimea maxim este 16 5 4 7 8 9 3 1 ³i se poate forma un singur b µ de lungime 16. Timp maxim de executare/test: 0.5 secunde Memorie: total 2 MB din care pentru stiv 1 MB Dimensiune maxim a sursei: 5 KB 7.1.1 Indicaµii de rezolvare prof. Lucia Miron Pentru a determina lungimea initiala a betelor L vom determina in S suma numerelor citite. Apoi evident L = S div N Determinam maximul elementelor din sirul a si numarul de aparitii al maximului, notate maxa si nrmaxa, apoi determinam maximul elementelor din b si numarul de aparitii al acestuia, notate maxb si nrmaxb. Evident K = maxa + maxb nrbetemax = min(nrmaxa, nrmaxb) Toate datele necesare le determinam la citire, nu este necesara utilizarea tablourilor 7.1.2 *Rezolvare detaliat 7.1.3 Cod surs Listing 7.1.1: bete_OFICIAL.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 //Lucia Miron #include<fstream> using namespace std; ifstream fin("bete.in"); ofstream fout("bete.out"); int n,l,k,a,b,i,j,s,ma,mb,na,nb; int main() { fin>>n; fin>>a; ma=a;na=1;s=a; for(i=2;i<=n;i++) { fin>>a; if(ma<a){ma=a;na=1;} else if(ma==a)na++; s+=a; } fin>>b; CAPITOLUL 7. 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 92 OJI 2013 mb=b;nb=1;s+=b; for(i=2;i<=n;i++) { fin>>b; if(mb<b){mb=b;nb=1;} else if(mb==b) nb++; s+=b; } l=s/n; fout<<l<<’\n’<<ma+mb<<’\n’<<min(na,nb)<<’\n’; fout.close(); return 0; } Listing 7.1.2: bete_vectori.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 //octavian dumitrascu #include<fstream> using namespace std; ifstream fin("bete.in"); ofstream fout("bete.out"); int n,l,k,a[1001],b[1001],i,j,s,p; int main() { fin>>n; s=0; for(i=1;i<=n;i++) { fin>>a[i]; s+=a[i]; } for(i=1;i<=n;i++) { fin>>b[i]; s+=b[i]; } l=s/n; k=0; for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(a[i]+b[j]>k) k=a[i]+b[j]; for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(a[i]+b[j]==k) { p++; a[i]=-1; b[j]=-1; }; fout<<l<<’\n’<<k<<’\n’<<p; fout<<’\n’; fout.close(); return 0; } 7.2 chibrituri - OJI 2013 Problema 2 - chibrituri 100 de puncte CAPITOLUL 7. 93 OJI 2013 Lui Gigel, elev în clasa a V-a, îi place grozav de tare s se joace cu cifrele, cu numerele ³i creeaz tot felul de probleme pe care apoi încearc s cu o cutie de chibrituri ³i formeaz le rezolve. Acum se joac cu ele cifre. Apoi privirea i-a c zut pe cadranul unui ceas electronic ³i a v zut c cifrele sunt formate din segmente orizontale ³i verticale ³i a început s formeze cu chibriturile cifrele care indic ora (vezi gura). i imediat ³i-a pus o întrebare: oare dac orizontal, care este ora minim Figura 7.1: chibrituri1 am n chibrituri puse vertical ³i m chibrituri puse pe care o pot forma cu aceste chibrituri Cerinµe Fiind date un num r n de chibrituri verticale ³i un num r m de chibrituri orizontale, s scrie un program care determin num rul de ore posibile, ora minim ³i ora maxim se 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 forma o or chibrituri.out va conµine pe prima linie num rul de variante posibile de a 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 toate chibriturile ³i nemodicând orientarea acestora. Ora minim ³i, respectiv, ora maxim utilizând vor scrie sub forma hh mm, unde ora hh ³i minutul mm vor formate din exact dou separate prin caracterul : (dou se cifre, puncte). Restricµii ³i preciz ri Pentru datele de test exist întotdeauna soluµie. Cifrele sunt formate din chibrituri în felul urm tor: Figura 7.2: chibrituri2 Pentru determinarea corect determinarea corect a num rului de variante se va acorda 20% din punctaj, pentru a num rului de variante ³i a orei minime se va acorda 60% din punctaj, iar pentru determinarea corect a num rului de variante, a orei minime ³i a orei maxime se va acorda punctajul maxim. Exemple chibrituri.in chibrituri.out Explicaµii 14 10 17 17 variante posibile 00:28 Ora minim : 00:28 20:08 Ora maxim : 20:08 Timp maxim de executare/test: 0.1 secunde Memorie: total 2 MB din care pentru stiv 1 MB Dimensiune maxim a sursei: 5 KB 7.2.1 Indicaµii de rezolvare prof. Marinel Serban Numar si retin pentru fiecare cifra numarul de chibrituri verticale si orizontale necesare. Retinerea valorilor o fac fie intr-un vector, fie in variabile fie ... pe hartie! CAPITOLUL 7. 94 OJI 2013 Plec de la ora 00:00, adica 0 minute Marchez faptul ca inca nu am gasit nicio ora corecta Parcurg toate orele posibile - intr-o zi sunt 24*60 minute calculez ora calculez minutele calculez prima si a doua cifra a orei calculez prima si a doua cifra a minutului numar chibriturile verticale (fie din vector, fie din variabile, fie direct ca si constante in instructiuni if sau switch) numar chibriturile orizontale (la fel) daca am gasit ambele valori corecte mai am o solutie, o numar daca este prima gasita aceasta este ora minima, o retin daca nu este prima am mai gasit solutie deci aceasta este (deocamdata) ora maxima, o retin trec la ora (minutul) urmatoare Afisez tinand cont ca daca am doar o solutie, aceasta este si ora maxima 7.2.2 *Rezolvare detaliat 7.2.3 Cod surs Listing 7.2.1: chibrituri_OFICIAL.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 //Serban Marinel - ianuarie 2013 //solutie fara utilizarea vectorilor #include <fstream> using namespace std; ifstream fin("chibrituri.in"); ofstream fout("chibrituri.out"); bool OK1; short int t, h1, h2, m1, m2, v, o, vOK, oOK, Cate; short int h1min, h2min, m1min, m2min; short int h1max, h2max, m1max, m2max; int main() { fin >> vOK >> oOK; t = 0; OK1 = false; Cate = 0; while (t < 24 * 60) { m1 = t % 60; h1 = t / 60; h2 = h1 % 10; h1 = h1 / 10; m2 = m1 % 10; m1 = m1 / 10; v = 0; switch (h1) { case 1: case 2: case 3: case 5: //plec de la ora 00:00 //inca nu am gasit nici o ora corecta //intr-o zi sunt 24*60 minute //trec pe la fiecare //ora //minute //a doua cifra a orei //prima cifra a orei //a doua cifra a minutului //prima cifra a minutului //numar chibrituri verticale CAPITOLUL 7. 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 OJI 2013 case 7: v += 2; break; case 4: case 6: case 9: v += 3; break; case 0: case 8: v += 4; break; } switch (h2) { case 1: case 2: case 3: case 5: case 7: v += 2; break; case 4: case 6: case 9: v += 3; break; case 0: case 8: v += 4; break; } switch (m1) { case 1: case 2: case 3: case 5: case 7: v += 2; break; case 4: case 6: case 9: v += 3; break; case 0: case 8: v += 4; break; } switch (m2) { case 1: case 2: case 3: case 5: case 7: v += 2; break; case 4: case 6: case 9: v += 3; break; case 0: case 8: v += 4; break; } o = 0; //numar chibrituri orizontale switch (h1) { case 1: o += 0; break; case 4: case 7: o += 1; break; case 0: o += 2; break; case 2: case 3: case 5: case 6: case 8: case 9: o += 3; break; } switch (h2) { case 1: o += 0; break; case 4: case 7: o += 1; break; case 0: o += 2; break; case 2: case 3: case 5: case 6: case 8: case 9: o += 3; break; } switch (m1) { 95 CAPITOLUL 7. 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 96 OJI 2013 case 1: o += 0; break; case 4: case 7: o += 1; break; case 0: o += 2; break; case 2: case 3: case 5: case 6: case 8: case 9: o += 3; break; } switch (m2) { case 1: o += 0; break; case 4: case 7: o += 1; break; case 0: o += 2; break; case 2: case 3: case 5: case 6: case 8: case 9: o += 3; break; } if (v == vOK && o == oOK) //daca am gasit ambele valori corecte { Cate++; //mai am o solutie, o numar if (!OK1) //prima gasita? deci este ora minima, retin { h1min = h1, h2min = h2, m1min = m1, m2min = m2; OK1 = true; } else //am mai gasit deci este (deocamdata) ora maxima h1max = h1, h2max = h2, m1max = m1, m2max = m2; } t++; //trec la ora (minutul) urmatoare } fout << Cate << ’\n’; fout << h1min << h2min << ’:’ << m1min << m2min << ’\n’; if (Cate == 1) //daca am doar o solutie, aceasta este si ora maxima fout << h1min << h2min << ’:’ << m1min << m2min << ’\n’; else fout << h1max << h2max << ’:’ << m1max << m2max << ’\n’; fout.close(); return 0; } Listing 7.2.2: chibrituri_v.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 //Serban Marinel - ianuarie 2013 //solutie cu utilizarea vectorilor #include <fstream> using namespace std; ifstream fin("chibrituri.in"); ofstream fout("chibrituri.out"); int OK1; short int t, h1, h2, m1, m2, v, o, vOK, oOK, Cate; short int h1min, h2min, m1min, m2min; short int h1max, h2max, m1max, m2max; short int Vert[] = {4, 2, 2, 2, 3, 2, 3, 2, 4, 3}; short int Oriz[] = {2, 0, 3, 3, 1, 3, 3, 1, 3, 3}; int main() { fin >> vOK >> oOK; t = 0; OK1 = 0; Cate = 0; //plec de la ora 00:00 //inca nu am gasit nici o ora corecta CAPITOLUL 7. 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 97 OJI 2013 while (t < 24 * 60) { m1 = t % 60; h1 = t / 60; h2 = h1 % 10; h1 = h1 / 10; m2 = m1 % 10; m1 = m1 / 10; //intr-o zi sunt 24*60 minute //trec pe la fiecare //ora //minute //a doua cifra a orei //prima cifra a orei //a doua cifra a minutului //prima cifra a minutului //numar chibrite verticale v = Vert[h1] + Vert[h2] + Vert[m1] + Vert[m2]; //numar chibrite orizontale o = Oriz[h1] + Oriz[h2] + Oriz[m1] + Oriz[m2]; if (v == vOK && o == oOK) //daca am gasit ambele valori corecte { Cate++; //mai am o solutie, o numar if (OK1 == 0) //prima gasita? deci este ora minima, retin { h1min = h1, h2min = h2, m1min = m1, m2min = m2; OK1 = 1; } else //am mai gasit deci este (deocamdata) ora maxima h1max = h1, h2max = h2, m1max = m1, m2max = m2; } t++; //trec la ora (minutul) urmatoare } fout << Cate << ’\n’; fout << h1min << h2min << ’:’ << m1min << m2min << ’\n’; if (Cate == 1) //daca am doar o solutie, aceasta este si ora maxima fout << h1min << h2min << ’:’ << m1min << m2min << ’\n’; else fout << h1max << h2max << ’:’ << m1max << m2max << ’\n’; fout.close(); return 0; } Capitolul 8 OJI 2012 8.1 alice - OJI 2012 Problema 1 - alice Într-o zi frumoas 100 de puncte 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³ natural. Într-o clip , lâng era scris câte un num r ea ap ru Iepurele Alb ³i-i spuse c cu numere magice pot deschise dac ajuta, Iepurele Alb i-a explicat c care poate redus la o cifr are cheile potrivite. doar u³ile Figura 8.1: alice Pentru a o un num r magic este un num r natural prin complementarea cifrelor acestuia faµ de cifra sa maxim scrierea zecimal , apoi prin complementarea cifrelor num rului obµinut faµ ³i a³a mai departe pân magice. din de cifra sa maxim când se obµine o cifr . Evident, nu toate numerele naturale sunt numere 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 Înainte s 3240 1204 3240 1204.). dispar , Iepurele Alb îi d du o cheie aurie inscripµionat poate deschide cu aceast cu cifra K ³i o avertiz c cheie doar u³ile cu numere magice ce pot reduse la cifra K . Cerinµe Scrieµi un program care s pe cele N u³i, ³i care s citeasc numerele naturale N , K ³i cele N numere naturale scrise 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 98 CAPITOLUL 8. 99 OJI 2012 - complementarea cifrelor unui num r natural faµ de cifra sa maxim din scrierea zecimal 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; const în înlocuirea ec rei cifre - pe ecare u³ - exist este scris un singur num r natural; 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 corect a cerinµei a) se acord a ambelor cerinµe se acord Exemple alice.in 20% din punctaj, iar pentru rezolvarea 100% din punctaj. 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 123 210 804 84 12 10 4), 23(23 1), 13(13 10 3210 20 2), 195(195 1), 10(10 1), 888 (888 0). Num rul 1204 nu este un num r magic. Astfel num rul 3 se va scrie pe a doua linie a ³ierului Timp maxim de executare/test: 1.0 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 10 KB 8.1.1 Indicaµii de rezolvare Figura 8.2: AliceIR1 alice.out. CAPITOLUL 8. 100 OJI 2012 Figura 8.3: AliceIR2 Figura 8.4: AliceIR3 Figura 8.5: AliceIR4 CAPITOLUL 8. 101 OJI 2012 8.1.2 *Rezolvare detaliat 8.1.3 Cod surs Listing 8.1.1: alice_CM2.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 //autor. prof. Carmen Minca #include <fstream> using namespace std; int main() { int x,cmax,c,z,nrmax,i,nc=0,a, maxpar=0,n,j,nr=0,k; ifstream f("alice.in"); ofstream g("alice.out"); f>>n>>k; for(j=1;j<=n; j++) { f>>a; z=x=a; if(a%2==0 && maxpar<a)maxpar=a; do { a=z; z=x; cmax=0; nc=0; while(x) { c=x%10; x=x/10;nc++; if(c>cmax)cmax=c; } nrmax=0; for(i=1;i<=nc;i++) nrmax=nrmax*10+cmax; x=nrmax-z; } while(x>9 && x!=z && x!=a); if(x==k) nr++; } g<<maxpar<<endl<<nr; return 0; } Listing 8.1.2: alice_CS.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //prof. Cristina Sichim #include <fstream> using namespace std; ifstream f("alice.in"); ofstream g("alice.out"); int i,n,x,m,k,nr; int vm(int x) { int cmax=0,u=0; while(x) { if(x%10>cmax) cmax=x%10; x=x/10; CAPITOLUL 8. 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 102 OJI 2012 u=u*10+1; } return u*cmax; } int complement(int x) { int nr=0,u; while(x>9 && nr<9) { u=vm(x); x=u-x; nr++; } if(x>9)return -1; return x; } int main() { f>>n>>k; while(n--) { f>>x; if(x%2==0 && x>m) m=x; if(complement(x)==k) nr++; } g<<m<<’\n’<<nr<<’\n’; f.close(); g.close(); return 0; } Listing 8.1.3: alice_SJ.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 //prof.Sanda Junea #include <iostream> #include<fstream> using namespace std; ifstream f("alice.in"); ofstream g("alice.out"); int magic(int x); int n,k,nr,maxim,x; int main(void) { f>>n>>k; for( int i = 0; i < n; ++i ) { f>>x; if(x%2==0 && x>maxim) maxim=x; if(magic(x)==k) nr++; } g<<maxim<<endl; g<<nr; f.close(); g.close(); return 0; } CAPITOLUL 8. 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 103 OJI 2012 int magic(int x) { int y=x,m=0,l=x,r=1,zero=0,ok=1,z=x; if(x<10) return x; while(l>=10 && ok) { l=0;r=1,m=0; y=x; while(y) { if(y%10>m) m=y%10; y=y/10; } y=x; while(y) { l=l+r*(m-y%10); r=r*10; y=y/10; } if(l==z) ok=0; else { ok=1; z=x; x=l; } } if(l<10) return l; else return -1; } 8.2 porumb - OJI 2012 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 Metoda se repet pân ca ³i primul agri. când toµi porumbii sunt cule³i. P mânteanul Ionel încearc s descopere ce ascunde aceast metod ³i se gânde³te câµi porumbi culege primul agri, câµi agri culeg un rând cu n porumbi, la a câta trecere este cules porumbul cu num rul x ³i care este num rul ultimului porumb cules. Exemplu: Dac pe un rând sunt n=14 porumbi atunci sunt 4 agri care culeg porumbii: a primul agri culege porumbii 1,3,5,7,9,11,13; a al doilea agri culege porumbii 2,6,10,14; a al treilea agri culege porumbii 4 ³i 12; a ultimul agri culege porumbul 8. Cerinµe Pentru a-l ajuta pe Ionel s Figura 8.6: porumbi descopere secretul acestei metode, scrieµi un program care cite³te cele dou a) num rul de porumbi cule³i de primul agri; numere naturale n ³i x ³i care determin : CAPITOLUL 8. 104 OJI 2012 b) num rul de agri care culeg ³irul de n porumbi; c) num rul trecerii la care este cules porumbul cu num rul x; d) num rul ultimului porumb cules. Date de intrare Fi³ierul porumb.in conµine pe prima linie, separate printr-un spaµiu, cele dou numere natu- rale n ³i x cu semnicaµia din enunµ. Date de ie³ire Fi³ierul de ie³ire porumb.out va conµine patru linii: - pe prima linie se va scrie un num r natural reprezentând num rul de porumbi cule³i de primul agri; - pe a doua linie se va scrie un num r natural reprezentând num rul de agri care culeg cei n porumbi; - pe a treia linie se va scrie un num r natural, reprezentând num rul trecerii la care este cules porumbul x; - pe a patra linie se va scrie un num r natural, reprezentând num rul ultimului porumb cules. Restricµii ³i preciz ri - 1 & x & n & 1000000000 - Trecerile se numeroteaz în ordine, începând cu valoarea 1. - Pentru rezolvarea corect a cerinµei a) se acord - Pentru rezolvarea corect a cerinµelor a) ³i b) se acord - Pentru rezolvarea corect a cerinµelor a), b) ³i c) se acord - Pentru rezolvarea corect a celor patru cerinµe se acord 10% din punctaj. 40% din punctaj. 70% din punctaj. 100% din punctaj. Exemple porumb.in porumb.out Explicaµii 14 4 7 7 reprezint 4 Sunt 4 agri care culeg rândul cu n 3 Porumbul x 8 num rul de porumbi cule³i de primul agri. 14 porumbi. 4 este cules la a 3-a trecere iar ultimul porumb cules are num rul 8. Timp maxim de executare/test: |1.0 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 10 KB 8.2.1 Indicaµii de rezolvare CAPITOLUL 8. 105 OJI 2012 Figura 8.7: porumbIR1 Figura 8.8: P orumbIR2 8.2.2 *Rezolvare detaliat 8.2.3 Cod surs Listing 8.2.1: p100_AS.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 //prof.Adriana Simulescu #include<iostream> #include<fstream> using namespace std; int main() {ofstream out("porumb.out"); ifstream in("porumb.in"); int p=1,n,na=1,x,randx; in>>n>>x; out<<(n+1)/2<<endl; CAPITOLUL 8. 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 106 OJI 2012 while(p<n) {p=p*2; na++; if((x-p)%(p*2)==0) randx= na; } if(p>n) {p=p/2;na--;} if(x%2==1) randx=1; out<<na<<endl<<randx<<endl<<p<<endl; in.close(); out.close(); return 0; } Listing 8.2.2: p100_CL.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 //prof. Chira Liliana #include<cstdio> using namespace std; int n,x; int main() { int m=1,k=0,nr=0; freopen("porumb.in","r",stdin); freopen("porumb.out","w",stdout); scanf("%d%d", &n, &x); printf("%d\n", (n+1)/2); while(m<=n) m*=2; m/=2; while(x%2==0) { x/=2; k++; } while(n!=0) { nr++; n/=2; } printf("%d\n%d\n%d\n", nr , k+1, m); return 0; } Listing 8.2.3: p100_CM1.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 //prof.Carmen Minca #include <fstream> #include <iostream> using namespace std; int main() { ifstream f("porumb.in"); ofstream g("porumb.out"); int n,x,pas=1,t=0,tx=0,u=0,k=0,m; CAPITOLUL 8. 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 107 OJI 2012 f>>n>>x; g<<(n+1)/2<<endl; m=n; while(k!=m) { t++; //o noua trecere k=k+(n+1)/2; //nr.porumbi culesi=nr de nr impare <=n //sirul: pas(1,2,3,4,5,6,7), pas=2^(t-1) u=n*pas; if(n%2==0) u-=pas; if(x%pas==0)tx=t; n/=2; pas*=2; } if(x%2)tx=1; g<<t<<endl<<tx<<endl<<u<<endl; } Listing 8.2.4: p100_CM2.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 //prof. Carmen Mica - o altfel de solutie #include <fstream> #include <iostream> #include <cmath> using namespace std; int main() { ifstream f("porumb.in"); ofstream g("porumb.out"); int n,x,a,t,ult,u; f>>n>>x; g<<(n+1)/2<<endl; u=log10(n*1.0)/log10(2.); //u<--log2(n) a=u+1; //a<--2^(u+1) ult=pow(2.0,u); //ult<--2^u t=1; while(x%2==0){t++; x>>=1;} // x este pe randul care incepe cu // 2^(t-1), t=maximum cu aceasta proprietate g<<a<<endl<<t<<endl<<ult<<endl; return 0; } Listing 8.2.5: p100_CS.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //autor. prof Cristina Sichim # include <fstream> using namespace std; long n,m,x,nr; int main() {ifstream f("porumb.in"); ofstream g("porumb.out"); f>>n>>x; //a) nr.porumbi la prima trecere g<<(n+1)/2<<’\n’; //b) nr trasee m=n; CAPITOLUL 8. 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 108 OJI 2012 while(m>0)nr++,m=m/2; g<<nr<<’\n’; //c)cand culege porumbul x while(x%2==0) x=x/2,m++; g<<m+1<<’\n’; //d) ultimul porumb m=1; while(m*2<=n)m=m*2; g<<m<<’\n’; f.close(); g.close(); return 0; } Listing 8.2.6: p100_DT.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 //prof. Daniela Tarasa #include<fstream> #include<math.h> using namespace std; ifstream f("porumb.in"); ofstream g("porumb.out"); int nr,n,x,nr1=1,aux; long long q; int main() {f>>n>>x; aux=x; //numarul de porumbi culesi de primul agri if(n%2==0) g<<n/2<<’\n’;else g<<n/2+1<<’\n’; //numarul de agri while(n!=0) { n=n/2; nr++; } g<<nr<<’\n’; //numarul trecerii la care este cules porumbul x while(x%2==0) { x=x/2; nr1++; } if (aux%2!=0) g<<1<<’\n’; else g<<nr1<<’\n’; q=pow(2,nr-1); g<<q<<’\n’; f.close(); g.close(); return 0; } Listing 8.2.7: p100_JIT.cpp 1 2 3 4 5 6 //prof. Jakab Irma Tunde #include <iostream> #include <fstream> #include <conio.h> #include <math.h> CAPITOLUL 8. 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 OJI 2012 using namespace std; int main(void) {unsigned long n,x,p=1,e=0,a,b; fstream f,g; f.open("porumb.in", ios::in); f>>n>>x; while (p*2<n) { p*=2; e++; } if (x%2)b=1; else { a=p;b=0; while (x%a!=0) { a/=2; b++; } } cout<<e+1<<’ ’<<e+1-b<<’ ’<<p; g.open("porumb.out", ios::out); g<<(n+1)/2<<endl<<e+1<<endl<<e+1-b<<endl<<p;; g.close(); } 109 Capitolul 9 OJI 2011 9.1 magic - OJI 2011 Problema 1 - magic 100 de puncte R ma³i singuri în p dure, Hansel ³i Grettel, ³tiu c g seasc ³i s intre în Castelul de Turt singura lor ³ans de supravieµuire este s 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 iar în drumul vostru o s vrea s -i ajute le spune: Mergeµi tot înainte, î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 Pentru rezolvarea cerinµei a) se acord Exemple magic.in diferit de zero. 40% din punctaj, pentru cerinµa b) 60% din punctaj magic.out Explicaµii 6 CB Cel mai mic num r cu cifre distincte c 2 5 5 b 2 25 ce se poate obµine este 25. 8 CABD 205 Cel mai mic num r cu cifre distincte c a 5 0 b 2 5 d ce se poate obµine este 205. Timp maxim de executare/test: 1.0 secunde 110 CAPITOLUL 9. 9.1.1 111 OJI 2011 Indicaµii de rezolvare Descriere solutie care utilizeaza vector caracteristic: Se considera vectorul caracteristic c asociat cifrelor de pe a doua linie a fisierului, vector construit astfel: 1, daca cifra i se afla pe a doua linie a fisierului c[i]= 0, altfel Prin parcurgerea caracterelor de pe a doua linie a fisierului, se determina si se afiseaza ca majuscule caracterele litera si se completeaza vectorul caracteristic. Numarul cerut se afiseaza prin parcurgerea vectorului caracteristic de la stanga la dreapta. Se trateaza separat cazul in care exista cifra 0. Daca nu exista cifre nenule, se va afisa 0, altfel, aceasta va aparea imediat dupa cifra cea mai mica, nenula, gasita pe a doua linie a fisierului. Descriere solutie care nu utilizeaza tablouri: Fiecarei cifre i se asociaza o variabila care sa memoreze aparitia acesteia pe a do linie a fisierului (0 daca nu apare si 1 daca apare). Prin parcurgerea caracterelor de pe a doua linie a fisierului, se determina si se afiseaza ca majuscule caracterele litera si se actualizeaza variabilele asociate caracterelor de tip cifra. Numarul cerut se afiseaza prin cercetarea continuturilor variabilelor asociate cifr Se trateaza separat cazul in care exista cifra 0. Daca nu exista cifre nenule, se va afisa 0, altfel, aceasta va aparea imediat dupa cea mai mica, nenula, gasita pe a doua linie a fisierului. 9.1.2 *Rezolvare detaliat 9.1.3 Cod surs Listing 9.1.1: CARACTER.CPP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include<iostream> #include<fstream> #include<ctype.h> using namespace std; char s[1001]; int c[10]; int n; int main() { int i,ncifre=0,j; ifstream f("magic.in"); ofstream g("magic.out"); f>>n; for(i=1;i<=n;i++) { f>>s[i]; s[i]=toupper(s[i]); if(isdigit(s[i])) { ncifre++; c[s[i]-48]++; } } CAPITOLUL 9. 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 112 OJI 2011 for(i=1;i<=n;i++) if(isalpha(s[i])) g<<s[i]; g<<’\n’; i=1; while(c[i]==0) i++; if(c[0]) g<<i<<0; else g<<i; for(j=i+1;j<=9;j++) if(c[j]) g<<j; f.close(); g.close(); return 0; } Listing 9.1.2: magic_DM.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include<fstream> #include<ctype.h> using namespace std; char s; int n; int c0,c1,c2,c3,c4,c5,c6,c7,c8,c9; int main() { int i; int nr; ifstream f("magic.in"); ofstream g("magic.out"); f>>n; for (i=1;i<=n;i++) { f>>s; if(isalpha(s)) { s=toupper(s); g<<s; } else { nr=int(s)-48; switch(nr) { case 0: c0++;break; case 1: c1++;break; case 2: c2++;break; case 3: c3++;break; case 4: c4++;break; case 5: c5++;break; case 6: c6++;break; case 7: c7++;break; case 8: c8++;break; case 9: c9++;break; } } } g<<’\n’; int t=0; CAPITOLUL 9. 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 OJI 2011 if(c1) { g<<1; if(c0 && t==0) { t=1; g<<0; } } if(c2) { g<<2; if(c0 && t==0) { t=1; g<<0; } } if(c3) { g<<3; if(c0 && t==0) { t=1; g<<0; } } if(c4) { g<<4; if(c0 && t==0) { t=1; g<<0; } } if(c5) { g<<5; if(c0 && t==0) { t=1; g<<0; } } if(c6) { g<<6; if(c0 && t==0) { t=1; g<<0; } } if(c7) { g<<7; if(c0 && t==0) { t=1; g<<0; } } if(c8) { g<<8; if(c0 && t==0) { t=1; 113 CAPITOLUL 9. 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 114 OJI 2011 g<<0; } } if(c9) { g<<9; if(c0 && t==0) { t=1; g<<0; } } if(t==0 && c0) g<<0; f.close(); g.close(); return 0; } Listing 9.1.3: MAGIC_S.CPP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <fstream> using namespace std; int x[10]; int main() { ifstream fin("magic.in"); ofstream fout("magic.out"); int n, g = 0, i; char c; fin >> n; for( i = 1; i <= n; i++) { fin >> c; if(’a’<= c && c <= ’z’) { c = c - 32; fout << c; } else { x[c-48]++; g = 1; } } fout<<’\n’; i = 1; while(x[i] == 0)i++; if(i <= 9) fout <<i, x[i] = 0; for(i = 0; i <= 9; i++) if(x[i]) fout << i; fout << ’\n’; fin.close(); fout.close(); return 0; } CAPITOLUL 9. 115 OJI 2011 Listing 9.1.4: magicAna.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <fstream> using namespace std; ifstream f("magic.in"); ofstream g("magic.out"); int n,i; char c; int x[10]; int main() { f>>n; for(i=1;i<=n;i++) { f>>c; if(c>=’a’ && c<=’z’) g<<(char)(c-32); else x[c-48]=1; } g<<’\n’; if(x[0]!=0) { i=1; while(x[i]==0 && i<=9)i++; } if(i<=9){g<<i;x[i]=0;} for(i=0;i<=9;i++) if(x[i]) g<<i; f.close(); g.close(); return 0; } Listing 9.1.5: MAGICDT3.CPP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include<fstream> using namespace std; ifstream f("magic.in"); ofstream g("magic.out"); long nr,nr_fin,m; int x0,x1,x2,x3,x4,x5,x6,x7,x8,x9; int main() { int n,i; char x; f>>n; for(i=1;i<=n;i++) { f>>x; if (!(x>=’0’ && x<=’9’)) g<<(char)(x-32); else switch (x) { case ’0’:x0++; break; case ’1’: x1++; break; case ’2’: x2++; break; case ’3’: x3++; break; case ’4’: x4++; break; case ’5’: x5++; break; case ’6’: x6++; break; case ’7’: x7++; break; case ’8’: x8++; break; case ’9’: x9++; break; } CAPITOLUL 9. 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 116 OJI 2011 } if(x1!=0 &&x0!=0) {nr=(nr*10+1)*10;x0=0;} else if(x1!=0) nr=nr*10+1; if(x2!=0 &&x0!=0) {nr=(nr*10+2)*10;x0=0;} else if (x2!=0) nr=nr*10+2; if(x3!=0 &&x0!=0) {nr=(nr*10+3)*10;x0=0;} else if(x3!=0) nr=nr*10+3; if(x4!=0 &&x0!=0) {nr=(nr*10+4)*10;x0=0;} else if(x4!=0) nr=nr*10+4; if(x5!=0 &&x0!=0) {nr=(nr*10+5)*10;x0=0;} else if(x5!=0) nr=nr*10+5; if(x6!=0 &&x0!=0) {nr=(nr*10+6)*10;x0=0;} else if(x6!=0) nr=nr*10+6; if(x7!=0 &&x0!=0) {nr=(nr*10+7)*10;x0=0;} else if(x7!=0) nr=nr*10+7; if(x8!=0 &&x0!=0) {nr=(nr*10+8)*10;x0=0;} else if(x8!=0) nr=nr*10+8; if(x9!=0 &&x0!=0) {nr=(nr*10+9)*10;x0=0;} else if(x9!=0) nr=nr*10+9; if(nr==0) g<<’\n’<<0<<’\n’; else g<<’\n’<<nr<<’\n’; f.close(); g.close(); return 0; } 9.2 numerus - OJI 2011 Problema 2 - numerus La ora de matematic propune elevilor s i s 100 de puncte distractiv , domnul profesor Numerus 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 tate primele 7 linii ale grilei. Deoarece pe tabl aveµi complesau 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 Numerus dore³te ca elevii s i s determine, cu ajutorul calcula- Figura 9.1: Numerus 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 numerele naturale k ³i n ³i care s linia k a grilei ³i scrieµi un program care s citeasc 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. CAPITOLUL 9. 117 OJI 2011 Date de ie³ire Fi³ierul de ie³ire numerus.out va conµine 3 linii: a) pe prima linie, se vor scrie numerele de pe linia k a grilei; b) pe a doua linie, se va scrie un num r natural reprezentând linia pe care se a în gril num rul natural n; c) pe a treia linie, se va scrie litera sau literele care reprezint care se a în gril coloana, respectiv coloanele pe num rul natural n; În situaµia în care avem de a³at dou litere acestea se vor a³a cu un spaµiu între ele. Restricµii ³i preciz ri a Numerele k ³i n sunt naturale nenule a 5 a 1 & k $ 200000000 & n & 999999999 Pentru rezolvarea cerinµei a) se acord 40% din punctaj, pentru cerinµa b) 30% din punctaj ³i pentru cerinµa c) 30% din punctaj. Exemple Figura 9.2: Numerus - exemple Timp maxim de executare/test: 1.0 secunde 9.2.1 Indicaµii de rezolvare a) Numerele de pe linia k sunt: 5* k-4, 5* k-3, 5* k-2, 5* k-1, 5* k, 5*k, daca linia k este impara si 5* k, 5*k, 5* k-1, 5* k-2, 5* k-3, 5* k-4, daca linia k este para b) Linia pe care se afla numarul n este: n/5, daca n este multiplu de 5 si [n/5]+1, altfel c) Coloana/coloanele pe care se afla numarul n este/sunt: A B, daca ultima cifra a lui n este 0 A, daca ultima cifra a lui n este 1 B, daca ultima cifra a lui n este 2 C, daca ultima cifra a lui n este 3 sau 9 D, daca ultima cifra a lui n este 4 sau 8 E, daca ultima cifra a lui n este 7 F, daca ultima cifra a lui n este 6 E F, daca ultima cifra a lui n este 5 9.2.2 *Rezolvare detaliat 9.2.3 Cod surs CAPITOLUL 9. 118 OJI 2011 Listing 9.2.1: A1_Numer.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include<fstream> using namespace std; ifstream f("numerus.in"); ofstream g("numerus.out"); long n,i,k,a,b,l,c; int main() { f>>k>>n; a=5*(k-1)+1; b=5*k; if(k%2==1) { for(i=a;i<=b;i++) g<<i<<’ ’; g<<b; } else { g<<b<<’ ’; for(i=b;i>=a;i--) g<<i<<’ ’; } g<<’\n’; l=n/5; if(n%5!=0)l++; g<<l<<’\n’; if(n%5==0) if(l%2==0) g<<’A’<<’ ’<<’B’; else g<<’E’<<’ ’<<’F’; else if(l%2==1) {char c=’A’+n%5-1;g<<c;} else{char c=’F’-n%5+1;g<<c;} g<<’\n’; f.close(); g.close(); return 0; } Listing 9.2.2: D_NUMERU.CPP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include<fstream> using namespace std; ifstream f("numerus.in"); ofstream g("numerus.out"); long n,k; int main() { long lin; f>>k>>n; lin=n/5; //prima cerinta if(k%2==0) g<<5*k<<’ ’<<5*k<<’ ’<<5*k-1<<’ ’<<5*k-2<<’ ’<<5*k-3<<’ ’<<5*k-4<<’\n’; else g<<5*k-4<<’ ’<<5*k-3<<’ ’<<5*k-2<<’ ’<<5*k-1<<’ ’<<5*k<<’ ’<<5*k<<’\n’; //a doua cerinta if(n%5==0) g<<lin<<’\n’; else {lin++;g<<lin<<’\n’;} // a treia cerinta if(lin%2==0) CAPITOLUL 9. 29 30 31 32 33 34 35 36 37 38 119 OJI 2011 if(n%5==0) g<<’A’<<’ ’<<’B’; else g<<(char)(’B’+(5-n%5)); else if(n%5==0) g<<’E’<<’ ’<<’F’; else g<<(char)(’E’-(5-n%5)); g<<’\n’; f.close(); g.close(); return 0; } Listing 9.2.3: S_Numeru.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #include <fstream> using namespace std; int main() { long k, n; long i, r, rd; ifstream fin("numerus.in"); ofstream fout("numerus.out"); fin >> k >> n; if(k % 2 == 1) { for(i = 1; i<= 5; i++) fout << (k-1)*5 +i<< " "; fout << k *5<<"\n"; } else { fout << k*5<< " "; for(i = 0; i< 5; i++) fout << k * 5 - i<< " "; fout << "\n"; } if( n%5 == 0) { rd = n/5; fout <<rd<<’\n’; } else { rd = (n/5 +1); fout << rd<< "\n"; } if(n%10 == 0 ) fout << ’A’<<" "<<’B’<<"\n"; else if(n%5 == 0) fout << ’E’<<" "<<’F’<< "\n"; if(rd % 2 == 1) { r = n%5; switch(r) { case 1: fout << ’A’<<"\n";break; case 2: fout << ’B’<<"\n";break; case 3: fout << ’C’<<"\n";break; case 4: fout << ’D’<<"\n";break; } } else { r = n%5; switch(r) { case 1: fout << ’F’<<"\n";break; case 2: fout << ’E’<<"\n";break; CAPITOLUL 9. 63 64 65 66 67 68 69 70 71 72 OJI 2011 case 3: fout << ’D’<<"\n";break; case 4: fout << ’C’<<"\n";break; } } fin.close(); fout.close(); return 0; } 120 Capitolul 10 OJI 2010 10.1 sir - OJI 2010 Problema 1 - sir Se genereaz 100 de puncte 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 numerele naturale k , x, a ³i b ³i care s citeasc determine: a sumei tuturor termenilor ³irului care sunt formaµi din cel mult k cifre; a) ultima cifr 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 cu a ³i nu conµin în egal 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 x imediat dup x (de exemplu, dac 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 la dreapta (de exemplu cifra cea mai semnicativ a Pentru rezolvarea cerinµei a) se acord din scrierea sa, de la stânga a num rului 32156 este 3) 30% din punctaj, pentru cerinµa b) 40% din punctaj ³i pentru cerinµa c) 30% din punctaj. 121 CAPITOLUL 10. OJI 2010 Exemple sir.in sir.out 3 45123 3 6 122 Explicaµii 0 Termenii ³irului formaµi ecare din cel mult k 3 cifre sunt: 51234 1, 12, 21, 123, 231, 312. cu 700, pe 3 prima linie a ³ierului Suma lor ind egal 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 10.1.1 Indicaµii de rezolvare Figura 10.1: sirir1 Figura 10.2: sirir2 CAPITOLUL 10. 123 OJI 2010 Figura 10.3: sirir3 Figura 10.4: sirir4 Figura 10.5: sirir5 CAPITOLUL 10. 124 OJI 2010 10.1.2 *Rezolvare detaliat 10.1.3 Cod surs Listing 10.1.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 /* autor prof.Minca Carmen Liceul Teoretic "Ion Neculce" Bucuresti */ #include<fstream> using namespace std; int main() {ofstream g("sir.out"); long x,y,p=1,z; int k,s=0,a,b,i,c,sa; ifstream f("sir.in"); f>>k>>x>>a>>b; s=1; sa=1; for(i=2;i<=k;i++) { s=(s+sa+i)%10; sa=(sa+i)%10; } g<<s<<endl; //cerinta b) y=x; k=1; while(y>9) { k++; y/=10; p=p*10; } if(y==k) { z=0; for(i=1;i<=k+1; i++) z=z*10+i; } else z=(x%p)*10+y; g<<z<<endl; //cerinta c) if(a<b) g<<b-a; else g<<0; f.close(); g.close(); return 0; } Listing 10.1.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 sir.CPP sirana.cpp //sursa 100p prof. Ana Intuneric //CN Ferdinand Bacau #include <fstream> using namespace std; unsigned long s[]={1,12,21,123,231,312, 1234,2341,3412,4123,12345,23451,34512,45123,51234, 123456,234561,345612,456123,561234,612345, 1234567,2345671,3456712,4567123,5671234,6712345,7123456, 12345678,23456781,34567812,45678123,56781234,67812345,78123456,81234567, 123456789,234567891,345678912,456789123,567891234,678912345,789123456, CAPITOLUL 10. 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 125 OJI 2010 891234567,912345678}; unsigned k,a,b,uc,i,nr; unsigned long x; ifstream f("sir.in"); ofstream g("sir.out"); int main() { f>>k>>x>>a>>b; //a) for(i=0;i<k*(k+1)/2;i++) uc=(uc+s[i]%10)%10; g<<uc<<’\n’; //b) i=0; while(s[i]<=x) i++; g<<s[i]<<’\n’; //c) if(a<b)g<<(9-a+1)-(9-b+1); else g<<0; f.close(); g.close(); return 0; } Listing 10.1.3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 // prof.Cristina Sichim // Colegiul National Ferdinand Bacau # include <fstream> # include <math.h> using namespace std; int k,a,b,u,i,c; long x,y,p; int main() { ifstream f("sir.in"); ofstream g("sir.out"); f>>k>>x>>a>>b; //a u=0; for(i=1;i<=k;i++) u=(u+i*(i+1)/2)%10; g<<u<<endl; //b u=0;y=x; while(y){u++;c=y%10; y=y/10;} if(c==u) for(i=1;i<=u+1;i++)y=y*10+i; else { p=pow(10,u-1); y=x%p*10+x/p; } g<<y<<endl; //c c=(b>a)?b-a:0; g<<c; f.close(); g.close(); return 0; SIRcris.CPP CAPITOLUL 10. 43 126 OJI 2010 } Listing 10.1.4: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <fstream> using namespace std; int k,a,b,u,i,n,v[11]; long x; int main() { ifstream f("sir.in"); ofstream g("sir.out"); f>>k>>x>>a>>b; //a u=0; for(i=1;i<=k;i++) u=(u+i*(i+1)/2)%10; g<<u<<endl; //b n=0; while(x){n++;v[n]=x%10;x=x/10;} if(v[n]==n) for(i=1;i<=n+1;i++)g<<i; else { for(i=n-1;i>=1;i--) g<<v[i]; g<<v[n]; } g<<endl; //c u=(b>a)?b-a:0; g<<u; f.close(); g.close(); return 0; } Listing 10.1.5: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 SIRcris2.CPP //prof Dana Marcu - Suceava #include<fstream> using namespace std; ifstream f("sir.in"); ofstream g("sir.out"); int main() { int k,a,b; long x; f>>k>>x>>a>>b; //punctul a) int i,uc=0; uc=(k*(k+1)*(k+2)/6)%10; g<<uc<<"\n"; //punctul b) long aux=x,p=1; int nrcif=0,pc; uc=x%10; while(aux) { nrcif++; p=p*10; SIRcris2.CPP CAPITOLUL 10. 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 127 OJI 2010 aux=aux/10; } p=p/10; if(x>1) { if(nrcif-1==uc) for(i=1;i<=nrcif+1;i++) g<<i; else g<<(x%p)*10+x/p; } else g<<"12"; g<<"\n"; //punctul c) if(b<=a) g<<"0"; else g<<b-a; return 0; } Listing 10.1.6: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 SIRVECT.CPP //autor. prof Carmen Minca - Bucuresti #include <fstream> using namespace std; int main() { long x; int v[10]; int k,i,s=0,a,b; ifstream f("sir.in"); ofstream g("sir.out"); f>>k>>x>>a>>b; for(s=1,i=2;i<=k;i++) s=(s+i*(i+1)/2)%10; g<<s<<endl; k=0; while(x) { k++; v[k]=x%10; x=x/10; } if(v[k]==k) for(i=1;i<=k+1;i++) g<<i; else { v[0]=v[k]; for(i=k-1;i>=0;i--) g<<v[i]; } if(a<b)g<<endl<<b-a; else g<<endl<<0; g.close(); return 0; } 10.2 tren - OJI 2010 Problema 2 - tren 100 de puncte CAPITOLUL 10. 128 OJI 2010 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 va sosi, momentul sosirii, adic (exprimat trenurile. În sosesc T trenuri. Pentru ecare tren din cele T , Rare³ cunoa³te linia L pe care acea zi, în gar ora H ³i minutul M , precum ³i durata de timp S de staµionare în minute). El a decis ca perioada de studiu a celor T trenuri s din cele T ³i s sosirii primului tren în gar se încheie odat înceap cu momentul cu momentul plec rii ultimului tren din cele T . Din sala de a³teptare Rare³ poate vedea cele 2 linii. Rare³ are îns un tren se a De exemplu, dac pe linia 1 la ora 14 21 ³i staµioneaz un tren ajunge în gar trenul va pleca din gar 5 minute atunci la ora 14 26. Astfel, în intervalul de timp 14 21 14 26, Rare³ nu poate vedea ce se întâmpl urm tor, adic o problem : atunci când pe linia 1, el nu poate vedea trenul staµionat în acela³i timp pe linia 2. în gar pe linia 2. Trenul de pe linia 2 va putea vizibil începând cu minutul de la 14 27. Cerinµe determine pentru un num r T de trenuri care trec prin gar Scrieµi un program care s î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; Y (exprimat a durata de timp maxim î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 au staµionat 3 trenuri, iar pe linia 2 au staµionat 5 trenuri, 1 14 20 3 astfel Z 2 14 21 1 ³i va staµiona pân 2 14 45 5 5. La ora 14 20 Rare³ vede trenul care ajunge pe linia 1 la ora 14 23. El nu vede trenul care ajunge pe linia 2 la ora 14 21 ³i pleac la 14 22. El vede trenul care ajunge pe linia 2 la 14 24 pentru c în momentul sosirii nu se a tren pe linia 1. De asemenea, el vede trenul care ajunge la 14 40 pe linia 1, dar nu vede urm toarele 2 trenuri care ajung pe linia 2 întrucât trenul de pe linia 1 pleac la 14 48. Vede ³i ultimul tren de pe linia 2 pentru 1 14 56 1 c 2 14 24 4 1 14 40 8 2 14 41 1 2 14 43 1 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 (determinat de trenul care pleac sose³te la 14 40). ind de 11 minute la 14 28 ³i urm torul tren care CAPITOLUL 10. 129 OJI 2010 Timp maxim de executare/test: 1.0 secunde 10.2.1 Indicaµii de rezolvare prof. Cristina Sichim, Colegiul National Ferdinand- Bacau a) Solutia cu vectori retine in vectorul g starea fiecarui minut de pe parcursul un In fiecare moment Rares vede cel mult un tren. Vectorul v, retine starea fiecarui tren care a trecut prin gara. # include <fstream.h> ifstream fi("tren.in"); ofstream fo("tren.out"); int x,t,y,z,u,t1,l,h,m,s,i,j,vine,pleaca,g[1441],v[101],inc=1441,sf; void main() { fi>>t; for(i=1;i<=t;i++) { fi>>l>>h>>m>>s; vine=h*60+m;pleaca=vine+s; if(i==1)inc=vine; if(sf<pleaca) sf=pleaca; if(l==1) { t1++; for(j=vine;j<=pleaca;j++)g[j]=i;} else for(j=vine;j<=pleaca;j++)if(g[j]==0)g[j]=i; //trenul de pe linia 2 este vizibil numai daca nu avem tren pe linia 1 } z=(t1>t-t1)?t1:t-t1; //numarul maxim de trenuri de pe o linie y=0; for(i=inc;i<=sf;i++) { v[g[i]]=1; //trenul care se afla in momentul i in gara este vizibil if(g[i]==0) u++; //u=numarul de minute consecutive in care //ambele linii sunt libere else { if(u>y)y=u; u=0; } } x=0; for(i=1;i<=t;i++) x=x+v[i]; fo<<z<<’ ’<<x<<’ ’<<y; fi.close();fo.close(); } b) Solutia fara vectori memoreaza in t1 numarul de trenuri care ajung pe linia 1 si actualizeaza pentru fiecare tren sosit valorile x, y si z. Un tren care ajunge pe linia 1 va fi intotdeauna vizibil. Un tren care ajunge pe linia 2 va fi vizibil daca in timpul stationarii exista cel putin un minut in care linia 1 nu este ocupat 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 10. 130 OJI 2010 if(l==1) t1++,p1=u; else p2=u; for(i=2;i<=t;i++) { f>>l>>h>>m>>sta; s=h*60+m; p=s+sta; //s-momentul sosirii, p-momentul plecarii if(s-u>y) y=s-u; if(s>p1+1 && am2==1 && p2>p1) x++,am2=0; // vad trenul care se afla acum pe linia 2 if(l==1) x++,t1++,p1=p; else if (s>p1) x++,am2=0,p2=p; // vine un tren pe linia 2 si linia 1 este libera else if (p>p1) p2=p,am2=1; // vine un tren pe linia 2 si linia 1 este ocupata u=(p1>p2)?p1:p2; } if(am2)x++; z=(t1>t-t1)?t1:t-t1; if(y)y--; g<<z<<’ ’<<x<<’ ’<<y; f.close();g.close(); } 10.2.2 *Rezolvare detaliat 10.2.3 Cod surs Listing 10.2.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 Ana.CPP #include <fstream> #include<math.h> using namespace std; int timp[1382]; int t,i,j,l,h,m,s,x,y,z,nrt1,nrt2,ts,tp,tmp; ifstream f("tren.in"); ofstream g("tren.out"); int main() { f>>t; for(i=1;i<=t;i++) { f>>l>>h>>m>>s; if(l==1) nrt1++; else nrt2++; ts=h*60+m;tp=ts+s; for(j=ts;j<=tp;j++) if(l==1) timp[j]=i; else if(l==2 && timp[j]==0) timp[j]=i; } //b) for(i=1;i<=1381;i++) if(timp[i]!=timp[i-1] && timp[i]!=0) x++; //c) i=0;while(timp[i]==0) i++; for(;i<=1381;i++) if(timp[i]==0) tmp++; else { CAPITOLUL 10. 36 37 38 39 40 41 42 43 44 131 OJI 2010 if(tmp>y) y=tmp; tmp=0; } z=(nrt1+nrt2+abs(nrt1-nrt2))/2; g<<z<<" "<<x<<" "<<y; f.close(); g.close(); return 0; } Listing 10.2.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 Carmen.CPP #include <fstream> using namespace std; ifstream fi("tren.in"); ofstream fo("tren.out"); long lin[1441]; int main() { long t,z,x,y,h,m,s,i,os,op,l; fi>>t; long n1,n2,j,pi=1441,pf=0; n1=0; n2=0; for(i=1;i<=t;i++) { fi>>l>>h>>m>>s; os=h*60+m; op=os+s; if(pi>os)pi=os; if(pf<op)pf=op; if(l==1)n1++; else n2++; for(j=os;j<=op;j++) { if(l==1) lin[j]=lin[j]+n1; else lin[j]=n2*1000+lin[j]; } } z=n1; if(z<n2) z=n2; y=0; x=0; long val=lin[pi],t1,t2; unsigned long d=0; t1=t2=0; i=pi; while(i<=pf) { if(lin[i]==0){i++;d++;} else { val=lin[i]; if(val%1000) { if(t1!=val%1000) { t1=val%1000; x++; } if((lin[i]%1000==val%1000)&&(i<=pf))i++; } else { if(t2!=val/1000) { t2=val/1000; x++; } if((lin[i]/1000==val/1000)&&(val%1000==0)&&(i<=pf))i++; } if(d>y)y=d; d=0; } CAPITOLUL 10. 64 65 66 67 68 69 70 71 72 132 OJI 2010 } fo<<z<<’ ’<<x<<’ ’<<y; fo.close(); fi.close(); return 0; } Listing 10.2.3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 # include <fstream> using namespace std; 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; int main() { f>>t; f>>l>>h>>m>>sta; u=h*60+m+sta; 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; if(s-u>y) y=s-u; if(s>p1+1 && am2==1 && p2>p1) x++,am2=0; if(l==1) x++,t1++,p1=p; else if (s>p1) x++,am2=0,p2=p; else if (p>p1) p2=p,am2=1; u=(p1>p2)?p1:p2; } if(am2)x++; z=(t1>t-t1)?t1:t-t1; if(y)y--; g<<z<<’ ’<<x<<’ ’<<y; f.close(); g.close(); return 0; } Listing 10.2.4: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Cris1.CPP Cris2.CPP # include <fstream> using namespace std; 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; int 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; } CAPITOLUL 10. 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 133 OJI 2010 z=(t1>t-t1) ? t1:t-t1; y=0; for(i=inc;i<=sf;i++) { v[g[i]]=1; if(g[i]==0) u++; else { if(u>y)y=u; u=0; } } x=0; for(i=1;i<=t;i++) x=x+v[i]; fo<<z<<’ ’<<x<<’ ’<<y; fi.close(); fo.close(); return 0; } Listing 10.2.5: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 # include <fstream> using namespace std; ifstream f("tren.in"); ofstream g("tren.out"); int x,t,y,z,u,t1,l,h,m,s,i,j,vine,pleaca,l1[1441],l2[1441],v[101],inc=1441,sf; int main() { f>>t; for(i=1;i<=t;i++) { f>>l>>h>>m>>s; vine=h*60+m;pleaca=vine+s; if(inc>vine) inc=vine; if(sf<pleaca) sf=pleaca; if(l==1) { t1++; for(j=vine;j<=pleaca;j++)l1[j]=i;} else for(j=vine;j<=pleaca;j++)l2[j]=i; } z=(t1>t-t1) ? t1 : t-t1; y=0; for(i=inc;i<=sf;i++) { v[l1[i]]=1; if(l1[i]==0)v[l2[i]]=1; if(l1[i]+l2[i]==0) u++; else { if(u>y)y=u; u=0; } } x=0; for(i=1;i<=t;i++) x=x+v[i]; g<<z<<’ ’<<x<<’ ’<<y; f.close(); g.close(); return 0; } Listing 10.2.6: 1 2 3 Cris3.CPP #include<fstream> using namespace std; Dana.cpp CAPITOLUL 10. 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 OJI 2010 ifstream f("tren.in"); ofstream g("tren.out"); int t,l,h,m,s; int nr1,nr2,z,gasit,ultim; int tp,x; int maxx,y,timpc,poz; int main() { int i; f>>t; for(i=1;i<=t;i++) { f>>l>>h>>m>>s; /*Daca exista un tren pe linia 2, iar pe linia 1 sosesc trenuri la interval de o secunda unul de altul, trenul de pe linia 2 nu se vede si deci va fi scazut din numaratoare (o singura data!: ultim=tp;) ultim reprezinta timpul de plecare din statie al trenului de pe linia 2*/ if(gasit) { gasit=0; x--; ultim=tp; } if(l==1) { nr1++; x++; if(ultim>h*60+m && h*60+m-tp==1 && i>1) gasit=1; tp=h*60+m+s; } else { nr2++; if(h*60+m>tp||h*60+m+s>tp) { x++; ultim=h*60+m+s; } } if(h*60+m>maxx) { timpc=h*60+m-maxx; maxx=h*60+m+s+1; if(timpc>y && i>1) y=timpc; } else if(h*60+m+s>maxx) maxx=h*60+m+s+1; } if(nr1>nr2) z=nr1; else z=nr2; g<<z<<" "<<x<<" "<<y; return 0; } 134 Partea II ONI - Olimpiada naµional de informatic 135 Capitolul 11 ONI 2019 11.1 Copii Problema 1 - Copii Iliuµ 100 de puncte ³i Pandele au înv µat la ³coal fraµi exerseaz scrie pe tabl operaµii aritmetice cu numere naturale. operaµiile folosindu-se de o tabl . Iliuµ spune un num r natural rezultatul înmulµirii tututor numerelor naturale de la 1 la Astfel cei doi X, iar Pandele X. Glumeµ, Iliuµ ³terge cifrele egale cu 0 de la nalul num rului scris de Pandele. Ca s Y ³i îi cere lui Iliuµ s determine un Z care este cel mai mare divizor al lui Y având un num r impar de divizori. îl ierte, Pandele spune ³i el un num r natural num r natural Cerinµe Cunoscându-se numerele spuse de copii, scrieµi un program care rezolv 1) a³eaz ultimele 0 de la nalul acestuia; 2) a³eaz num rul urm toarele cerinµe: K cifre ale produsului calculat de Pandele, dup ³tergerea cifrelor egale cu Z cu semnicaµia de mai sus ³i num rul de divizori ai acestuia. Date de intrare copii.in conµine pe prima linie num rul C, care reprezint num rul cerinµei ³i poate ³ierul conµine pe a doua linie num rul X, iar pe cea de a treia linie num rul K. Pentru a doua cerinµ ³ierul conµine pe a doua linie num rul Y. Fi³ierul avea doar valorile 1 sau 2. Pentru prima cerinµ 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 & X & 106 12 a 1 & Y & 10 a 1 & K & 9 a 1 a Num rul r mas dup ³tergerea zerourilor de la nalul produsului are cel puµin a Pentru rezolvarea primei cerinµe se acord 40 de puncte; a Pentru rezolvarea celei de a doua cerinµe se acord Exemple 136 60 de puncte. K cifre; CAPITOLUL 11. 137 ONI 2019 copii.in copii.out 1 016 Explicaµii 01600. Produsul 1*2*3*4*5*6*7*8*9*10*11*12 = 4790 12 Dup 3 ³tergerea zerourilor de la nalul produsului, ultimele 3 cifre sunt 016. 2 14641 5 Cel mai mare divizor al lui 14641 care are un num r 14641 impar de divizori este chiar 14641. 1 813433856 01600. Produsul 1*2*3*4*5*6*7*8*9*10*11*12 = 4790 723432 Dup 9 ³tergerea zerourilor de la nalul produsului, ultimele 9 cifre sunt 813433856 2 286597481104 105 573194962208 Cel mai mare divizor cu un num r impar de divizori este 286597481104 care are 105 divizori Timp maxim de executare/test: 0.2 secunde Memorie: total 64MB din care pentru stiv 64MB Dimensiune maxim a sursei: 15KB Sursa: copii.cpp, copii.c sau copii.pas va salvat în folderul care are drept nume ID-ul t u. 11.1.1 Indicaµii de rezolvare Prof. Lica Daniela, Centrul Judeµean de Excelenµ 1) Pentru prima cerinµ Prahova - Ploie³ti se vor contoriza factorii de 5 din descompunerea numerelor de la 1 la N. Fie Nr5 acest num r. Se vor determina ultimele K cifre ale produsului numerelor, ignorând factorii de 2 ³i de 5, în num r egal cu Nr5. 2) Num rul Z cerut este p trat perfect, deci toµi factorii primi ai acestuia apar la puteri pare. Se va descompune Y în factori primi ³i se va calcul num rul Z, derminând produsul factorilor din descompunerea lui Y la cea mai mare putere par mai mic sau egal lui Y. 11.1.2 Rezolvare detaliat Listing 11.1.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include<iostream> #include<fstream> // cout // fstream using namespace std; ifstream fin("copii.in"); ofstream fout("copii.out"); int C; // nr cerinta void rezolva1() { } void rezolva2() { } int main() { fin>>C; cout<<"C = "<<C<<"\n"; if(C==1) {rezolva1(); return 0;} if(C==2) {rezolva2(); return 0;} return 0; } Copii - Etapa nr. 0 cu cea din descompunerea CAPITOLUL 11. 138 ONI 2019 Listing 11.1.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 #include<iostream> #include<fstream> Copii - Etapa nr. 1 // cout // fstream using namespace std; ifstream fin("copii.in"); ofstream fout("copii.out"); int C; int X, K; long long Y; // nr cerinta // pentru C=1 ... (K cifre) <=9 ...10^9 ... incape pe int ... // pentru C=2 ... atentie ... Y <= 10^12 ... !!! int k10; // k10 = 10^k ... pentru ultimele k cifre (fac modulo k10) int nr5; int nr2; // nr factorilor de 5 pe care ii scot din 1*2*3*...*X (10=2*5) // nr factorilor de 2 pe care ii scot din X (nr2 > nr5 ... sigur!) long long p1x; // // produs de la 1 la x ... pastrez numai (p1x % k10) ...X*10^k = = 10^6*10^9 = 10^15 = long long ... !!! void rezolva1() { fin>>X; fin>>K; cout<<"X = "<<X<<"\n"; cout<<"K = "<<K<<"\n"; // atentie la X=1 sau X=2 sau X=3 ... !!! k10=1; for(int i=1; i<=K; i++) k10=k10*10; // k10 *= 10; cout<<"\n k10 = "<<k10<<"\n\n"; nr5=0; for(int i=1; i<=X; i++) // pentru 1*2*3*...*X (nu prea are rost de la 1 ...) { int ci=i; // copia lui i ... ca sa nu il stric pe i ... while(ci%5==0) // atentrie la cele doua = uri !!! { nr5++; ci=ci/5; // ci /= 5; } cout<<i<<" : nr5 = "<<nr5<<"\n"; } cout<<"\n--- nr5 = "<<nr5<<" ---\n\n"; p1x=1LL; // atentie la 1 pentru long long ... !!! nr2=nr5; for(int i=2; i<=X; i++) { int ci=i; // copia lui i ... ca sa nu il stric pe i ... while((nr2>0) && (ci%2==0)) // scot 2-urile { ci=ci/2; // scot un 2 nr2--; } while((nr5>0) && (ci%5==0)) // scot 5-urile { ci=ci/5; // scot un 2 nr5--; } p1x = p1x * ci; cout<<i<<" : p1x = "<<p1x; p1x = p1x % k10; cout<<"\t = "<<p1x<<"\n"; } cout<<"\n--- p1x = "<<p1x<<" ---\n\n"; // de pus 0-uri in stanga ... 16 --> 016 ... la test1 CAPITOLUL 11. 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 139 ONI 2019 int ncp1x=0; // nr cifre p1x int cp1x=p1x; // copie a lui p1x while(cp1x>0) { ncp1x++; cp1x=cp1x/10; } // scriu (K - ncp1x) zerouri la inceputul rezultatului afisat for(int i=1; i<=(K-ncp1x); i++) { cout<<"0"; } cout<<p1x<<’\n’; } void rezolva2() { } int main() { fin>>C; cout<<"C = "<<C<<"\n"; if(C==1) {rezolva1(); return 0;} if(C==2) {rezolva2(); return 0;} return 0; } Listing 11.1.3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include<iostream> // cout #include<fstream> // fstream #include<stdio.h> // getchar(); infinit" ... !!! Copii - Etapa nr. 2 // getc(stdin); // in while ... poate sa cicleze "la using namespace std; ifstream fin("copii.in"); ofstream fout("copii.out"); int C; int X, K; // nr cerinta // pentru C=1 ... (K cifre) <=9 ...10^9 ... incape pe int ... long long Y; // pentru C=2 ... atentie ... Y <= 10^12 ... !!! long long Z; // Z divizor <= Y <= 10^12 ... ==> long long long long ndivz;// nr divizori ai lui Z int k10; // k10 = 10^k ... pentru ultimele k cifre (fac modulo k10) int nr5; int nr2; // nr factorilor de 5 pe care ii scot din 1*2*3*...*X (10=2*5) // nr factorilor de 2 pe care ii scot din X (nr2 > nr5 ... sigur!) long long p1x; // // produs de la 1 la x ... pastrez numai (p1x % k10) ...X*10^k = = 10^6*10^9 = 10^15 = long long ... !!! void rezolva1() { fin>>X; fin>>K; cout<<"X = "<<X<<"\n"; cout<<"K = "<<K<<"\n"; // atentie la X=1 sau X=2 sau X=3 ... !!! k10=1; for(int i=1; i<=K; i++) k10=k10*10; // k10 *= 10; cout<<"\n k10 = "<<k10<<"\n\n"; nr5=0; for(int i=1; i<=X; i++) // pentru 1*2*3*...*X (nu prea are rost de la 1 ... dar...) { int ci=i; // copia lui i ... ca sa nu il stric pe i ... CAPITOLUL 11. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 ONI 2019 140 while(ci%5==0) // atentrie la cele doua = uri !!! { nr5++; ci=ci/5; // ci /= 5; } cout<<i<<" : nr5 = "<<nr5<<"\n"; } cout<<"\n--- nr5 = "<<nr5<<" ---\n\n"; p1x=1LL; // atentie la 1 pentru long long ... !!! nr2=nr5; for(int i=2; i<=X; i++) { int ci=i; // copia lui i ... ca sa nu il stric pe i ... while((nr2>0) && (ci%2==0)) // scot 2-urile { ci=ci/2; // scot un 2 nr2--; } while((nr5>0) && (ci%5==0)) // scot 5-urile { ci=ci/5; // scot un 2 nr5--; } p1x = p1x * ci; cout<<i<<" : p1x = "<<p1x; p1x = p1x % k10; cout<<"\t = "<<p1x<<"\n"; } cout<<"\n--- p1x = "<<p1x<<" ---\n\n"; // de pus 0-uri in stanga ... 16 --> 016 ... la test1 int ncp1x=0; // nr cifre p1x int cp1x=p1x; // copie a lui p1x while(cp1x>0) { ncp1x++; cp1x=cp1x/10; } // scriu (K - ncp1x) zerouri la inceputul rezultatului afisat for(int i=1; i<=(K-ncp1x); i++) { cout<<"0"; } cout<<p1x<<’\n’; } void rezolva2() { fin>>Y; //Y=1LL*2*2*3*3*3*3*5*7*7*7; cout<<"Y = "<<Y<<"\n\n"; // atentie la Y=1 sau Y=2 sau Y=3 ... !!! //getchar(); // Z = f1^e1 * f2^e2 * ... fn^en unde fi=factor_i si ei=exponent_i // nr_divizori(Z) = (1+e1)*(1+e2)*...*(1+en) = impar // ==> toate parantezele sunt impare // ==> toti exponentii sunt pari // ==> Z = patrat perfect // Daca Y=patrat perfect ==> sa ia Z = Y // Daca Y NU ESTE patrat perfect ==> se ia CEL MAI MARE patrat perfect // adica, se ia fiecare factor fi la cea mai mare putere para la care apare ... Z=1LL; ndivz=1LL; // pentru produsul factorilor // nr divizorilor lui Z CAPITOLUL 11. 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 141 ONI 2019 int fp; // factor prim de incercat: 2, 3, 5, 7, 9(?), 11, 13, 15(?), 17, 19, 21(?), ... int nfp; // de cate ori apare factorul prim fp long long cy=Y; // copia lui Y ... atentie la ... long long ... !!! fp=2; nfp=0; while((cy > 0) && (cy%fp == 0)) // 2-urile ... { nfp++; cy=cy/fp; //getchar(); } if(nfp>0) cout<<"fp = "<<fp<<" nfp = "<<nfp<<"\n"; //getchar(); if(nfp%2==1) nfp--; // sa apara de nr par de ori ... for(int i=1; i<=nfp; i++) Z = Z*fp; ndivz=ndivz*(1+nfp); cout<<"fp = "<<fp<<" nfp = "<<nfp<<" Z = "<<Z<< " ndivz = "<<ndivz<<" cy = "<<cy<<"\n\n"; fp=3; while(fp*fp <= cy) { // fp=2; // scapa in bucla infinita ... !!! nfp=0; while((cy > 0) && (cy%fp == 0)) // fp-urile ... { nfp++; cy=cy/fp; //getchar(); } if(nfp>0) cout<<"fp = "<<fp<<" nfp = "<<nfp<<"\n"; if(nfp%2==1) nfp--; // sa apara de nr par de ori ... for(int i=1; i<=nfp; i++) Z = Z*fp; ndivz=ndivz*(1LL+nfp); if(nfp>0) cout<<"fp = "<<fp<<" nfp = "<<nfp<<" Z = "<<Z<< " ndivz = "<<ndivz<<" cy = "<<cy<<"\n\n"; fp=fp+2; //getchar(); } cout<<"\n --- cy = "<<cy<<" --- \n\n"; cout<<Z<<’ ’<<ndivz<<’\n’; } int main() { fin>>C; cout<<"C = "<<C<<"\n"; if(C==1) {rezolva1(); return 0;} if(C==2) {rezolva2(); return 0;} return 0; } 11.1.3 Cod surs Listing 11.1.4: 1 // ce a ramas ... #include <fstream> copii_cpp.cpp CAPITOLUL 11. 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 ONI 2019 #include <algorithm> #include <cassert> using namespace std; long long prim[1000010]; int expp[1000010], p = 0; int main () { ifstream cin ("copii.in"); ofstream cout ("copii.out"); int c, k; long long x; cin >> c >> x; assert (c == 1 || c == 2); if (c == 1) { cin >> k; assert (1LL <= x && x <= 1000000LL); assert (1 <= k && k <= 9); int m = 1; for (int i = 1; i <= k; ++i) m *= 10; assert (m > 0); int nr2 = 0, nr5 = 0; for (int i = 1; i <= x; ++i) { int ci = i; while (ci % 5 == 0) { ++nr5; ci /= 5; } } nr2 = nr5; long long prod = 1LL; for (int i = 1; i <= x; ++i) { int ci = i; while (ci % 2 == 0 && nr2 > 0) { --nr2; ci /= 2; } while (ci % 5 == 0 && nr5 > 0) { --nr5; ci /= 5; } prod *= 1LL * ci; prod %= 1LL * m; } int aux = prod, p = 0; while (aux > 0) { ++p; aux /= 10; } for (int i = p + 1; i <= k; ++i) cout << 0; 142 CAPITOLUL 11. 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 143 ONI 2019 cout << prod << ’\n’; } else { assert (1LL <= x && x <= 1000000000000LL); long long i = 2LL; while (i * i <= x) { if (x % i == 0LL) { prim[++p] = i; while (x % i == 0) { x /= i; ++expp[p]; } } i += 1LL; } if (x > 1LL) { prim[++p] = x; expp[p] = 1; } long long divizor = 1LL, numar = 1LL; for (int i = 1; i <= p; ++i) { if (expp[i] % 2 == 1) --expp[i]; for (int j = 1; j <= expp[i]; ++j) divizor *= prim[i]; numar *= 1LL * (1 + expp[i]); } cout << divizor << " " << numar << ’\n’; } return 0; } 11.2 Numere Problema 2 - Numere 100 de puncte Într-o zi, Ioana a scris toate numerele naturale de - num rul format din primele dou - a treia cifr N cifre ecare îndeplinind, simultan, condiµiile: cifre este p trat perfect; 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 N ³i X, scrieµi un program care determin : 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 Fi³ierul de intrare numere.in conµine pe prima linie un num r natural C. Num rul C poate avea doar valorile 1 sau 2. Pe a doua linie se a , în cazul primei cerinµe, num rul N, iar în cazul celei de-a doua cerinµe, num rul X. Cunoscându-se numerele 1) câte numere de CAPITOLUL 11. 144 ONI 2019 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 & X & 20 000 000 a 100 a Pentru rezolvarea primei cerinµe se acord cerinµe se acord 30 de puncte, iar pentru rezolvarea celei de a doua 70 de puncte. Exemple numere.in numere.out Explicaµii 1 45 Numerele de patru cifre, scrise de Ioana, sunt: 4 1630, 1632, 1634, 1636, 1638, 1650, 1652, 1654, 1656, 1658, 1670, 1672, 1674, 1676, 1678, 2521, 2523, 2525, 2527, 2529, 3630, 3632, 3634, 3636, 3638, 3650, 3652, 3654, 3656, 3658, 3670, 3672, 3674, 3676, 3678, 4921, 4923, 4925, 4927, 4929, 8121, 8123, 8125, 8127, 8129. 2 167 Cel mai apropiat num r de 200 este 167 (numerele de 200 trei cifre, scrise de Ioana, sunt: 163, 165, 167, 252, 363, 365, 367, 492, 812). Timp maxim de executare/test: 0.5 secunde Memorie: total 2MB din care pentru stiv 2MB Dimensiune maxim a sursei: 15KB Sursa: numere.cpp, numere.c sau numere.pas va salvat în folderul care are drept nume ID-ul t u. 11.2.1 Indicaµii de rezolvare Prof. Ana-Maria Ari³anu, Colegiul Naµional Mircea cel B trân, Rm. Vâlcea a) Numerele ce respect condiµiile din enunµ pot începe cu 16, 25, 36, 49 sau 81 Caz 1. Dac încep cu 16 sau 36 a treia cifra poate 3, 5 sau7. Caz 2. Dac încep cu 25, 49 sau 81 a treia cifra poate doar 2 Începând cu a patra cifra avem câte 5 posibilit µi, respectiv 0, 2, 4, 6 sau 8 (pentru cazul 1) ³i 1, 3, 5, 7 sau 9 (pentru cazul 2) Num rul de numere de N cifre care respect condiµiile din enunµ este: 2 3 5 n 3 3 5 n 3 b) Fie 9 5 n 3 k num rul de cifre ale num rului X. 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... Construim Determin m cel mai mic num r, mai mare decât x ce respect 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 exist ). Acest num r nu poate mai mic decât Dintre cele dou xmin. numere determinate se a³eaz condiµiile din enunµ (dac condiµiile din enunµ (dac cel mai aproape de X. CAPITOLUL 11. 11.2.2 145 ONI 2019 Rezolvare detaliat Atenµie la enunµ: ... cel mai apropiat num r de X, diferit de X, ... Exemplu pentru 3 cifre: zona16 100 163 165 zona25 167 252 zona36 363 365 zona49 zona81 492 812 367 999 Figura 11.1: Numere cu 3 cifre X este în stînga zonei zona16 (de exemplu X 150) atunci rezultatul este 163. 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. Dac Dac Exemplu pentru 4 cifre: zona16 1000 1630 16.. zona25 1678 252. zona36 3630 36.. zona49 zona81 492. 812. zona49 zona81 492.. 812.. 3678 9999 Figura 11.2: Numere cu 4 cifre Pentru nc r2521, 2523, 2525, 2527, 2529x. 4 zona zona25 (celelalte zone sunt deja precizate în enunµul problemei). Exemplu pentru 5 cifre: zona16 10000 16301 16... zona25 16789 252.. zona36 36301 36... 36789 99999 Figura 11.3: Numere cu 5 cifre Pentru nc 5 zona zona25 r25210, 25212, 25214, 25216, 25218, 25230, 25232, 25234, 25236, 25238, 25250, 25252, 25254, 25256, 25258, 25270, 25272, 25274, 25276, 25278, 25290, 25292, 25294, 25296, 25298x. Celelalte zone NU mai sunt precizate în enunµul problemei dar sunt u³or de intuit! 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: (11.2.1) Pentru CAPITOLUL 11. 1 1 1 1 1 1 1 1 1 1 2 p trat 6 6 6 6 6 6 6 6 6 146 ONI 2019 3 prim 3 3 3 5 5 5 7 7 7 4 5 6 paritati diferite 7 8 0 1 0 1 0 ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 4 5 6 7 8 8 0 8 0 8 9 1 8 0 9 1 8 0 9 8 9 1 9 1 9 8 0 8 0 8 Pentru 25: 1 2 2 2 2 p trat 5 5 5 3 prim 2 2 2 1 0 ... ... 3 4 5 9 paritati diferite 8 1 0 1 ... ... ... 6 7 8 9 8 9 Pentru 36: 1 3 3 3 3 3 3 3 3 3 2 p trat 6 6 6 6 6 6 6 6 6 prim 3 3 3 5 5 5 7 7 7 paritati diferite 0 1 0 1 0 ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 4 5 6 7 8 8 0 8 0 8 9 1 8 0 9 1 8 0 9 8 9 1 9 1 9 8 0 8 0 8 Pentru 49: 1 4 4 4 2 p trat 9 9 9 3 prim 2 2 2 1 0 ... ... 3 4 5 9 paritati diferite 8 1 0 1 ... ... ... 6 7 8 9 8 9 Pentru 81: 1 8 8 8 2 p trat 1 1 1 prim 2 2 2 1 0 ... ... 9 paritati diferite 8 Pentru 81 puµin mai detaliat la mijlocul zonei: 1 0 1 ... ... ... 9 8 9 CAPITOLUL 11. 1 2 p trat 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 147 ONI 2019 3 4 prim 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 5 6 7 paritati diferite 8 1 0 1 0 1 ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 5 5 5 5 5 5 5 0 0 0 0 0 0 0 5 5 5 5 5 5 5 1 1 1 1 1 1 1 8 8 8 8 8 8 8 9 0 0 0 0 0 2 2 9 9 9 9 9 9 9 8 1 3 5 7 9 1 3 6 6 8 8 8 8 8 9 7 9 1 3 5 7 9 8 9 Mi³carea contorului electric sau a kilometrajului de la ma³in ! Când se m re³te valoarea cu o unitate: 1. Se m re³te cu o unitate ultima cifr 2. Dac se caut nu se poate (pentru c permis pe poziµia vericat ), spre stânga prima poziµie care se poate m ri ³i se pun pe 0 toate poziµiile prin care s-a trecut. (0 este cea mai mic Când se Dac cifr permis pe poziµia vericat ). mic³oreaz valoarea cu o unitate: 1. Se mic³oreaz 2. (cea din dreapta). este 9 = cea mai mare cifr cu o unitate ultima cifr nu se poate (pentru c (cea din dreapta). este 0), se caut spre stânga prima poziµie care se poate mic³ora ³i se pun pe 9 toate poziµiile prin care s-a trecut. (9 este cea mai mare cifr permis pe poziµia vericat ). Un exemplu pentru nc 1 1 2 p trat 3 4 prim 5 6 paritati diferite 7 2 7 0 7 0 ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 1 1 3 4 4 8 8 8 5 7 (num rul cifrelor): 6 6 6 4 9 1 1 2 Un exemplu pentru nc 3 3 7 4 2 2 2 0 0 0 8 4 1 9 9 0 0 1 9 4 0 8 9 0 7 (num rul cifrelor): 9 0 8 4 1 9 0 0 9 1 9 min16 = min163 max36 = max367 4 0 8 0 0 min49 = min492 max81 = max812 CAPITOLUL 11. 1 148 ONI 2019 2 p trat 3 4 prim 5 6 7 paritati diferite ... ... ... ... ... ... ... ... ... ... ... ... ... ... 3 6 3 3 6 6 3 3 5 0 8 0 1 9 1 0 8 0 1 9 1 ... ... ... ... ... ... ... 3 3 6 6 5 5 4 4 0 1 0 0 0 1 ... ... ... ... ... ... ... 3 3 6 6 ... ... 5 7 8 0 ... ... 3 4 9 1 8 0 9 1 ... ... ... 5 6 7 min363 max363 min365 err! max365 min367 Celalalt vecin este: 1 3 3 2 p trat 6 6 prim 5 5 2 4 paritati diferite 9 1 8 0 9 1 6 7 Evident, num rul este între cei doi vecini: 1 2 p trat ... ... 3 3 3 6 6 6 ... 3 ... ... 5 5 5 ... Un exemplu pentru nc 1 4 prim 2 p trat 3 5 paritati diferite ... 2 4 4 ... ... 9 0 1 ... ... 8 0 0 ... 9 0 1 ... ... 6 7 7 (num rul cifrelor): 4 prim 5 paritati diferite ... ... ... ... ... ... ... ... ... ... ... ... ... ... 3 6 3 3 6 6 3 3 5 0 8 0 1 9 1 0 8 0 1 9 1 ... ... ... ... ... ... ... ... ... ... ... ... ... ... 3 3 6 6 3 3 6 6 ... ... 5 5 5 7 4 4 8 0 ... ... 3 4 9 9 9 1 8 9 8 0 9 0 9 1 ... ... ... 5 6 7 Celalalt vecin este: 1 3 3 2 p trat 6 6 prim 5 5 err! 4 6 paritati diferite 9 1 Evident, numarul este intre cei doi vecini. 8 0 9 1 min363 max363 min365 err! max365 min367 CAPITOLUL 11. 1 2 3 p trat ... se realizeaz 2. dac 6 ... 4 4 6 ... În nal se cristalizeaz 1. dac ... 5 5 5 ... 5 7 paritati diferite ... 6 6 6 ... 4 prim ... 3 3 3 149 ONI 2019 ... 9 9 1 ... 8 9 0 ... ... ... 9 0 1 err! ... urm toarea idee de rezolvare: num rul este între grupuri se determin ³i se a³eaz soluµia, v1 sau v2, pentru care min(nr-v1, v2-nr) unde v1 = maxGrupStanga ³i v2 = minGrupDreapta num rul este într-un grup 2a. se determin unul dintre cei mai apropiaµi vecini (v1 = mai mic sau v2 = mai mare, decât num rul) 2b. se determin cel lalt vecin al num rului (succesor sau predecesor, în secvenµa numerelor valabile) 2c. se a³eaz Obs. soluµia, v1 sau v2, pentru care se realizeaz min(nr-v1, v2-nr) Cei mai experimentaµi pot folosi aceste idei ³i pot obµine un algoritm apropiat de cei prezentaµi ocial! Adic , 1. se determin poziµia eronat 2. se construie³te elementul corect î n secvenµ din poziµia eronat ) sau mai mare (dac 3. se completeaz cu ce trebuie ca s mai mic (dac se poate mic³ora acea valoare nu se poate ...) e cât mai mare/mic ... în funcµie de alegerea facut 2. 4. se determin succesorul/predecesorul 5. se determin soluµia Structura general ³i rezolvarea primei cerinµe Listing 11.2.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include<iostream> #include<fstream> Numere - Etapa nr. 0 // cout ... afisari pe ecran ... !!! // fstream using namespace std; ifstream fin("numere.in"); ofstream fout("numere.out"); int C; int N; int X; // 20.000.000 incape pe "int" int nr3c[9] = { 163, 165, 167, 252, 363, 365, 367, 492, 812 }; long long rez1=9; // unsigned long long ... este mai OK! void rezolva1() { fin>>N; rez1=9LL; for(int i=1; i<=min(N-3,28-3); i++)// N=28 este ultimul care este ok rez1=rez1*5; if(N==29) // trebuie si ultima inmultire cu 5 ... !!! { int v[21]; // vector cu cifrele rezultatului int i; // variabila de lucru ... trebuie si in afara for-ului int poz=-1; // pozitia in vectorul cifrelor lui rez1 while(rez1>0L) { poz++; v[poz]=rez1%10; rez1=rez1/10; } la CAPITOLUL 11. 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 150 ONI 2019 // inmultirea rez*5 int t=0; // cifra de transport ... la inmultire for(i=0; i<=poz; i++) { int cifra=v[i]*5+t; v[i]=cifra%10; t=cifra/10; } if(t>0) { v[i]=t; poz++; } for(i=poz; i>=0; i--) fout<<v[i]; fout<<’\n’; } else fout<<rez1<<’\n’; } void rezolva2() { } int main() { fin>>C; if(C==1) rezolva1(); if(C==2) rezolva2(); return 0; } Variabile globale pentru cerinµa 2 Listing 11.2.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int C; int N; int X; Numere - Etapa nr. 1 // 20.000.000 incape pe "int" int nr3c[9] = { 163, 165, 167, 252, 363, 365, 367, 492, 812 }; long long rez1=9; int rez2, rez2min, rez2max; int vcifx[9]; int vcifxs[9]; int vcifxd[9]; // unsigned long long ... este mai OK! // solutie pentru Cerinta 2 // indici 0, 1, ..., 8 ... vcifx[8] EROARE la ncx=8 ... // nr mai mic decat X (in stanga) ... predecesor // nr mai mare decat X (in dreapta) ... succesor int ncx; int pozincorecta; int x123; int x12; int x3; int x2; // nr cifre in X // pozitia ... cu cifra incorecta // primele 3 cifre // primele 2 cifre // cifra x3 // cifra x2 222 Listing 11.2.3: 1 2 3 4 5 6 7 8 9 10 11 Numere - Etapa nr. 2 void rezolva2() { fin>>X; nrcifrex(X); vcifrex(X); x123=X; for(int i=ncx; i>=4; i--) x123=x123/10; x12=x123/10; x3=x123%10; CAPITOLUL 11. 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 151 ONI 2019 calcpozincorecta(); if(pozincorecta>ncx) // X este OK ... { rez2=X; // ... trebuie sa fie DIFERIT de X ... !!! int x123min=f123min(x123); int x123max=f123max(x123); if(X < x123max) succesorX(); if(X > x123min) predecesorX(); // vcifxd[] // vcifxs[] rez2min=rez2max=0; for(int i=1; i<=ncx; i++) { rez2min=rez2min*10+vcifxs[i]; rez2max=rez2max*10+vcifxd[i]; } if(X == x123min) rez2 = rez2max; else if(X == x123max) rez2 = rez2min; else { rez2=rez2min; if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X } } else if(pozincorecta<=3) pozincorecta23(); else pozincorecta45678(); fout<<rez2<<’\n’; } 333 Listing 11.2.4: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 Numere - Etapa nr. 3 void nrcifrex(int x) { ncx=0; while(x>0) { ncx++; x=x/10; } } void vcifrex(int x) { for(int i=1; i<=ncx; i++) { vcifx[ncx-i+1]=x%10; x=x/10; } } void calcpozincorecta() { if(x12 != 16 && x12 != 25 && x12 != 36 && x12 != 49 && x12 != 81) pozincorecta=2; else if(!(x3 == 2 || x3 == 3 || x3 == 5 || x3 == 7) && (x3+x2)%2==1) pozincorecta=3; else { int i=4; while((i<=ncx) && (vcifx[i]+vcifx[i-1])%2==1) i++; pozincorecta=i; } } int f123min(int c123) { int c123min=c123; for(int i=4; i<=ncx; i++) CAPITOLUL 11. 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 152 ONI 2019 if(c123min%2==0) c123min=c123min*10+1; else c123min=c123min*10+0; return c123min; } int f123max(int c123) { int c123max=c123; for(int i=4; i<=ncx; i++) if(c123max%2==0) c123max=c123max*10+9; else c123max=c123max*10+8; return c123max; } void succesorX() // dupa X = OK { for(int i=1; i <= ncx; i++) vcifxd[i]=vcifx[i]; int poz=ncx; while(vcifxd[poz]>=8) poz=poz-1; // nu pot sa adun 2 (sa rapana paritatea ok!) vcifxd[poz]=vcifxd[poz]+2; // completez spre dreapta cu 0, 1 ... for(int i=poz+1; i<=ncx; i++) if(vcifxd[i-1]%2==0) vcifxd[i]=1; else vcifxd[i]=0; } void predecesorX() // inainte de X = OK { for(int i=1; i<=ncx; i++) vcifxs[i]=vcifx[i]; int poz=ncx; while(vcifx[poz]<=1) poz=poz-1; // copie // nu pot sa scad 2 (sa ramana paritatea ok!) vcifxs[poz]=vcifx[poz]-2; // completez spre dreapta cu 8, 9 ... for(int i=poz+1; i<=ncx; i++) if(vcifxs[i-1]%2==0) vcifxs[i]=9; else vcifxs[i]=8; } 444 Listing 11.2.5: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Numere - Etapa nr. 4 void pozincorecta23() // 163 165 167 252 363 365 367 492 812 { if(x123<163) { rez2=f123min(163); return;} if(x123>812) { rez2=f123max(812); return;} if(x123<252) // 16 < x12 < 25 { rez2min=f123max(167); // patrat, prim cel mai mare permis rez2max=f123min(252); // patrat, prim cel mai mic permis rez2=rez2min; if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X return; } if(x12<36) // 25 < x12 < 36 { rez2min=f123max(252); rez2max=f123min(361); rez2=rez2min; if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X return; CAPITOLUL 11. 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 153 ONI 2019 } if(x12<49) // 36 < x12 < 49 { rez2min=f123max(367); rez2max=f123min(492); rez2=rez2min; if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X return; } if(x12<81) // 49 < x12 < 81 { rez2min=f123max(492); rez2max=f123min(812); rez2=rez2min; if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X return; } } void pozincorecta45678() { if(vcifx[pozincorecta]>=1) // pot sa scad 1 ... corectez paritatea !!! { calcvcifxs(); succesor(); } else // sigur pot sa adun 1 ... corectez paritatea !!! { calcvcifxd(); predecesor(); } rez2min=rez2max=0; for(int i=1; i<=ncx; i++) { rez2min=rez2min*10+vcifxs[i]; rez2max=rez2max*10+vcifxd[i]; } rez2=rez2min; if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X } 555 Listing 11.2.6: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include<iostream> #include<fstream> Numere - Etapa nr. 5 // cout ... afisari pe ecran ... !!! // fstream using namespace std; ifstream fin("numere.in"); ofstream fout("numere.out"); int C; int N; int X; // 20.000.000 incape pe "int" int nr3c[9] = { 163, 165, 167, 252, 363, 365, 367, 492, 812 }; long long rez1=9; int rez2, rez2min, rez2max; int vcifx[9]; int vcifxs[9]; int vcifxd[9]; // indici 0, 1, ..., 8 ... vcifx[8] EROARE la ncx=8 ... // nr mai mic decat X (in stanga) ... predecesor // nr mai mare decat X (in dreapta) ... succesor int ncx; int pozincorecta; int x123; // unsigned long long ... este mai OK! // solutie pentru Cerinta 2 // nr cifre in X // pozitia ... cu cifra incorecta // primele 3 cifre CAPITOLUL 11. 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 int x12; int x3; int x2; 154 ONI 2019 // primele 2 cifre // cifra x3 // cifra x2 void rezolva1() { fin>>N; rez1=9LL; for(int i=1; i<=min(N-3,28-3); i++)// N=28 este ultimul care este ok rez1=rez1*5; if(N==29) // trebuie si ultima inmultire cu 5 ... !!! { int v[21]; // vector cu cifrele rezultatului int i; // variabila de lucru ... trebuie si in afara for-ului int poz=-1; // pozitia in vectorul cifrelor lui rez1 while(rez1>0L) { poz++; v[poz]=rez1%10; rez1=rez1/10; } // inmultirea rez*5 int t=0; // cifra de transport ... la inmultire for(i=0; i<=poz; i++) { int cifra=v[i]*5+t; v[i]=cifra%10; t=cifra/10; } if(t>0) { v[i]=t; poz++; } for(i=poz; i>=0; i--) fout<<v[i]; fout<<’\n’; } else fout<<rez1<<’\n’; } void nrcifrex(int x) { ncx=0; while(x>0) { ncx++; x=x/10; } } void vcifrex(int x) { for(int i=1; i<=ncx; i++) { vcifx[ncx-i+1]=x%10; x=x/10; } } void predecesorX() // inainte de X = OK { for(int i=1; i<=ncx; i++) vcifxs[i]=vcifx[i]; int poz=ncx; while(vcifx[poz]<=1) poz=poz-1; // copie // nu pot sa scad 2 (sa ramana paritatea ok!) vcifxs[poz]=vcifx[poz]-2; // completez spre dreapta cu 8, 9 ... for(int i=poz+1; i<=ncx; i++) if(vcifxs[i-1]%2==0) vcifxs[i]=9; else vcifxs[i]=8; } void predecesor() // inainte de vcifxd[] = existent deja { for(int i=1; i<=ncx; i++) vcifxs[i]=vcifxd[i]; // copie CAPITOLUL 11. 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 155 ONI 2019 int poz=ncx; while(vcifxd[poz]<=1) poz=poz-1; // nu pot sa scad 2 (sa ramana paritatea ok!) vcifxs[poz]=vcifxd[poz]-2; // completez spre dreapta cu 8, 9 ... for(int i=poz+1; i<=ncx; i++) if(vcifxs[i-1]%2==0) vcifxs[i]=9; else vcifxs[i]=8; } void succesorX() // dupa X = OK { for(int i=1; i <= ncx; i++) vcifxd[i]=vcifx[i]; int poz=ncx; while(vcifxd[poz]>=8) poz=poz-1; // nu pot sa adun 2 (sa ramana paritatea ok!) vcifxd[poz]=vcifxd[poz]+2; // completez spre dreapta cu 0, 1 ... for(int i=poz+1; i<=ncx; i++) if(vcifxd[i-1]%2==0) vcifxd[i]=1; else vcifxd[i]=0; } void succesor() // dupa vcifxs[] = existent deja ... !!! { for(int i=1; i<=ncx; i++) vcifxd[i]=vcifxs[i]; // copie int poz=ncx; while(vcifxd[poz]>=8) poz=poz-1; // nu pot sa adun 2 (sa ramana paritatea ok!) vcifxd[poz]=vcifxd[poz]+2; // completez spre dreapta cu 0, 1 ... for(int i=poz+1; i<=ncx; i++) if(vcifxd[i-1]%2==0) vcifxd[i]=1; else vcifxd[i]=0; } int f123min(int c123) { int c123min=c123; for(int i=4; i<=ncx; i++) if(c123min%2==0) c123min=c123min*10+1; else c123min=c123min*10+0; return c123min; } int f123max(int c123) { int c123max=c123; for(int i=4; i<=ncx; i++) if(c123max%2==0) c123max=c123max*10+9; else c123max=c123max*10+8; return c123max; } calcvcifxs() // pot sa scad ... construiesc vcifxs[] cat mai mare { for(int i=1; i<=pozincorecta; i++) vcifxs[i]=vcifx[i]; // copie ... vcifxs[pozincorecta]-=1; // scad 1 ==> se repara paritatea for(int i=pozincorecta+1; i<=ncx; i++) if(vcifxs[i-1]%2==0) vcifxs[i]=9; else vcifxs[i]=8; CAPITOLUL 11. 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 156 ONI 2019 } calcvcifxd() // pot sa adun 1 ... construiesc vcifxd[] cat mai mic { for(int i=1; i<=pozincorecta; i++) vcifxs[i]=vcifx[i]; // copie ... vcifxd[pozincorecta]+=1; // adun 1 ==> se repara paritatea for(int i=pozincorecta+1; i<=ncx; i++) if(vcifxd[i-1]%2==0) vcifxd[i]=1; else vcifxd[i]=0; } void calcpozincorecta() { if(x12 != 16 && x12 != 25 && x12 != 36 && x12 != 49 && x12 != 81) pozincorecta=2; else if(!(x3 == 2 || x3 == 3 || x3 == 5 || x3 == 7) && (x3+x2)%2==1) pozincorecta=3; else { int i=4; while((i<=ncx) && (vcifx[i]+vcifx[i-1])%2==1) i++; pozincorecta=i; } } void pozincorecta23() // 163 165 167 252 363 365 367 492 812 { if(x123<163) { rez2=f123min(163); return;} if(x123>812) { rez2=f123max(812); return;} if(x123<252) // 16 < x12 < 25 { rez2min=f123max(167); // patrat, prim cel mai mare permis rez2max=f123min(252); // patrat, prim cel mai mic permis rez2=rez2min; if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X return; } if(x12<36) // 25 < x12 < 36 { rez2min=f123max(252); rez2max=f123min(361); rez2=rez2min; if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X return; } if(x12<49) // 36 < x12 < 49 { rez2min=f123max(367); rez2max=f123min(492); rez2=rez2min; if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X return; } if(x12<81) // 49 < x12 < 81 { rez2min=f123max(492); rez2max=f123min(812); rez2=rez2min; if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X return; } } void pozincorecta45678() { if(vcifx[pozincorecta]>=1) { calcvcifxs(); succesor(); // pot sa scad 1 ... corectez paritatea !!! CAPITOLUL 11. 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 } else { 157 ONI 2019 // pot sa adun 1 ... corectez paritatea !!! calcvcifxd(); predecesor(); } rez2min=rez2max=0; for(int i=1; i<=ncx; i++) { rez2min=rez2min*10+vcifxs[i]; rez2max=rez2max*10+vcifxd[i]; } rez2=rez2min; if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X } void rezolva2() { fin>>X; nrcifrex(X); vcifrex(X); x123=X; for(int i=ncx; i>=4; i--) x123=x123/10; x12=x123/10; x3=x123%10; calcpozincorecta(); if(pozincorecta>ncx) // X este OK ... { rez2=X; // ... trebuie sa fie DIFERIT de X ... !!! int x123min=f123min(x123); int x123max=f123max(x123); if(X < x123max) succesorX(); if(X > x123min) predecesorX(); // vcifxd[] // vcifxs[] rez2min=rez2max=0; for(int i=1; i<=ncx; i++) { rez2min=rez2min*10+vcifxs[i]; rez2max=rez2max*10+vcifxd[i]; } if(X == x123min) rez2 = rez2max; else if(X == x123max) rez2 = rez2min; else { rez2=rez2min; if(rez2max-X < X-rez2min) rez2=rez2max; // mai aproape de X } } else if(pozincorecta<=3) pozincorecta23(); else pozincorecta45678(); fout<<rez2<<’\n’; } int main() { fin>>C; if(C==1) rezolva1(); if(C==2) rezolva2(); return 0; } CAPITOLUL 11. 11.2.3 158 ONI 2019 Cod surs Listing 11.2.7: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 numere_cpp.cpp #include <fstream> using namespace std; ifstream f("numere.in"); ofstream g ("numere.out"); int main() { int p,n,x,dif1=20000000,dif2=20000000,y,xx; long long xmin,xmax,i, nr1,nr2; unsigned long long nr; f>>p; if (p==1) { f>>n; nr=9; for (i=1; i<=n-3; i++) nr=nr*5; g<<nr<<’\n’; } else { f>>x; y=x; xmin=163; xmax=812; i=3; while (y>999) { i++; if (i%2==0) { xmin=xmin*10; xmax=xmax*10+9; } else { xmin=xmin*10+1; xmax=xmax*10+8; } y=y/10; } if (x<xmin) g<<xmin; else if (x>xmax) g<<xmax; else { for (xx=x-1; xx>=xmin; xx--) { int v[11],k=0,n2,i,xxx=xx, bun=1; while (xxx>99) { k++; v[k]=xxx%10; xxx=xxx/10; } if (xxx!=16 && xxx!=25 && xxx!=36 && xxx!=49 && xxx!=81) bun=0; else if ((xxx==16|| xxx==36)&& (v[k]!=3 && v[k]!=5 && v[k]!=7)) bun=0; else if ((xxx==25 || xxx==49 ||xxx==81) && v[k]!=2) bun=0; else for (i=k-1; i>=1; i--) if (v[i]%2==v[i+1]%2) bun=0; if (bun) { CAPITOLUL 11. 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 159 ONI 2019 nr1=xx; dif1=x-nr1; break; } } for (xx=x+1; xx<=xmax; xx++) { int v[11],k=0,n2,i,xxx=xx, bun=1; while (xxx>99) { k++; v[k]=xxx%10; xxx=xxx/10; } if (xxx!=16 && xxx!=25 && xxx!=36 && xxx!=49 && xxx!=81) bun=0; else if ((xxx==16|| xxx==36)&& (v[k]!=3 && v[k]!=5 && v[k]!=7)) bun=0; else if ((xxx==25 || xxx==49 ||xxx==81) && v[k]!=2) bun=0; else for (i=k-1; i>=1; i--) if (v[i]%2==v[i+1]%2) bun=0; if (bun) { nr2=xx; dif2=nr2-x; break; } } if (dif1<=dif2) g<<nr1<<’\n’; else g<<nr2<<’\n’; } } } 11.3 Trio Problema 3 - Trio Trio este un joc ce conµine 100 de puncte 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 zone, iar în ecare dintre ele este scris câte o cifr . Se consider c are marcate pe ea trei 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 C1 C2 C3 este identic cu o alt pies de C2 C3 ³i cu o pies de forma C3 C2 C1 . forma C1 este prieten cu o alt pies dac aceasta conµine exact acelea³i cifre ca piesa dat , C1 C2 C3 este prieten cu piesele: dar nu neap rat în aceea³i ordine. Astfel, piesa C1 C2 C3 , C1 C3 C2 , C2 C1 C3 , C2 C3 C1 , C3 C1 C2 C2 C1 . Se observ c dou piese identice sunt ³i prietene! ³i C3 Un grup de piese prietene este format din TOATE piesele prietene între ele, aate pe tabla este cu ale ei sau în ordine invers . Astfel, piesa de joc. Cerinµe 1) Alegeµi o pies de pe tabla de joc, astfel încât num rul cel mai mare posibil ³i a³aµi num rul M determinat; M al pieselor identice cu ea s e 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µ tabla de joc, pentru care prima pies ³i ultima pies ce conµine piese a³ezate una lâng din secvenµ alta pe sunt prietene. Date de intrare - pe prima linie un num r natural 2 sau 3. C care reprezint num rul cerinµei ³i poate avea valorile 1, CAPITOLUL 11. 160 ONI 2019 N ce reprezint num rul pieselor de joc; N linii, câte trei cifre, desp rµite prin câte un spaµiu, ce reprezint , în ordine, - pe cea de-a doua linie un num r natural - pe urm toarele 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 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 O pies piese identice pe tabla de joc; ce nu e prieten cu nicio alt pies Pentru rezolvarea cerinµei 1) se acord de pe tabla de joc formeaz singur un grup; 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 9 5 4 pe tabl 3 3 1 2 sau 4 exist 9 4 5 1 cerinµa 1. Alegând oricare din piesele 1, 3 sau 5 exist douÄ piese identice cu piesa aleas . Alegând oricare din piesele Dac 2 doar o pies ce este identic alegem piesa 6 nu exist pe tabl cu piesa aleas . piese identice cu ea. . 6 1 3 3 4 5 9 1 3 3 Se rezolv 9 5 4 3 3 1 un grup de piese prietene. alt grup. Piesa 3 formeazÄ singur un grup. În total, pe tabl , sunt 3 grupuri de piese prietene. 9 4 5 1 cerinµa 2. Piesele 1 ³i 5 formez Piesele 2, 4 ³i 6 formeaz 2 6 Se rezolv xim , egal cerinÈa cu 5, 3. Identic m pentru care prima dou ³i secvenµe ultima de pies lungime sunt ma- prietene: 1 3 3 4 5 9 1 3 3 9 5 4 3 3 1 9 4 5 Timp maxim de executare/test: 0.2 secunde Memorie: total 2MB din care pentru stiv 2MB Dimensiune maxim a sursei: 15KB Sursa: trio.cpp, trio.c sau trio.pas va salvat 11.3.1 în folderul care are drept nume ID-ul t u. Indicaµii de rezolvare Prof. Cristina Iordaiche Liceul Teoretic Grigore Moisil Timi³oara Cerinµa 1 - pentru determinarea num rului joc, identice cu o pies M ce reprezint cel mai mare num r de piese de pe tabla de V cu ajutorul c ruia se va aleas , se construie³te un vector de frecvenµ contoriza num rul pieselor identice; CAPITOLUL 11. - ec rei piese 161 ONI 2019 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]; - se va µine cont de faptul c - pentru oricare dou piese identice C1 C2 C3 ³i C3 C2 C1 vor avea asociat aceea³i valoare numeric ; V[C1*100+C2*10+C3] se va incrementa de ecare dat când este întâlnit pe tabla de joc o pies valoarea numeric prezizat mai sus; - se va determina valoarea maxim ce are asociat memorat în vectorul V. Cerinµa 2 - pentru determinarea num rului de grupe de piese prietene de pe tabla de joc, se vor identica toate piesele prietene de pe tabla de joc ce aparµin aceluia³i grup. C1 C2 C3 , C1 C3 C2 , C2 C1 C3 , C2 C3 C1 , C3 C1 C2 ³i C3 C2 C1 aparµin aceluia³i grup de piese prietene, toate vor avea - deoarece piesele asociat aceea³i valoare numeric egal cu C1*100+C2*10+C3. Aceast valoare se poate obµine prin ordonarea cresc toare a celor trei cifre C1,C2 ³i C3 - se va memora cu ajutorul unui vector de frecvenµ num rul de apariµii al ec rei valori numerice din intervalul [0,999] - se va utiliza o variabil de tip contor pentru num rarea tuturor grupurilor de piese prietene Cerinµa 3 - Pentru determinarea celei mai lungi secvenµe de piese a³ezate una lâng joc, în care prima ³i ultima pies alta pe tabla de 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 11.3.2 Rezolvare detaliat Listing 11.3.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include<iostream> #include<fstream> // cout // fstream using namespace std; ifstream fin("trio.in"); ofstream fout("trio.out"); int C; int N; // nr cerinta int c1, c2, c3; void rezolva1() { for(int i=1; i<=N; i++) { fin>>c1>>c2>>c3; } } void rezolva2() { for(int i=1; i<=N; i++) { fin>>c1>>c2>>c3; } } void rezolva3() { for(int i=1; i<=N; i++) { fin>>c1>>c2>>c3; } } Trio - Etapa nr. 0 acea valoare. CAPITOLUL 11. 41 42 43 44 45 46 47 48 49 50 51 52 53 162 ONI 2019 int main() { fin>>C; fin>>N; if(C==1) rezolva1(); else if(C==2) rezolva2(); else if(C==3) rezolva3(); return 0; } Listing 11.3.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 void rezolva1() { int nraparitii[1000]={0}; // nu N ... !!! int p123; // "prieteni": 123 cu 321 int maxp; // raspuns la cerinta 1 int aux; // variabila auxiliara pentru interschimbare for(int i=1; i<=N; i++) { fin>>c1>>c2>>c3; if(c1>c3) {aux=c1; c1=c3; c3=aux;} p123=c1*100+c2*10+c3; nraparitii[p123]++; } cout<<"maxp-1 = "<<maxp-1<<"\n"; fout<<maxp-1<<’\n’; // Atentie la textul cerintei si exemplul 1 } Trio - Etapa nr. 2 void rezolva2() { int nraparitii[1000]={0}; // nu N ... !!! int p123; // "prieteni": 123 cu 321 int nrgp; // nr grupuri de prieteni - raspuns la cerinta 2 int aux; // variabila auxiliara pentru interschimbare for(int i=1; i<=N; i++) { fin>>c1>>c2>>c3; if(c1>c2) {aux=c1; c1=c2; c2=aux;} if(c1>c3) {aux=c1; c1=c3; c3=aux;} if(c2>c3) {aux=c2; c2=c3; c3=aux;} p123=c1*100+c2*10+c3; nraparitii[p123]++; // c1 <= c2 // c1 <= c3 deci c1=min // c2 <= c3 deci c3=max // c1 <= c2 <= c3 } nrgp=0; for(int i=0; i<=999; i++) if(nraparitii[i] > 0) nrgp+=1; cout<<"nrgp = "<<nrgp<<"\n"; fout<<nrgp<<’\n’; // Atentie la textul cerintei si exemplul 2 } Listing 11.3.4: 1 2 // c1 <= c3 "identice" (1,2,3)=(3,2,1) maxp=0; for(int i=0; i<=999; i++) if(nraparitii[i] > maxp) maxp=nraparitii[i]; Listing 11.3.3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 Trio - Etapa nr. 1 void rezolva3() { Trio - Etapa nr. 3 CAPITOLUL 11. 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 163 ONI 2019 int primaaparitie[1000]={0}; int ultimaaparitie[1000]={0}; int p123; int maxpiese; int aux; // nu N ... !!! // nu N ... !!! // "prieteni": 123 cu 321 // nr max piese - raspuns la cerinta 3 // variabila auxiliara pentru interschimbare for(int i=1; i<=N; i++) { fin>>c1>>c2>>c3; if(c1>c2) {aux=c1; c1=c2; c2=aux;} if(c1>c3) {aux=c1; c1=c3; c3=aux;} if(c2>c3) {aux=c2; c2=c3; c3=aux;} p123=c1*100+c2*10+c3; // c1 <= c2 <= c3 if(primaaparitie[p123]==0) primaaparitie[p123]=i; else ultimaaparitie[p123]=i; } maxpiese=0; for(int i=0; i<=999; i++) if(ultimaaparitie[i] - primaaparitie[i] > maxpiese) maxpiese=ultimaaparitie[i] - primaaparitie[i]; cout<<"maxpiese = "<<maxpiese+1<<"\n"; fout<<maxpiese+1<<’\n’; // Atentie la textul cerintei si exemplul 3 } 11.3.3 Cod surs Listing 11.3.5: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 // c1 <= c2 // c1 <= c3 deci c1=min // c2 <= c3 deci c3=max #include <fstream> #include <iostream> #include <algorithm> trio_cpp.cpp // sort using namespace std; ifstream f("trio.in"); ofstream g("trio.out"); int N,C,nr,ap[1000],c[4],max_identice,nr_ord,nr_grupuri; bool grup[1000]= {0}; //cerinta2 int ultima_poz[1000], prima_poz[1000]={0}, max_echivalente; //cerinta3 int main() { int i; f>>C>>N; for(int i=1; i<=N; i++) { f>>c[1]>>c[2]>>c[3]; if(c[3]>c[1]) swap(c[1],c[3]); nr=(c[1]*100+c[2]*10+c[3]); ap[nr]++; if(ap[nr]>max_identice) max_identice=ap[nr]; // ordonez cifrele de pe o piesa pentru a determina // cele ce aprtin aceluiasi grup sort(c+1,c+4); nr_ord=c[1]*100+c[2]*10+c[3]; CAPITOLUL 11. 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 ONI 2019 grup[nr_ord]=1;// vector de aparitii ptr grup if(prima_poz[nr_ord]==0) //memorez primul nr de ordine al unei piese din grup prima_poz[nr_ord]=i; else //memorez ultimul numar de ordine al unei piese din acelasi grup ultima_poz[nr_ord]=i; } if (C==1) g<<max_identice-1<<’\n’; else if (C==2) { for(i=0; i<=999; i++) if(grup[i]) nr_grupuri++; g<<nr_grupuri<<’\n’; } else { for(i=0; i<=999; i++) if(ultima_poz[i]-prima_poz[i]>max_echivalente) max_echivalente=ultima_poz[i]-prima_poz[i]; g<<max_echivalente+1<<’\n’; } return 0; } 164 Capitolul 12 ONI 2018 12.1 desen - ONI 2018 Problema 1 - desen 100 de puncte La ora de desen, Gigel a primit ca tem e realizat dup un desen care s urm torul algoritm: Pas 1: se deseneaz un triunghi, numerotat cu 1, ca în Figura 1; Pas 2: se împarte triunghiul 1 în trei poligoane (un dreptunghi ³i dou triunghiuri numerotate cu 2 ³i 3) trasând dou segmente ca în Figura 2 ; Pas 3: ecare triunghi dintre cele dou obµinute la Pas 2, se împarte în câte un dreptunghi ³i câte dou (numerotate cu 4, 5, 6, 7) trasând câte dou triunghiuri segmente ca în Figura 3 ; Pas 4: ecare triunghi dintre cele patru obµinute la Pas 3, se împarte în câte un dreptunghi ³i câte dou triunghiuri (numerotate cu 8, 9,10, 11, 12, 13, 14, 15) trasând câte dou segmente ca în Figura 4 ; ....... Pas N: ecare triunghi dintre triunghiurile obµinute la Pas N 1, se împarte în câte un dreptunghi ³i câte dou triunghiuri trasând câte dou Dac segmente. valoarea lui K este ultimul num r folosit pentru nu- merotarea triunghiurilor obµinute la Pas N 1, atunci triunghiurile rezultate la Pas N vor numerotate cu numerele naturale distincte consecutive K 1, K 2, K 3, ..., etc. Cerinµe Scrieµi un program care s s citeasc num rul natural K ³i determine: 1. cel mai mic num r X ³i cel mai mare num r Y dintre numerele folosite pentru numerotarea triunghiurilor obµinute la pasul în care este obµinut ³i triunghiul numerotat cu K ; 2. numerele triunghiurilor care au fost împ rµite conform algoritmului din enunµ astfel încât s e obµinut triunghiul numerotat cu K . Date de intrare Fi³ierul de intrare din problem Figura 12.1: desen desen.in conµine pe prima linie un num r natural C reprezentând cerinµa care trebuie rezolvat (1 sau 2). Fi³ierul conµine pe a doua linie num rul natural K . 165 CAPITOLUL 12. 166 ONI 2018 Date de ie³ire 1, atunci prima linie a ³ierului de ie³ire desen.out conµine cele dou C Dac numere naturale X ³i Y , separate printr-un singur spaµiu, reprezentând r spunsul la cerinµa 1 a problemei. 2, atunci prima linie a ³ierului de ie³ire desen.out conµine un ³ir de numere C Dac 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 a 2 & K & 9223372036854775807 63 2 1 a doar triunghiurile sunt numerotate a pentru rezolvarea corect a cerinµei 1 se acord a pentru rezolvarea corect a cerinµei 2 se acord Exemple desen.in 40 de puncte 60 de puncte. desen.out Explicaµii 1 13 Cerinµa este 1, K 8 15 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 2 13 15. Cerinµa este 2, 1 3 6 K 13. A³a cum arat Figura 4, triunghiul 13 se obµine din triunghiul 6. Triunghiul 6 numerotat cu K este obµinut din triunghiul 3 care este obµinut din triunghiul 1. Timp maxim de executare/test: 0.3 secunde Memorie: total 8 MB din care pentru stiv 8 MB Dimensiune maxim a sursei: 5 KB 12.1.1 Indicaµii de rezolvare prof. Daniela T taru, Colegiul Naµional Al. D. Ghica, Alexandria Observ m c : Exemple Pas Cel folosit Cel mai mare num r folosit Num r la numerotarea triunghiurilor mai mic num r la numerotarea triunghiurilor obµinute obµinute la acest pas obµinute la acest pas pas Pas 1: 1 1 Pas 2: 2 3 Pas 3: 4 7 Pas 4: 8 15 2 1 2 2 2 3 2 Pas ...: ... ... Pas N: 2 2 N 1 0 N ... 1 2 Cerinµa 1. Se determin N 1 valorile X ³i Y cu proprietatea c : &K&Y Cerinµa 2. X 2 Se a³eaz x1 2 N 1 în ordine invers K ©2, x2 x1 ©2, x3 N 1 22 1 2X 1 valorile: x2 ©2, ..., xN 12.1.2 *Rezolvare detaliat 12.1.3 *Cod surs 1 N 1 triunghiuri la acest CAPITOLUL 12. 12.2 167 ONI 2018 mostenire - ONI 2018 Problema 2 - mostenire Regele Rufus dore³te s 100 de puncte stabileasc mo³tenitorul averii sale, adic s celui mai de³tept dintre ii s i. Iniµial, regele a avut parola X format ofere parola de la seif 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µ la parola nal de cifre din parol ajungând P. Pentru ecare secvenµ se cunoa³te poziµia S a primei cifre din secvenµ ³i poziµia D a ultimei din cifrele situate pe poziµiile S , S 1, S 2, ..., cifre din secvenµ . Astfel, secvenµa este format 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 ultima cifr a lui Q, ..., a ec rei apariµii a cifrei 9 cu 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 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. iniµial 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 1. determin parola iniµial 2. determin poziµia minim urm toarele dou cerinµe: X; Z ³i cifrele distincte care au ocupat aceast poziµie în cei K ani de domnie. Date de intrare Fi³ierul de intrare cerinµa din problem mostenire.in conµine pe prima linie un num r natural C reprezentând 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 numere naturale S ³i D , separate printr-un singur spaµiu, reprezentând câte o pereche câte dou 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 Z , reprezentând r spunsul la pe a doua linie cifrele distincte care au ap rut pe poziµia minim 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 a cel puµin o cifr &D din parola X va înlocuit a pentru rezolvarea corect a cerinµei 1 se acord a pentru rezolvarea corect a cerinµei 2 se acord 50 de puncte 50 de puncte. CAPITOLUL 12. 168 ONI 2018 Exemple: mostenire.in mostenire.out Explicaµii 2 7 3 5 4 1 3 3 7 9 2 8 Cerinµa este 1, N=12, K=4. 2 3 Cerinµa este 2, N=12, K=4. 712534698 12 4 1 2 3 7 P=(1 4 7 1 3 4 7 1 4 8 1 8) 1 712534698 12 4 1 4 7 1 3 4 7 1 4 8 1 8 2 4 6 11 3 9 1 7 1 4 7 1 3 4 7 1 4 8 1 8 Poziµiile care au ap rut în cele mai multe secvenµe 2 4 sunt: 3,4,6,7 => Z=3, iar cifrele distincte care au 6 11 ocupat succesiv aceast 3 9 cifre se vor scrie în ³ier în ordine cresc toare pozitie sunt 3,2,1,7. Aceste 1 7 Timp maxim de executare/test: 0.3 secunde Memorie: total 8 MB din care pentru stiv 8 MB Dimensiune maxim a sursei: 10 KB 12.2.1 Indicaµii de rezolvare prof. Flavius Boian, Colegiul Naµional Spiru Haret, Târgu Jiu Cerinta 1 Se citesc succesiv intervalele S , D pe care s-au aplicat modic ri. Pentru secvenµa curent , ecare cifr poziµionat în secvenµ se înlocuie³te cu poziµia acestei cifre în codul Q realizându-se astfel transformarea în sens invers. Cerinta 2 Se poate utiliza un vector de frecvenµ determin cu N elemente. Pentru ecare poziµie i din vector se 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 poziµie, realizând de K cifrele ce au ocupat acest 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. 12.2.2 *Rezolvare detaliat 12.2.3 *Cod surs 12.3 pyk - ONI 2018 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 Num rul P este o k -putere dac exist y x1 x2 x3 ... xn . k z . un num r natural z astfel încât P 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 num rul P y x1 x2 x3 ... xn este o k -putere. ' 2) cu proprietatea c CAPITOLUL 12. 169 ONI 2018 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 & n & 50000 & k & 100 a 2 & x1 , x2 , x3 , ..., xn & 10000 a 2 & y a 2 a 2 a pentru rezolvarea corect a cerinµei 1 se acord a pentru rezolvarea corect a cerinµei 2 se acord Exemple pyk.in 10 puncte 90 de puncte. pyk.out Explicaµii 1 Cerinµa este 1, k 4 1111 2, n 7. 2 7 Numerele din ³irul X formate doar din cifre identice sunt: 122 1111 5 4 88 123 999 2 3 1111, 5, 4, 88, 999. Cel mai mic num r dintre acestea este 4, iar cel mai mare este 1111. 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 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 5 1 Timp maxim de executare/test: 0.3 secunde Memorie: total 8 MB din care pentru stiv 8 MB Dimensiune maxim a sursei: 5 KB 12.3.1 Indicaµii de rezolvare prof. Carmen Minc , Colegiul Naµional de Informatic Tudor Vianu, Bucure³ti Cerinta 1. Se pot folosi dou variabile xmin ³i xmax pentru a memora valorile cerute. Se citesc succesiv numerele din ³ier. Se compar curent se compar cifrele ec rui num r. Dac cifrele sunt identice, atunci num rul cu xmax ³i xmin curent, actualizându-se valorile acestora. Cerinµa 2. O soluµie se poate obµine f r a Se determin a calcula produsul numerelor astfel: 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 12. 170 ONI 2018 a Se parcurge vectorul f r . Pentru ecare num r cu frecvenµa nenul (adic dac se veric dac este prim 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 în care elementul w j memoreaz un vector w produsul dintre frecvenµa de apariµie a factorului prim j ³i exponentul acestuia). Elementele w j % 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 w j %k (se incrementeaz exponentul pân la primul multiplu de k ). 12.3.2 *Rezolvare detaliat 12.3.3 *Cod surs Capitolul 13 ONI 2017 13.1 prime - ONI 2017 Problema 1 - prime Eu sunt fascinat 100 de puncte de numerele prime. numerelor sau "atomii" acestora, pentru c Consider c numerele prime sunt "scheletul" tuturor 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 cifre, iar descompunerea sa în factori primi se scrie cu dou c 128 se scrie cu 3 7 cifre (2 ); 4374 este economic pentru 7 se scrie cu 4 cifre, în timp ce descompunerea sa în factori primi se scrie cu 3 cifre (2 3 ) Observaµi c 3. atunci când un factor prim apare la puterea 1, aceasta nu este necesar s Multe numere naturale pot scrise ca sum exemplu, 121 nu poate scris ca sum de dou de dou numere prime. e scris . Dar nu toate. De numere prime. Cerinµe Scrieµi un program care cite³te num rul natural n ³i o secvenµ rezolv de n numere naturale, apoi urm toarele cerinµe: 1. determin ³i a³eaz câte dintre numerele din secvenµa dat 2. determin ³i a³eaz câte dintre numerele din secvenµa dat 3. determin ³i a³eaz câte dintre numerele din secvenµa dat sunt numere prime din ³irul Fibonacci; dou sunt numere economice; nu pot scrise ca sum de 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 171 CAPITOLUL 13. a 1 172 ONI 2017 $ n & 50 7 c c 1 sau c 3 numerele naturale din ³ir sunt mai mari decât 1 ³i mai mici decât 10 . 14 a Dac 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. a Dac 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. 4 Succesiunea conµine dou numere economice (128 ³i 4374). 128 25 4374 720 3 4 Cerinµa este 3. Sunt 4 numere naturale din secvenµ 5 scrise ca sum de dou care nu pot numere prime: 57, 121, 11, 3. 57 30 121 11 3 Timp maxim de executare/test: 1.2 secunde Memorie: total 24 MB din care pentru stiv 1 MB Dimensiune maxim a sursei: 15 KB 13.1.1 Indicaµii de rezolvare prof. Emanuela Cerchez, Colegiul Naµional "Emil Racoviµ " Ia³i Vom citi într-un vector a cele n valori ³i vom determina vmax cea mai mare valoare din vector. Pentru o abordare ecient , pentru toate cele 3 cerinµe, pregener m numerele prime (sau & 107 & 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 ³i lungimea ec rui num r prim. Pentru cerinµa 1 este sucient s gener m termenii ³irului Fibonacci într-un vector acei termeni care sunt numere prime. Fiindc Fibonacci & 107 este foarte mic, putem s reµinem într-un vector & vmax ³i s memor m num rul de termeni primi din ³irul 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 folosiµi numerele prime memorate în vectorul prim). scrierea factorilor primi ³i a puterilor acestora este c Dac a în factori primi (ecient!!! num rul de cifre necesare pentru $ lungimea num rului curent din a, deducem 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 prime pân când se termin de dou numere prime. Pentru aceasta parcurg vectorul de numere (sau, mai ecient, pân decât complementarul s u ai p) sau pân este deasemenea prim. Dac când num rul prim curent p este mai mare când g sesc un num r prim p pentru care ai p un astfel de num r prim nu a fost g sit, contorizez pe ai. Soluµie alternativ (100 puncte) prof. andor Nicoleta, Colegiul Naµional Mihai Eminescu Satu Mare Pentru ecare cerinµ se vor prelucra numerele la citire. Cerinµa 1: Veric m dac dac num rul citit este termen al ³irului lui Fibonacci. În caz armativ, veric m 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 13. Dac 173 ONI 2017 valoarea citit are num rul de cifre primi ³i a puterilor acestora, deducem c % num rul de cifre necesare pentru scrierea factorilor 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 dou numere este impar doar dac aceast condiµie folosim proprietatea c unul dintre cele dou suma dintre 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. 13.1.2 *Rezolvare detaliat 13.1.3 Cod surs Listing 13.1.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 //Carmen Popescu #include <iostream> #include <fstream> #include <cmath> using namespace std; ifstream f("prime.in"); ofstream g("prime.out"); bool ciur[10000001]; int prim[665000],lg[665000]; int main() { int i,j,n,c,np,nf,f1,f2,f3; long long a[51],mx; int fib[26]; f>>c>>n; for (i=0;i<n;i++) { f>>a[i]; if (a[i]>mx) mx=a[i]; } if (c==2) mx=sqrt(mx); // nr prime cu ciur ciur[0]=ciur[1]=1; for (i=2;i*i<=mx;i++) if (ciur[i]==0) for (j=i*i;j<=mx;j=j+i) ciur[j]=1; np=0; int p=9,k=1; for (i=2;i<=mx;i++) if (ciur[i]==0) { prim[np]=i; while (i>p) { p=(p+1)*10-1; k++; } lg[np++]=k; prime_cp.cpp CAPITOLUL 13. 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 ONI 2017 } // fibonacci prime nf=0; f1=0; f2=1; f3=1; while (f3<=mx) { if (ciur[f3]==0) fib[nf++]=f3; f1=f2; f2=f3; f3=f1+f2; } if (c==1) { int k=0; for (i=0;i<n;i++) for (j=0;j<nf;j++) if (a[i]==fib[j]) { k++; break; } g<<k<<"\n"; } else if (c==2) { int k=0; for (i=0;i<n;i++) { long long y=a[i],w=a[i]; f1=0; f2=0; while (y>0) { f1++; y/=10; } for(j=0; j<np && prim[j]*prim[j]<=a[i] && f2<f1; j++) { p=0; while (a[i]%prim[j]==0) { p++; a[i]/=prim[j]; } if (p) { f2 += lg[j]; if (p>1) { y=p; while (y>0) { f2++; y/=10; } } } } if (a[i]>1) { y=a[i]; while (y>0) { f2++; y/=10; } } if (f2<f1) k++; } g<<k<<"\n"; } else { int k=0; for (i=0;i<n;i++) { if (a[i]%2==1) { 174 CAPITOLUL 13. 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 175 ONI 2017 if (ciur[a[i]-2]==0) k++; } else { for (j=0;prim[j]<a[i];j++) if (ciur[a[i]-prim[j]]==0) { k++; break; } } } g<<n-k<<"\n"; } return 0; } Listing 13.1.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 prime_em.cpp //Emanuela Cerchez #include <fstream> #include <cmath> #define VMAX 10000001 #define PMAX 1000000 #define NMAX 50 using namespace std; ifstream fin("prime.in"); ofstream fout("prime.out"); bool ciur[VMAX]; int nrprim, nr, n; int prim[PMAX]; int lgprim[PMAX]; long long int a[NMAX], vmax; int fib[NMAX]; int nrfib; int main() {int cerinta, i, j, d, lg, lgx, f1, f2, f3, p, gasit; long long int cx; fin>>cerinta>>n; for (i=0; i<n; i++) { fin>>a[i]; if (a[i]>vmax) vmax=a[i]; } //ciur if (cerinta==2) vmax=sqrt((double)vmax); ciur[0]=ciur[1]=1; for (d=2; d*d<=vmax; d++) if (!ciur[d]) for (j=d*d; j<=vmax; j+=d) ciur[j]=1; //transfer intr-un vector numerele prime <=vmax prim[0]=2; nrprim=1; lgprim[0]=1; for (d=3; d<=vmax; d+=2) if (!ciur[d]) {prim[nrprim]=d; cx=d; do { cx/=10; lgprim[nrprim]++; } while (cx); nrprim++; } if (cerinta==1) CAPITOLUL 13. 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 { for (f1=f2=1; f1+f2<=vmax; ) { f3=f1+f2; f1=f2; f2=f3; if (!ciur[f3]) fib[nrfib++]=f3; } nr=0; for (i=0; i<n; i++) { for (j=0; j<nrfib && a[i]!=fib[j]; j++); if (j<nrfib) nr++; } fout<<nr<<’\n’; fout.close(); return 0; } if (cerinta==2) { nr=0; //descompunere in factori primi eficient for (i=0; i<n; i++) { cx=a[i]; lgx=0; do {lgx++; cx/=10;} while (cx); lg=0; for (j=0; j<nrprim && prim[j]*prim[j]<=a[i] && lg<lgx; j++) { for (p=0; a[i]%prim[j]==0; p++,a[i]/=prim[j]); if (p) { lg+=lgprim[j]; if (p>1) { cx=p; do {lg++; cx/=10;} while(cx); } } } if (a[i]>1) {cx=a[i]; do {lg++; cx/=10;} while (cx);} if (lg<lgx) nr++; } fout<<nr<<’\n’; fout.close(); return 0; } //cerinta 3 nr=0; for (i=0; i<n; i++) { for (gasit=j=0; j<nrprim && a[i]>prim[j]; j++) if (!ciur[a[i]-prim[j]]) {gasit=1; break;} if (!gasit) nr++; } fout<<nr<<’\n’; fout.close(); return 0; } Listing 13.1.3: 1 2 3 4 5 6 7 8 176 ONI 2017 //prof. Sandor Nicoleta #include <fstream> #include<iostream> using namespace std; ifstream fin("prime.in"); ofstream fout("prime.out"); prime_fara_ciur_sn.cpp CAPITOLUL 13. 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 ONI 2017 bool prim(int n) { if (n<2) return 0; if(n==2) return 1; if(n%2==0) return 0; for(int d=3; d*d<=n; d=d+2) if(n%d==0) return 0; return 1; } bool fibo(int n) { int a,b,c; a=b=c=1; while(c<n) { c=a+b; a=b; b=c; } return c==n; } int nrcif(long long n) { int c=0; while(n) { n/=10; c++; } return c; } int descompun(long long x) { int c,s=0; long long d=2; while(x > 1) { if(x % d == 0) { s+=nrcif(d); c=0; while(x % d == 0) x /= d,c++; if(c>1) s+=nrcif(c); } d ++; // daca x este numar prim ne oprim if(x > 1 && d * d > x) { s+=nrcif(x); x = 1; } } return s; } int main() { int i,n,c,v[50],x=0, a; long long a1,j; fin>>c>>n; if(c==1) { for(i=0; i<n; i++) { fin>>a; if (fibo(a)&&prim(a)) x++; } fout<<x; } 177 CAPITOLUL 13. 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 178 ONI 2017 else if(c==2) { for(i=0; i<n; i++) { fin>>a1; if (descompun(a1)<nrcif(a1)) { x++; cout<<a1<<"\n"; } } fout<<x; } else { x=n; for(i=0; i<n; i++) { fin>>a; if(n>3) { //orice numar par mai mare dcat 4 se poate scrie // ca suma a doua numere prime if(a%2==0) x--; else if (prim(a-2)) { x--; } } } fout<<x; } return 0; } 13.2 robot - ONI 2017 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 îndepline³te urm toarele dou corect dac num rul 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 descresc 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 dac este necesar. Robotul reparator se deplaseaz în linie dreapt dintre cele N standuri. La ecare stand, robotul veric Pentru a repara eticheta, robotul aranjeaz nuare, aranjeaz cifr impar par o înlocuie³te cu 9; dac le repare, eticheta ³i dac nu este corect , o repar . cifrele impare în ordine cresc toare, apoi, în conti- cifrele pare în ordine descresc toare; dac cea mai mare cifr verice numere ³i s ³i se opre³te pe rând la ecare eticheta nu conµine nicio cifr eticheta nu conµine nicio cifr impar , par , cea mai mic o înlocuie³te cu 0. 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. Deplasarea de la un stand la altul dureaz 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 1. calculeaz ³i a³eaz urm toarele cerinµe: timpul (ora, minutul ³i secunda) când robotul a încheiat vericarea tuturor celor N standuri ³i repararea etichetelor incorecte; 2. repar nal. (unde este necesar) etichetele standurilor ³i a³eaz etichetele celor N standuri la CAPITOLUL 13. 179 ONI 2017 Date de intrare Fi³ierul de intrare care urmeaz s robot.in conµine pe prima linie un num r natural C , reprezentând cerinµa e rezolvat (1 sau 2). numerele naturale N , h, m, s, iar pe linia a treia numerele naturale t, Pe linia a doua se a 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 1, ³ierul de ie³ire robot.out va conµine o singur linie pe care vor scrise 3 numere mf sf , reprezentând ora, minutul ³i respectiv secunda C naturale separate prin câte un spaµiu hf la care robotul termin Dac C repararea. 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 o etichet ce robotul a încheiat vericarea ³i repararea, câte pe o linie. Restricµii ³i preciz ri a 2 & N & 500 a Etichetele standurilor au cel puµin dou ³i cel mult nou a Robotul începe ³i încheie repararea în aceea³i zi; 0 a Pentru rezolvarea corect cerinµei 2 se acord Exemple robot.in a cerinµei 1 se acord cifre. & h, hf $ 24; 0 & m, mf, s, sf $ 60 40 de puncte; pentru rezolvarea corect a 60 de puncte. 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 11 20 50 3564 Primul stand are eticheta 376572, care este incorect , robotul o 3 standuri. 7 5 15 130 repar ³i aceasta devine 357762. 376572 La al doilea stand eticheta 3564 este corect . deci robotul nu o 3564 va modica. 113 Al treilea stand are eticheta incorect 113, robotul o repar ³i devine 130. Timp maxim de executare/test: 0.1 secunde Memorie: total 2 MB din care pentru stiv 1 MB Dimensiune maxim a sursei: 15 KB 13.2.1 Indicaµii de rezolvare prof. Adriana Simulescu, Liceul Teoretic GRIGORE MOISIL Timi³oara Vom citi pe rând câte un num r. Pentru ecare num r citit, pentru a verica corectitudinea sa, vom construi num rul corect format din cifrele num rului citit astfel: - a³ez m cifrele impare ce apar în num r în ordine cresc toare ³i contoriz m concomitent num rul lor CAPITOLUL 13. 180 ONI 2017 - a³ez m în continuare cifrele pare ce apar în num r în ordine descresc toare ³i contoriz m concomitent num rul lor Num rul citit este corect dac îndepline³te simultan condiµiile: - num rul citit este egal cu num rul construit - num rul este format atât din cifre pare cât ³i din cifre impare Pentru rezolvarea cerinµei 1) - contoriz m numerele corecte în variabila ncorecte - la nal, calcul m timpul astfel: s=s+(N-1)*(t+v)+(N-ncorecte)*r+v; m=m+s/60; s=s%60; h=h+m/60; m=m%60; - scriem în ³ier timpul calculat Pentru rezolvarea cerinµei 2) Dup construirea num rului prin a³ezarea cifrelor pare ³i impare, dac a) doar cifre pare, înlocuie³te prima cifr b) doar cifre impare, ³terge prima cifr a num rului construit ³i adaug Scriem în ³ier num rul calculat 13.2.2 *Rezolvare detaliat 13.2.3 Cod surs Listing 13.2.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 robot_adriana.cpp //Adriana Simulescu #include <fstream> #include <iostream> #include <cmath> using namespace std; int main() { int N,i,cod,h,m,s,ok,cod1,cod2,ap[10],c,c1,j,T,t,v,r, ncorecte=0,cif,ci,cp,pp,p2,pi; ifstream in("robot.in"); ofstream out("robot.out"); in>>T; in>>N>>h>>m>>s; in>>t>>v>>r; if(T==2) for(i=1;i<=N;i++) { in>>cod; cod2=0; ci=0;cp=0;pp=1;pi=1; for(cif=1;cif<=9;cif=cif+2) { cod1=cod; while(cod1>0) { if(cod1%10==cif) { cod2=cod2*10+cif;ci++; pi*=10; } cod1/=10; } } for(cif=8;cif>=0;cif=cif-2) { cod1=cod; acesta conµine: a num rului construit cu cifra 9 0 la sfâr³it CAPITOLUL 13. 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 ONI 2017 while(cod1>0) { if(cod1%10==cif) { cod2=cod2*10+cif; cp++; pp*=10; } cod1/=10; } } if(cod==cod2&&ci*cp!=0) out<<cod<<’\n’; else { if(ci*cp!=0) out<<cod2<<’\n’; else { if(ci==0) cod2=cod2%(pp/10)+9*(pp/10); else cod2=cod2%(pi/10)*10; out<<cod2<<’\n’; } } } else { for(i=1;i<=N;i++) { in>>cod; cod2=0; ci=0;cp=0;pp=1;pi=1; for(cif=1;cif<=9;cif=cif+2) { cod1=cod; while(cod1>0) { if(cod1%10==cif) { cod2=cod2*10+cif;ci++; pi*=10; } cod1/=10; } } for(cif=8;cif>=0;cif=cif-2) { cod1=cod; while(cod1>0) { if(cod1%10==cif) { cod2=cod2*10+cif;cp++; pp*=10; } cod1/=10; } } if(cod==cod2&&ci*cp!=0) { ncorecte++; } } s=s+(N-1)*(t+v)+(N-ncorecte)*r+v; m=m+s/60; s=s%60; h=h+m/60; m=m%60; out<<h<<" "<<m<<" "<<s<<"\n"; } 181 CAPITOLUL 13. 115 116 117 118 182 ONI 2017 in.close(); out.close(); return 0; } Listing 13.2.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 //Carmen Popescu #include <fstream> using namespace std; ifstream f("robot.in"); ofstream g("robot.out"); long long verif(long long x) { int cif[10]={0}; long long y=0; int np=0,ni=0,i,j; while (x>0) { cif[x%10]++; if (x%2==0) np++; else ni++; x=x/10; } if (np==0) { for (i=1;i<=9;i+=2) if (cif[i]>0) { cif[i]--; cif[0]=1; break; } } else if (ni==0) { for (i=8;i>=0;i-=2) if (cif[i]>0) { cif[i]--; cif[9]=1; break; } } y=0; for (i=1;i<=9;i+=2) for (j=0;j<cif[i];j++) y=y*10+i; for (i=8;i>=0;i-=2) for (j=0;j<cif[i];j++) y=y*10+i; return y; } int main() { int c,n,h,m,s,t,v,r,i; long long u,x,y; f>>c; f>>n>>h>>m>>s>>t>>v>>r; for { (i=0;i<n;i++) f>>x; robot_cp.cpp CAPITOLUL 13. 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 183 ONI 2017 y=verif(x); if (x!=y) { s=s+r; if (s>60) { s-=60; m++; if (m>60) { m-=60; h++; } } } if (c==2) g<<y<<’\n’; } if (c==1) { s=s+t*(n-1)+v*n; m=m+s/60; s=s%60; h=h+m/60; m=m%60; g<<h<<" "<<m<<" "<<s<<"\n"; } return 0; } Listing 13.2.3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 robot_ema.cpp //Emanuela Cerchez #include <fstream> using namespace std; ifstream fin("robot.in"); ofstream fout("robot.out"); int cerinta, n, h,m,s, v, r,t, nr; int main() {int i, rez, cx, x, cate, maxpar, minimpar, p10, corect, c, uc, j, timp, hf, mf, sf; fin>>cerinta; fin>>n>>h>>m>>s>>t>>v>>r; if (cerinta ==1) { for (i=1; i<=n; i++) { fin>>x; corect=1; cx=x; if (x%2==1) corect=0; else { c=x%10; x/=10; while (x>0 && x%2==0) { uc=x%10; if (uc<c) corect=0; c=uc; x=x/10; } if (x==0) corect=0; else {c=x%10; x/=10; while (x>0) { uc=x%10; if (uc%2==0) corect=0; if (uc>c) corect=0; c=uc; x/=10; } CAPITOLUL 13. 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 184 ONI 2017 } } if (corect) nr++; } timp=h*3600+m*60+s+(n-nr)*r+t*(n-1)+v*n; hf=timp/3600; timp=timp%3600; mf=timp/60; sf=timp%60; fout<<hf<<’ ’<<mf<<’ ’<<sf<<’\n’; } else { for (i=1; i<=n; i++) { fin>>x; corect=1; cx=x; if (x%2==1) corect=0; else { c=x%10; x/=10; while (x>0 && x%2==0) {uc=x%10; if (uc<c) corect=0; c=uc; x=x/10; } if (x==0) corect=0; else {c=x%10; x/=10; while (x>0) { uc=x%10; if (uc%2==0) corect=0; if (uc>c) corect=0; c=uc; x/=10; } } } if (corect) {nr++; rez=cx;} else { rez=0; minimpar=10; maxpar=-1; p10=1; for (c=1; c<10; c+=2) { x=cx; cate=0; while (x) {if (x%10==c) cate++; x/=10; } for (j=0; j<cate; j++) {rez=rez*10+c; p10*=10;} if (cate && minimpar==10) minimpar=c; } for (c=8; c>=0; c-=2) { x=cx; cate=0; while (x) {if (x%10==c) cate++; x/=10;} for (j=0; j<cate; j++) {rez=rez*10+c; p10*=10;} if (cate && maxpar==-1) maxpar=c; } p10/=10; if (maxpar==-1) rez=(rez%p10)*10; if (minimpar==10) rez=9*p10+rez%p10; } fout<<rez<<’\n’; } } fout.close(); return 0; } Listing 13.2.4: 1 2 //Jakab Tunde #include <iostream> robot-JT.cpp CAPITOLUL 13. 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 ONI 2017 #include <fstream> using namespace std; ifstream f("robot.in"); ofstream g("robot.out"); int main() {int n,p,h,m,s,t,v,r,ok,a,b,c,i,d; unsigned long long T=0; f>>p; if(p==1) { f>>n>>h>>m>>s; f>>t>>v>>r; b=0; for(i=1;i<=n;i++) { f>>a; T=T+t+v; d=a; ok=1; if(a%2!=0)ok=0; else { c=a%10; a=a/10; while(c<=a%10 and a%2!=1) { c=a%10; a=a/10; } c=a%10; a=a/10; if(c%2==0)ok=0; else { while(c>=a%10 and a%2==1) { c=a%10; a=a/10; } if(a!=0) ok=0; } } if(!ok) { T=T+r; int x=0,y=0,z1=1,z2=1,j,v; for(j=1;j<=9;j=j+2) { a=d; while(a!=0) { if(a%10==j){x=x*10+j;z1=z1*10;} a=a/10; } } for(j=8;j>=0;j=j-2) { a=d; while(a!=0) { if(a%10==j){y=y*10+j;z2=z2*10;} a=a/10; } } if(x==0) { 185 CAPITOLUL 13. 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 ONI 2017 z2=z2/10; v=9*z2+y%z2; } else if(y==0) if(z2>1)v=x*z2; else { z1=z1/10; v=(x%z1)*10; } else v=x*z2+y; } } T=T-t; h=h+T/3600; T=T%3600; m=m+T/60; T=T%60; s=s+T; if(s>=60) { m=m+s/60; s=s%60; } if(m>=60) { h=h+m/60; m=m%60; } g<<h<<’ ’<<m<<’ ’<<s; } if(p==2) { f>>n>>h>>m>>s; f>>t>>v>>r; b=0; for(i=1;i<=n;i++) { f>>a; T=T+t+v; d=a; ok=1; if(a%2!=0)ok=0; else { c=a%10; a=a/10; while(c<=a%10 and a%2!=1) { c=a%10; a=a/10; } c=a%10; a=a/10; if(c%2==0)ok=0; else { while(c>=a%10 and a%2==1) { c=a%10; a=a/10; } if(a!=0)ok=0; } } 186 CAPITOLUL 13. 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 187 ONI 2017 if(!ok) { T=T+r; int x=0,y=0,z1=1,z2=1,j,v; for(j=1;j<=9;j=j+2) { a=d; while(a!=0) { if(a%10==j){x=x*10+j;z1=z1*10;} a=a/10; } } for(j=8;j>=0;j=j-2) { a=d; while(a!=0) { if(a%10==j){y=y*10+j;z2=z2*10;} a=a/10; } } if(x==0) { z2=z2/10; v=9*z2+y%z2; } else if(y==0) if(z2>1)v=x*z2; else { z1=z1/10; v=(x%z1)*10; } else v=x*z2+y; g<<v<<endl; } else g<<d<<endl; } } } 13.3 roua - ONI 2017 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 celor N 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 colorare formeaz c o colorare este o secvenµ R-frumoas , dac roua. De exemplu, pentru N oricare R caractere consecutive din 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 . CAPITOLUL 13. 188 ONI 2017 Date de intrare Fi³ierul de intrare din problem roua.in conµine pe prima linie un num r natural C reprezentând cerinµa (1 sau 2). A doua linie din ³ier conµine numerele naturale N care trebuie rezolvat ³i R, separate prin spaµiu, reprezentând num rul de ou ³i lungimea unei secvenµe roua . Dac C colorarea celor N ou . 1, ³ierul va conµine ³i o a treia linie pe care se a Date de ie³ire Fi³ierul de ie³ire roua.out va conµine o singur reprezentând r spunsul la cerinµa specicat linie pe care va scris un num r natural, în ³ierul de intrare. Restricµii ³i preciz ri a 3 a 2 & N & 10000 &R$N a Pentru rezolvarea corect 2 se acord a cerinµei 1 se acord 60 de puncte. a Pentru 60% dintre testele pentru cerinµa 2, 3 40 puncte, pentru rezolvarea corect a cerinµei & N & 70 % 70 a Pentru 40% dintre testele pentru cerinµa 2, N 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 7 3 vrrrgrr N=7 ou . Secvenµele roua de lungime 3 existente în colorare sunt "vrr", "rrg", "rgr", "grr". 2 15 Cerinµa este 2. Exist 4 3 4 ou . Color rile 3-frumoase ale celor 4 ou sunt "grrg", "grrv", "grra", "vrrg", "vrrv", "vrra", "arrg", "arrv", "arra", "rgrr", "rvrr", "rarr", "rrgr", "rrvr", "rrar". Timp maxim de executare/test: 0.25 secunde Memorie: total 2 MB din care pentru stiv 1 MB Dimensiune maxim a sursei: 15 KB 13.3.1 Indicaµii de rezolvare Autor prof. Carda³ Cerasela-Daniela, Colegiul National A.T.Laurian Boto³ani Variabilele N ³i R memoreaz num rul de caractere, respectiv lungimea unei secvenµe roua. 1. În variabilele p1 ³i p2 memor m penultima, respectiv ultima poziµie a unui caracter diferit de 'r'. Pentru ecare caracter c citit din ³ier avem cazurile: c='r', increment m nr de secvenµe roua dac p1 < poziµia_curent - R ³i p2 > pozi- R b) c j 'r', increment m nr de secvenµe roua dac poziµia_curent - p2 ' R, actualiz m valorile lui p1 ³i p2. a) µia_curent 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 Calcul m a N %R, b orice poziµie de la 1 la R, în cadrul unei secvenµe. N ©R. Pentru deducerea formulei, analiz m mai întai cazul a a) Dac a 0, exist 0. în ³ir b grupe de c te R valori consecutive. Pentru o colorare R-frumoas , caracterul X poate avea o valoare din 3 valori posibile ³i ocup aceea³i poziµie în cadrul ec rei grupe. Poziµia caracterului X este o valoare de la 1 la R => putem forma b 3 color ri R-frumoase în care X ocup poziµia 1, b 3 color ri R-frumoase în care X ocup poziµia 2, CAPITOLUL 13. 189 ONI 2017 ..., b 3 color ri R-frumoase în care X ocup In total avem R 3 color ri posibile. a j 0, exist b) Dac poziµia R . b în ³ir b grupe de c te R valori ³i o grup cu ultimele a valori din ³ir . Pentru o colorare R-frumoas , caracterul X va ocupa b1 a3 color ri b - e o poziµie între a 1 ³i R în primele b grupe => se formeaz R a 3 color ri. - e o poziµie între 1 ³i a în b 1 grupe, caz în care se formeaz In total, num rul de color ri va b1 a3 Pentru N b R a 3 b = a3 3 b R a 3 b = 3 & 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 . 13.3.2 *Rezolvare detaliat 13.3.3 Cod surs Listing 13.3.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 b a 3 R a = 3 2 a R. roua_cardas.cpp //Cardas Daniela #include <fstream> using namespace std; ifstream in("roua.in"); ofstream out("roua.out"); int N,P,R,i,nroua,p1,p2,a,b,v[2500],x,p,j,ct; char c; int main() { in>>P; if(P==1) { in>>N>>R>>c;i=1; while(c==’r’&&i<N)in>>c,i++; if(c!=’r’){p2=i;if(p2>=R)nroua=1;} if(c==’r’&&i==N){out<<0<<’\n’;return 0;} for(i=p2+1; i<=N; i++) { in>>c; if(c!=’r’) { if(i-p2+1>R){nroua++;} p1=p2;p2=i; } else if(p1<=i-R&&i>=R&&p2>i-R){nroua++;} } out<<nroua<<’\n’; } else { ///P=2 in>>N>>R; a=N%R;b=N/R; if(N<=70) { long long p=1; for(i=1;i<=b;i++,p*=3); p=p*(2*a+R); out<<p<<’\n’; CAPITOLUL 13. 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 190 ONI 2017 return 0; } ///initializam vectorul de cifre cu numarul 2a+R x=2*a+R;i=0; while(x)v[++i]=x%10,x/=10; v[0]=i; ///inmultim vectorul de cifre v cu 3 de b ori for(i=1;i<=b;i++) { for(ct=0,j=1;j<=v[0];j++) { v[j]*=3; x=v[j]+ct;v[j]=x%10;ct=x/10; } if(ct) { v[0]++;v[v[0]]=ct; } } for(i=v[0];i>=1;i--) out<<v[i]; out<<’\n’; } } Listing 13.3.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 //Carmen Popescu #include <fstream> #include <iostream> using namespace std; ifstream f("roua.in"); ofstream g("roua.out"); int main() { int c,n,r,x,ct,i,j; char ch[10001]; long long v,p; f>>c; f>>n>>r; if (c==1) { x=0; ct=0; for (i=0;i<r;i++) { f>>ch[i]; if (ch[i]==’r’) x++; } if (x==r-1) ct++; for (i=r;i<n;i++) { f>>ch[i]; if (ch[i-r]==’r’) x--; if (ch[i]==’r’) x++; if (x==r-1) ct++; } g<<ct<<"\n"; } else { // 3^(n/r)*(2*(n%r)+r) int c[10001],nc=0; x=n/r; // 3^(n/r) nc=1; c[0]=1; roua_cp.cpp CAPITOLUL 13. 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 191 ONI 2017 for (i=1;i<=n/r;i++) { c[0]=3*c[0]; p=c[0]/10; c[0]=c[0]%10; for (j=1;j<nc;j++) { c[j]=3*c[j]+p; p=c[j]/10; c[j]=c[j]%10; } while (p>0) { c[nc++]=p%10; p=p/10; } } v=2*(n%r)+r; if (v>1) { p=0; for (i=0;i<nc;i++) { c[i]=v*c[i]+p; p=c[i]/10; c[i]=c[i]%10; } while (p>0) { c[nc]=p%10; nc++; p=p/10; } } for (i=nc-1;i>=0;i--) g<<c[i]; g<<"\n"; } return 0; } Listing 13.3.3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 //Jakab Tunde #include <fstream> using namespace std; ifstream f("roua.in"); ofstream g("roua.out"); int t[10001]; int main() {int p,r,n; f>>p>>n>>r; if(p==1) { int a=1,b=0,h; char c; f>>c; while(c==’r’ and a<=n) { f>>c; a++; } if(c==’r’)g<<0; else { if(a>=r)b++; h=a-1; for(int i=a+1;i<=n;i++) { roua_jt.cpp CAPITOLUL 13. 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 ONI 2017 f>>c; if(c==’r’) { if(i-a<r and i-a+h+1>=r)b++; } else { h=i-a-1; a=i; if (h>=r-1)b++; } } } g<<b; } else { int a,j,k,b=0,c; a=2*(n%r)+r; k=0; while(a>0) { t[++k]=a%10; a=a/10; } b=0; for(int i=1;i<=n/r;i++) { for(j=1;j<=k;j++) { c=t[j]*3+b; t[j]=c%10; b=c/10; } if(c>9)t[++k]=c/10; b=0; } for(int i=k;i>=1;i--) g<<t[i]; } f.close(); g.close(); return 0; } 192 Capitolul 14 ONI 2016 14.1 Norocos - ONI 2016 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 Dac C norocos.out. 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 niciun num r norocos se va a³a valoarea 0. Dac nu exist singur num r norocos, acesta se va a³a de dou Dac C exist un ori. 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 & N & 1000 & k & 30 a 1 & numerele citite de pe a treia linie a ³ierului & 2000000000 a 1 a 2 a Pentru rezolvarea corect a primei cerinµe se acord a celei de-a doua cerinµe se acord 60 de puncte. Exemple 193 40 de puncte, pentru rezolvarea corect CAPITOLUL 14. 194 ONI 2016 norocos.in norocos.out Explicaµii 1 5 165 Atenµie, C 1, deci se va rezolva doar prima 9 3 cerinµ . 165 12 33 30 5 18 105 15 4 Cel mai mic num r norocos este 5 2 5 =25=3+4+5+6+7 Cel 2 mai mare num r norocos 165 =27225=83+84+85+...+246+247 este 165 Ob- servaµi faptul c , de³i se cite³te valoarea lui aceasta nu este folosit 2 3 Atenµie, C k, în rezolvarea cerinµei 1. 2, deci se va rezolva doar a doua 5 3 cerinµ . 165 31 165 105 44 Cele trei numere k -norocoase sunt 165, 165, 105 Timp maxim de executare/test: 0.5 secunde Memorie: total 16 MB Dimensiune maxim a sursei: 15 KB 14.1.1 Indicaµii de rezolvare Ana-Maria Ari³anu ³i Cristian Frâncu a) 2 m este norocos m 2m 2ma m 1m 2 2 a a 1 a 2 ... a m 1 m ma m 1m©2 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 Trebuie s - S avem grij descompunem ecare num r x în factori primi. de urm toarele aspecte: 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. 14.1.2 *Rezolvare detaliat 14.1.3 Cod surs Listing 14.1.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 norocos.cpp #include <fstream> #include <cmath> using namespace std; int t, n, k, a, sol, d, e, nr, i, x, ok, r, amax = 0, amin = 2000000000; int main () { ifstream fin ("norocos.in"); ofstream fout("norocos.out"); fin>>t>>n>>k; for (i=1;i<=n;i++) { fin>>x; CAPITOLUL 14. 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 195 ONI 2016 if (t == 1 && x%2 == 1) { a++; if (x < amin) { amin = x; } if (x > amax) { amax = x; } } if (x == 1) continue; if (t == 2) { ok = 1; r = (int)sqrt(x); d = 2; nr = 0; while (x != 1 && d <= r) { if (x%d == 0) { e = 0; while (x%d == 0) { x /= d; e++; } if (e != 1) { ok = 0; break; } nr++; if (nr > k) { ok = 0; break; } } d++; } if (x!=1) if (nr != k) if (ok) nr++; ok = 0; sol++; } } if (t == 1) { if (a == 0) { fout<<a<<"\n"; } else { fout<<amin<<" "<<amax<<"\n"; } } else fout<<sol<<"\n"; return 0; } 14.2 Oglinda - ONI 2016 Problema 2 - Oglinda 100 de puncte Pentru un num r natural N se consider 1 & i & N. ³irul a Asupra acestui ³ir se pot aplica operaµii de dou a) la operaµia de tipul 1 se specic dou 1, 2, 3..., N , deci ai tipuri: valori i ³i j , cu 1 i pentru orice i, & 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 operaµia 3 6, atunci ³irul devine a 1, 2, 6, 5, 4, 3, 7. Iar în ³irul a 1, 2, 3, 4, 5, 6, 7 se aplic 1, 4, 3, 2, 5, 6, 7, dac se CAPITOLUL 14. aplic operaµia 4 6, atunci a b) Operaµia de 196 ONI 2016 1, 4, 3, 6, 5, 2, 7. tipul 2 conµine un indice i, 1 & i & N , ³i cere s a³ m valoarea elementului în acel moment pe poziµia i în ³ir. care se a M astfel de operaµii într-o ordine dat . Se consider Cerinµe Scrieµi un program care s determine ³i s a³eze rezultatul pentru ecare operaµie de tipul 2. Date de intrare oglinda.in conµine pe prima linie dou numere naturale N ³i M , separate Fi³ierul de intrare printr-un spaµiu. Pe ecare dintre urm toarele M linii este specicat sau 2. O linie poate s conµin dou sau trei numere, astfel: câte o operaµie de tipul 1 1 i j (indicând o operaµie de tipul 1) respectiv 2 i (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 oglinda.out conµine un num r de linii egal cu num rul de operaµii de tipul 2 Fi³ierul de ie³ire care sunt denite în ³ierul de intrare. Pe ecare linie este a³at câte un num r natural reprezintâ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 a 1 & N & 1000000 & M & 2000 & N & 2000. 1 & i & j & N la operaµiile de tipul 1 ³i c 1 & i & N la operaµiile de tip 2. exist cel puµin o operaµie de tipul 2. a Pentru teste în valoare de 40 de puncte, vom avea 1 a Se garanteaz c a Se garanteaz c Exemple oglinda.in oglinda.out Explicaµii 10 4 3 irul iniµial este: 1 2 3 4 5 6 7 8 9 10 2 3 6 Rezultatul operaµiei 2 3 are ca efect a³area elementului de pe 1 2 7 1 poziµia 3 (care este chiar 3). 2 3 Rezultatul operaµiei 1 2 7 are ca efect transformarea ³irului în: 2 1 1 7 6 5 4 3 2 8 9 10. Rezultatul operaµiei 2 3 are ca efect a³area elementului de pe poziµia 3 (care acum este 6). Rezultatul operaµiei 2 1 are ca efect a³area elementului de pe poziµia 1 (care acum are valoarea 1). Timp maxim de executare/test: 0.3 secunde Memorie: total 16 MB Dimensiune maxim a sursei: 15 KB 14.2.1 Indicaµii de rezolvare prof. Marius Nicoli, C.N. Fraµii Buze³ti, Craiova O prim abordare a problemei se face prin simularea operaµiilor date pe un vector cu componente. Aceast soluµie nu se încadreaz N în timp pe toate testele. Pentru punctaj maxim se poate proceda astfel: se reµin operaµiile de tip 1 în doi vectori unul pentru capetele stânga ale intervalelor de indici date ³i altul pentru capetele din dreapta. La întâlnirea unei operaµii de tip 2 se determin pe a current prin aplicarea în ordine invers valoarea iniµial de pe poziµia a, actualizând a operaµiilor de tip 1 întâlnite pân atunci. Informaµii despre aceste operaµii le g sim în cei doi vectori. La o operaµie de tip 1 s, d (memorat pe a doar dac în vector în momentul apariµiei sale), aceasta afecteaz a este cuprins între s ³i d (inclusiv). Timpul de executare este de ordinul m m (m este num rul de operaµii). CAPITOLUL 14. 197 ONI 2016 14.2.2 *Rezolvare detaliat 14.2.3 Cod surs Listing 14.2.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 oglinda.cpp #include <fstream> #define DIMM 2010 using namespace std; int S[DIMM], D[DIMM]; int n, m, i, j, a, b, t, k, x; int main () { ifstream fin ("oglinda.in"); ofstream fout("oglinda.out"); fin>>n>>m; for (i=1;i<=m;i++) { fin>>t; if (t == 1) { k++; fin>>S[k]>>D[k]; } else { fin>>a; for (j=k; j>=1; j--) { if (S[j] <= a && a <= D[j]) { x = a - S[j]; a = D[j] - x; } } fout<<a<<"\n"; } } return 0; } 14.3 Perechi - ONI 2016 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 valoarea egal obµinut s nu dep ³easc se obµin ³irul cu toate elementele egale, dar 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 14. 198 ONI 2016 Date de ie³ire Fi³ierul perechi.out va conµine 1. Dac C 0 dac 1, atunci se va rezolva doar prima cerinµ , deci se va a³a pe prima linie valoarea nu se pot obµine în ³ir toate elementele egale, sau se vor a³a trei numere naturale i j v cu semnicaµia: la poziµiile i ³i j din ³ir se adaug valoarea v ³i astfel toate elementele vectorului vor deveni egale. C 2, atunci se va rezolva doar a doua cerinµ . Pe ecare linie a ³ierului de ie³ire valoarea v la ai ³i la aj (unde i ³i j sunt distincte ³i sunt cuprinse între 1 ³i n). 2. Dac se vor a³a exact trei valori i j v cu semnicaµia: se adun Restricµii ³i preciz ri a 5 a 0 & n $ 2000, n este impar & 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 a Dac num rul operaµiilor aplicate este mai mic sau egal decât n iar valoarea nal cel mult dou mai multe soluµii, puteµi a³a oricare dintre ele ori cât maximul iniµial ³i rezultatul aplic rii operaµiilor furnizeaz este de în ³ir aceea³i valoare, atunci veµi primi 100% din punctaj num rul ope raµiilor este cuprins între n 1 ³i 2n iar valoarea nal a Dac dou ori cât maximul iniµial ³i rezultatul aplic rii operaµiilor furnizeaz este de cel mult î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 maxime iniµiale, atunci veµi primi 0 puncte . De asemenea, dac se obµine un ³ir cu aceea³i valoare peste tot, sau dac dep ³e³te dublul valorii în urma operaµiilor aplicate nu 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 1 5 8 2 8 8 2 perechi.out Explicaµii 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 5 3 4 4 din ³ir este 10, deci valoarea nal 2, deci se va rezolva doar a doua cerinµ ! Valoarea maxim 8 5 6 3 10 2 4 3 Trebuie efectuate cel mult 5 operaµii pentru 100 puncte. trebuie s e maximum 20. 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 8 2 7 8 2 egale. operaµie astfel încât toate elementele ³irului s 2 1 3 1 C 3 1 2 2 din ³ir este 3, deci valoarea nal 1 2 3 devin 2, deci se va rezolva doar a doua cerinµ ! Valoarea maxim trebuie s e maximum 6. Trebuie efectuate cel mult 3 operaµii pentru 100 puncte. Aplicând operaµia 1 3 1, obµinem ³irul 2 2 4 Aplicând operaµia 1 2 2, obµinem ³irul 4 4 4 Timp maxim de executare/test: 0.5 secunde Memorie: total 16 MB Dimensiune maxim a sursei: 15 KB 14.3.1 Indicaµii de rezolvare prof. Dan Pracsiu, Liceul Teoretic Emil Racoviµ Cerinµa 1 Vaslui CAPITOLUL 14. Se veric 199 ONI 2016 dac în ³ir sunt doar dou valori distincte, una care apare de 2 ori, cealalt apare de n 2 ori. În caz armativ, se veric decât cealalt dac valoarea care apare de dou care ori este mai mic 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 sortat (cele mai mici). Fie acestea a ³i b cu a elemente ale ³irului & 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 Deci acum valoarea maxim poziµii vom avea valorile max ³i b max a ( în ³ir, max, se a & max). 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 ³i b max a. 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). 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. În acest moment am efectuat (n-1) Vom aduna la toate cuplurile egale atât cât este necesar s înc 14.3.2 *Rezolvare detaliat 14.3.3 Cod surs Listing 14.3.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ajungem la valoarea maxim (n-1) div 2 operaµii). În total am efectuat n 1 operaµii, deci ne încadr m în limita de n operaµii efectuate. #include <fstream> #define inFile "perechi.in" #define outFile "perechi.out" #define Dim 10005 using namespace std; int a[Dim]; int P[Dim]; int n; void Cerinta1() { int i, cnt; ofstream fout(outFile); /// verifica nr de numere diferite cnt = 1; for (i = 2; i <= n; ++i) if (a[i] != a[i - 1]) cnt++; if (cnt != 2 || a[2] == a[3]) { fout << "0\n"; fout.close(); return ; } cnt = a[3] - a[2]; fout<<P[1]<<" "<<P[2]<<" "<<cnt<<"\n"; fout.close(); perechi.cpp (deci CAPITOLUL 14. 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 ONI 2016 } void Cerinta2() { int i, ultim, v; ofstream fout(outFile); ultim = n; for (i = 1; i < n; i += 2) { v = a[ultim] - a[i]; if (v > 0) { a[i] += v; a[i + 1] += v; fout << P[i] << " " << P[i + 1] << " " << v << "\n"; a[++ultim] = a[i]; P[ultim] = P[i]; a[++ultim] = a[i + 1]; P[ultim] = P[i + 1]; } } for ( ; i < ultim; i += 2) { v = a[ultim] - a[i]; if (v > 0) { a[i] += v; a[i + 1] += v; fout << P[i] << " " << P[i + 1] << " " << v << "\n"; } } fout.close(); } int main() { int i, j, C; int aux; //citire ifstream fin(inFile); fin >> C; fin >> n; for (i = 1; i <= n; ++i) { fin >> a[i]; P[i] = i; } fin.close(); //sortare for (i = 1; i < n; ++i) for (j = i + 1; j <= n; ++j) if (a[i] > a[j]) { aux = a[i]; a[i] = a[j]; a[j] = aux; aux = P[i]; P[i] = P[j]; P[j] = aux; } if (C == 1) Cerinta1(); else Cerinta2(); return 0; } 200 Capitolul 15 ONI 2015 15.1 iepuras - ONI 2015 Problema 1 - iepuras Iepura³ul Cocona³ vrea s prin salturi o zon ajung la gr dina cu morcovi. Pentru aceasta el trebuie s cu propriet µi speciale. Zona este format N , dispuse una dup de energie necesar c suµ 100 de puncte cealalt , iar ecare c suµ conµine un num r natural ce reprezint iepura³ului pentru a s ri într-o alt c suµ . Iepura³ul pleac ³i se deplaseaz , de la stânga la dreapta, spre gr dina cu morcovi dup a num rul înscris în c suµa în care se a traverseze din N c suµe numerotate de la 1 la iepura³ul reprezint cantitatea dintr-o anumit urm toarele reguli: 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 se dubleaz iepura³ul este num r prim, atunci energia lui ³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 a dac iepura³ul ajunge într-o c suµ mai are energie s sar 3 2 5). care conµine num rul 0, el r mâne acolo pentru c mai departe, altfel el continu a iepura³ul ajunge la gr dina cu morcovi dac s sar dup nu regulile descrise mai sus; 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 de ie³ire valoarea lui P este 1, se va rezolva numai punctul 1) din cerinµe. În acest caz, ³ierul iepuras.out va conµine pe prima linie cuvântul DA în cazul în care iepura³ul a ajuns în 201 CAPITOLUL 15. 202 ONI 2015 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 de ie³ire valoarea lui P este 2, se va rezolva numai punctul 2) din cerinµe. În acest caz, ³ierul 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 & N & 7000 &K&N a 0 & numerele conµinute în c suµe & 100 a 1 a 1 a Pentru rezolvarea corect a primei cerinµe se acord Exemple iepuras.in 30 de puncte, pentru rezolvarea corect 70 de puncte. a celei de a doua cerinµe se acord iepuras.out Explicaµii NU P 2 Iepura³ul pleac 1, pentru acest test, se rezolva cerinµa 1). 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 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 cerinµa din c suµa cu num rul de ordine 2 ³i sare, pe rând, în c suµele cu numerele de ordine 8, 9, 13, ³i apoi în gr din , traversând astfel 13 c suµe (de la c suµa 2 la c suµa 14). Iepura³ul nu s-a aat sau nu a s rit în c suµele de pe poziµiile 1, 3, 4, 5, 6, 7, 10, 11, 12 ³i 14. Timp maxim de executare/test: 1.0 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 10 KB 15.1.1 Indicaµii de rezolvare Soluµia 1 Cerinµa 1 Memor m traseul cu c suµe într-un vector pe poziµiile de la 1 pâna la N . Pornim parcurgerea vectorului de la poziµia k ³i parcurgem vectorul cât timp valoarea gasit în c suµ este diferit de 0 ³i indicele c suµei este mai mic sau egal cu N . Cre³tem indicele vectorului cu valoarea care se g se³te memorat este prim sau cu dublul valorii care se g se³te în c suµ dac în c suµ dac num rul nu num rul este prim. Increment m num rul de salturi pe care le face iepura³ul. Algoritmul se repet pân când ajungem într-o c suµ care conµine num rul 0 sau pân când indicele calculat dep ³e³te valoarea N . Dac indicele la care ajungem este mai mic sau egal cu N , iepura³ul nu ajunge la gr dina cu morcovi ³i scriem N U , 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 15. Dac 203 ONI 2015 indicele c suµei la care ajunge iepura³ul este mai mare strict decat N atunci num rul de c suµe = N - poziµia de pornire + 1 altfel num rul de c suµe = indicele c suµe - poziµia de pornire + 1. Actualiz m maximum ³i poziµia de pornire. Repet m algoritmul pentru restul c suµelor pân la N . Scriem poziµia de pornire ³i valoarea num rului maxim de c suµe în ³ier. Scriem toate c suµele de la 1 pân la c suµa de pornire determinat mai sus apoi scriem toate c suµele de pe traseul iepura³ului, cu excepµia c suµei de pornire ³i a celor în care a s rit. Dac ultima c suµ c suµelor pân în care ajunge iepura³ul are indicele strict mai mic decât N , scriem restul la N . Soluµia are complexitatea O 2 n . Soluµia 2 Cerinµa 1 Se memoreaz Se simuleaz c suµ numerele din casuµe într-un vector v . s riturile iepura³ului ce porne³te din c suµa k ³i se opreste e când ajunge la o ce conµine num rul 0 e când ajunge în gr dina cu morcovi. Cerinµa 2 Pentru a determina num rul maxim de c suµe traversate se construie³te începând cu poziµia n, un vector suplimentar a cu semnicaµia: ai = poziµia în care se opre³te iepura³ul ce porne³te din c suµa cu num rul i. ai ~ n; i; ai 2 ai; ai ai; dac pornim din poziµia i iepura³ul ajunge în gr din dac ai 0 ai este num r prim ai nu este num r prim dac dac Pentru ecare poziµie i, începând cu poziµia n se determin ind l ai i 1 ³i se actualizeaz 15.1.2 *Rezolvare detaliat 15.1.3 Cod surs Listing 15.1.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream> #include <fstream> #include <cmath> using namespace std; const int DIM=100000; int v[DIM],x[101]; /*void afisare(int N, unsigned int v[DIM]) { int i; for(i=1;i<=N;i++) cout<<v[i]<<’ ’; cout<<endl; }*/ void prim(int n) { int i,j; for (i=2;i<=n;i++) x[i]=1; for (i=2;i<=sqrt(n);i++) if (x[i]) num rul c suµelor traversate ca valoarea maxim , reµinându-se poziµia. iepuras_1.cpp CAPITOLUL 15. 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 ONI 2015 for (j=i;j<=n/i;j++) x[i*j]=0; } int main() { int N, K, P, i, j, l, nr=0, Max=0, poz; //nr-numar salturi din pozitia i ifstream in("iepuras.in"); ofstream out("iepuras.out"); in>>P>>N>>K; for(i=1;i<=N;i++) in>>v[i]; prim(100); if(P==1) { //cerinta 1 j=K; nr=0; while(v[j] && j<=N) { nr++; if(x[v[j]]) j+=2*v[j]; else j+=v[j]; } if(j<=N) { out<<"NU"<<endl; out<<nr; } else { out<<"DA"<<endl; out<<nr; } } else { //cerinta 2 i=1,j=1; while(i<=N && j<=N) { j=i;nr=1; while(v[j] && j<=N) { if(x[v[j]]) j+=2*v[j]; else j+=v[j]; } if(j>N) nr=N-i+1; else nr=j-i+1; if(nr>Max) poz=i, Max=nr; i++; } out<<poz<<’ ’<<Max<<’\n’; for(i=1;i<=poz-1;i++) out<<v[i]<<’ ’; j=poz; for(i=1;i<=Max && i<=N;i++) { if(x[v[j]]) j+=2*v[j]; else j+=v[j]; for(l=poz+1;l<j && l<=N;l++) 204 CAPITOLUL 15. 100 101 102 103 104 105 106 107 108 109 205 ONI 2015 out<<v[l]<<’ ’; poz=j; } for(i=j+1;i<=N;i++) out<<v[i]<<’ ’; } return 0; } Listing 15.1.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 iepuras_2.cpp #include <cstdio> #include <cassert> using namespace std; int i, N, A[100005], Countstep, step, P, K, bool Prim[100]; Pos, Count, CountMax; bool prim(int x) { for(int d=2; d*d<=x; d++) if(x%d==0) return false; return (x>=2); } int main() { freopen("iepuras.in", "r",stdin); freopen("iepuras.out","w",stdout); scanf("%d\n%d%d\n",&P, &N, &K); assert(P>0&& P<3 && N>=1 && N<=7000); for(int i=1; i<=N; i++) { scanf("%d", &A[i]); assert( A[i]>=0 && A[i]<=100); } for(int i=2; i<=100; i++) Prim[i]=prim(i); if(P==1) { Countstep=0; for(i=K; i<=N && A[i]; i+=step, Countstep++) { if (Prim[A[i]]) step=A[i]*2; else step=A[i]; } if (i>N) printf("DA\n%d", Countstep); else printf("NU\n%d", Countstep); } else { CountMax=0; for(int I=1; I<=N ; I++) { for(i=I; i<=N && A[i]; i+=step) { if (Prim[A[i]]) step=A[i]*2; else step=A[i]; } if (i>N) i = N; if(i- I + 1>CountMax) { CountMax=i- I + 1; Pos = I; } } CAPITOLUL 15. 63 64 65 66 67 68 69 70 71 72 73 206 ONI 2015 printf("%d %d\n", Pos, CountMax); for(i=1; i<=N; i++) if(i!=Pos) printf("%d ", A[i]); else if (Prim[A[i]]) Pos+=A[i]*2; else Pos+=A[i]; } return 0; } Listing 15.1.3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 iepuras_3.cpp #include <cstdio> #include <cassert> using namespace std; int i, N, A[100005],Countstep, step, P, K, bool Prim[100]; Pos, Count, CountMax; bool prim(int x) { for(int d=2; d*d<=x; d++) if(x%d==0) return false; return (x>=2); } int main() { freopen("iepuras.in", "r",stdin); freopen("iepuras.out","w",stdout); scanf("%d\n%d%d\n",&P, &N, &K); for(int i=1; i<=N; i++) { scanf("%d", &A[i]); } for(int i=2; i<=100; i++) Prim[i]=prim(i); if(P==1) { Countstep=0; for(i=K; i<=N && A[i]; i+=step, Countstep++) { if (Prim[A[i]]) step=A[i]*2; else step=A[i]; } if (i>N) printf("DA\n%d", Countstep); else printf("NU\n%d", Countstep); } else { CountMax=0; for(int I=1; I<=N ; I++) { for(i=I; i<=N && A[i]; i+=step) { if (Prim[A[i]]) step=A[i]*2; else step=A[i]; } if (i>N) i = N; if(i- I + 1>CountMax) { CountMax=i- I + 1; Pos = I; } } printf("%d %d\n", Pos, CountMax); CAPITOLUL 15. 62 63 64 65 66 67 68 69 70 71 207 ONI 2015 for(i=1; i<=N; i++) if(i!=Pos) printf("%d ", A[i]); else if (Prim[A[i]]) Pos+=A[i]*2; else Pos+=A[i]; } return 0; } Listing 15.1.4: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #include <fstream> #include <iostream> using namespace std; int prim (int x) { if (x<2) return 0; if (x==2) return 1; if (x%2==0) return 0; for (int i=3; i*i<=x; i++) if (x%i==0) return 0; return 1; } int v[100001]; int a[100001]; int main() { ifstream f("iepuras.in"); ofstream g("iepuras.out"); int n,p,k,i,j,nr=0,l; f>>p>>n>>k; for (i=1; i<=n; i++) f>>v[i]; if (p==1) { while (k<=n && v[k]!=0) { nr++; if (prim (v[k])) k=k+2*v[k]; else k=k+v[k]; } if (k>n) g<<"DA"<<’\n’<<nr<<’\n’; else g<<"NU"<<’\n’<<nr<<’\n’; } else { int vm=-1; for (i=n; i>=1; i--) { if (v[i]==0) a[i]=i; else if (prim(v[i])) { j=i+2*v[i]; if (j<n) a[i]=a[j]; else a[i]=n; } else { j=i+v[i]; if (j<n) a[i]=a[j]; else a[i]=n; } l=a[i]-i+1; iepuras_4.cpp CAPITOLUL 15. 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 208 ONI 2015 if (vm<=l){vm=l; k=i;} } g<<k<<’ ’<<vm<<’\n’; int u=1; for (i=1; i<k; i++) g<<v[i]<<’ ’; while (k<=n && v[k]!=0) { u=k+1; if (prim (v[k])) k=k+2*v[k]; else k=k+v[k]; if (k<=n) else for (i=u; i<k; i++) g<<v[i]<<’ ’; for (i=u; i<=n; i++) g<<v[i]<<’ ’; } if (k<n && v[k]==0) for (i=k+1; i<=n; i++) g<<v[i]<<’ ’; g<<’\n’; } return 0; } Listing 15.1.5: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <fstream> #include <cassert> using namespace std; int prim (int x) { if (x<2) return 0; if (x==2) return 1; if (x%2==0) return 0; for (int i=3; i*i<=x; i++) if (x%i==0) return 0; return 1; } int v[100001]; int a[100001]; int main() { ifstream f("iepuras.in"); ofstream g("iepuras.out"); int n,p,k,i,j,nr=0,l,x; f>>p>>n>>k; i=0; while (f>>x) { i++; v[i]=x; assert (v[i]>=0&&v[i]<=100); } assert(p==1||p==2); assert(n>=1&& n<=7000); assert(k<=n && k>=1); assert(i==n); if (p==1) { while (k<=n && v[k]!=0) { nr++; if (prim (v[k])) k=k+2*v[k]; iepuras_5.cpp CAPITOLUL 15. 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 209 ONI 2015 else k=k+v[k]; } if (k>n) g<<"DA"<<’\n’<<nr<<’\n’; else g<<"NU"<<’\n’<<nr<<’\n’; } else { int vm=-1; for (i=n; i>=1; i--) { if (v[i]==0) a[i]=i; else if (prim(v[i])) { j=i+2*v[i]; if (j<n) a[i]=a[j]; else a[i]=n; } else { j=i+v[i]; if (j<n) a[i]=a[j]; else a[i]=n; } l=a[i]-i+1; if (vm<=l){vm=l; k=i;} } g<<k<<’ ’<<vm<<’\n’; int u=1; for (i=1; i<k; i++) g<<v[i]<<’ ’; while (k<=n && v[k]!=0) { u=k+1; if (prim (v[k])) k=k+2*v[k]; else k=k+v[k]; if (k<=n) else for (i=u; i<k; i++) g<<v[i]<<’ ’; for (i=u; i<=n; i++) g<<v[i]<<’ ’; } if (k<n && v[k]==0) for (i=k+1; i<=n; i++) g<<v[i]<<’ ’; g<<’\n’; } return 0; } Listing 15.1.6: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <fstream> #include <math.h> #define MAX 100 using namespace std; ifstream f("iepuras.in"); ofstream g("iepuras.out"); bool c[MAX],e1[100001]; int e[100001],salturi,N,P,M,K,pozMin,nrMax; int main() { int i,j,aux; c[1]=1; iepuras_6.cpp CAPITOLUL 15. 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 210 ONI 2015 //generare ciur M=sqrt(MAX); for(i=2;i<=M;i++) if(c[i]==0) for(j=i*i;j<=MAX;j+=i)c[j]=1; //citire f>>P>>N>>K; for(i=1;i<=N;i++)f>>e[i]; if(P==1)//1) { //sarituri iepure for(i=K;i<=N;) if(e[i]==0)break; else { salturi++;aux=e[i];if(c[aux]==0)aux*=2; i=i+aux; } //verficare if(i<=N)g<<"NU"<<’\n’;else g<<"DA"<<’\n’; g<<salturi<<’\n’; } else//2) { for(i=1;N-i>nrMax;i++) { //caut nrMax si pozMin j=i; while(j<=N && e[j]!=0) { if(c[e[j]]==0)j+=2*e[j]; else j+=e[j]; } if(j>N)salturi=N-i+1; else salturi=j-i+1; if(salturi>nrMax) {nrMax=salturi;pozMin=i;} } //afisez pozMin si nrMax g<<pozMin<<’ ’<<nrMax<<’\n’; //afisez casutele pana la pozMin for(i=1;i<pozMin;i++) g<<e[i]<<’ ’; //fac traseul maxim for(i=pozMin;i<=N;) { e1[i]=1; if(e[i]==0)break; else { aux=e[i];if(c[aux]==0)aux*=2;i+=aux;e1[i]=1; } } //afisez casutele de la pozMin pana unde a mers for(i=pozMin;i<=pozMin+nrMax-1;i++) if(e1[i]==0)g<<e[i]<<’ ’; //afisez casutele pana la N for(;i<=N;i++)if(e1[i]!=-1)g<<e[i]<<’ ’; g<<’\n’; } f.close(); g.close(); return 0; } CAPITOLUL 15. 15.2 211 ONI 2015 inventie - ONI 2015 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 corect num rul divizorilor pari pentru rezultatul obµinut prin operaµia smile. primit N perechi de numere a, b pentru care trebuie s calculeze a b ³i s determine Astfel, Mihai a 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 care nu are divizori pari. b) cel mai mic ³i cel mai mare rezultat a 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 divizori pari, atunci, pe linia N 1 se va a³a cel b care nu are divizori pari, ³i pe linia N 2 se va a³a cel mai mare rezultat s-a obµinut m car un rezultat f r mai mic rezultat a 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 13 13 9761512 9761512, ambele numere având divizori pari. 268 1244 0 Timp maxim de executare/test: 0.5 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 10 KB se obµin, în ordine, valorile 26, CAPITOLUL 15. 15.2.1 212 ONI 2015 Indicaµii de rezolvare Rezultatul "invenµiei" se obµine prin concatenarea valorilor ¶a b¶ si a b. Un caz special este cazul a b, cand rezultatul este a b. Numerele care au 0 divizori pari sunt numerele impare, prin urmare pentru a doua cerinµ intereseaz a, b în care a b este num r par, adic ne perechile a, b în care a ³i b minimul ³i maximul dintre rezultatele obµinute din perechile a, b cu a ³i b având doar perechile au parit µi diferite. Se determin parit µi diferite. Numerele a ³i b având maxim 18 cifre, rezultatul invenµiei poate un num r mare, deci trebuie efectuate comparaµii între numere mari. 15.2.2 *Rezolvare detaliat 15.2.3 Cod surs 15.3 mesaj - ONI 2015 Problema 3 - mesaj 100 de puncte În µara lui Piticot cuvintele au doar dou doua o minuscul litere, prima ind o majuscul mic ). Piticii Mi ³i Gi se distreaz (liter (liter mare) iar a ³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 al turate, este numit a o secvenµ ori, pe poziµii terminator; se încheie când s-a întâlnit o succesiune de litere ter- minator; a cuvântul este format din prima majuscul secvenµ , f r a lua în seam a o secvenµ ascunde un cuvânt dac conµine cel puµin o liter ³i ultima minuscul din Figura 15.1: mesaj litera terminator a secvenµei; mare ³i o liter terminatorul s u se repet de exact dou ori ³i dac 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. s f u E e t R u E E ascunde un cuvânt deoarece conµine ³i majuscule 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). De exemplu secvenµa ³i minuscule, iar litera terminator de secvenµ , La primirea mesajului, piticul Gi determin , pentru ecare majuscul , costul maxim al cuvintelor 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. 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 sau 3. 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. CAPITOLUL 15. 213 ONI 2015 Date de ie³ire Dac ie³ire valoarea lui P este 1, se va rezolva numai punctul 1) din cerinµe. În acest caz, ³ierul de mesaj.out va conµine pe prima linie un num r natural reprezentând r spunsul la cerinµa 1). Dac ie³ire valoarea lui P este 2, se va rezolva numai punctul 2) din cerinµe. În acest caz, ³ierul de 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 ie³ire valoarea lui P este 3, se va rezolva numai punctul 3) din cerinµe. În acest caz, ³ierul de 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µ 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 4) j j natorul se repet 5) i M o e i t t t a secvenµa a ³asea nu conµine majuscule. ³i a patra deoarece conµin numai deoarece termi- de mai mult de dou ori; 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µ 1) u N a a dou are terminatorul a care se repet 2) e D o r F D o r r A doua secvenµ 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. are terminatorul r ³i ascunde cu- 6) j w w 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: de ori ³i ascunde cuvântul Nu CAPITOLUL 15. 214 ONI 2015 Textul conµine cinci secvenµe: Cuvintele transmise în mesaj sunt 1) A a t t Aa (cost 2) 2) B b B t t Bb (cost 3) 3) e A e a n n Aa (cost 2) 4) B w I I Bw (cost 2) 5) F i e F F Fe (cost 4) Costul maxim al cuvintelor care încep cu A este 2 ³i au fost 2 cuvinte transmise. Pentru litera B s-a transmis un singur cuvânt de cost maxim 3. Pentru litera F s-a transmis un singur cuvânt de cost maxim 4. Timp maxim de executare/test: 1.5 secunde Memorie: total 1 MB din care pentru stiv 1 MB Dimensiune maxim a sursei: 10 KB 15.3.1 Indicaµii de rezolvare Problema poate rezolvat citind caracter cu caracter ³i memorând doar ultimele dou litere citite. Pe parcursul citiri se reµine num rul apariµiilor consecutive al unui caracter. acesta se identic a cele dou în funcµie de ecare secvenµ . în cadrul secvenµei curente se actualizeaz : litere ale posibilului cuvânt ascuns în secvenµ curent , a num rul de apariµii al ec rei minuscule ale alfabetului englez (se folose³te un vector de frecvenµ ) a num rul de apariµii al primei majuscule întâlnite în cadrul secvenµei curente La nalul unei secvenµe se actualizeaz dac este cazul, costul maxim al unui cuvânt care începe cu majuscula din cuvântului determinat la pasul curent. Dac se opteaz pentru preluarea literelor într-un vector de 1 milion de caractere, se vor obµine 50 de puncte. 15.3.2 *Rezolvare detaliat 15.3.3 Cod surs Capitolul 16 ONI 2014 16.1 2048 - ONI 2014 Problema 1 - 2048 100 de puncte Ada ³i Ben sunt pasionaµi de jocurile pe calculator ³i tocmai au descoperit cea mai recent versiune a jocului 2048. Regulile jocului sunt foarte simple: a se porne³te de la un ³ir de N piese pe care sunt înscrise numere din mulµimea { 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048 }; a piesele sunt a³ezate în locaµii numerotate consecu- tiv cu numerele 1, 2, ..., N ; a la ecare pas, poate avea loc o MUTARE la STÂNGA sau o MUTARE la DREAPTA; a pentru ecare joc este stabilit un num r maxim de mut ri M ; a dac are loc o MUTARE la DREAPTA, atunci: - piesele pot fuziona la dreapta, începând cu penulo pies se a pe o poziµie i ³i tima pies din ³ir: dac are înscris valoarea k , iar pe poziµia i 1 se a o pies Figura 16.1: 2048 cu aceea³i valoare k , atunci aceste piese vor fuziona, pe poziµia i 1 se va obµine o pies - dup cu valoarea 2k , iar pe poziµia i r mâne o locaµie liber ; efectuarea fuzion rilor, piesele se aliniaz la dreapta, astfel încât ultima pies s se ae se a pe o pe poziµia n; a dac are loc o MUTARE la STâNGA, atunci: - piesele pot fuziona la stânga, începând cu a doua pies poziµie i ³i are înscris valoarea k , iar pe poziµia i 1 se a din ³ir: dac o pies aceste piese vor fuziona, pe poziµia i 1 se va obµine o pies o pies cu aceea³i valoare k , atunci cu valoarea 2k , iar pe poziµia i r mâne o locaµie liber ; - dup efectuarea fuzion rilor, piesele se aliniaz la stânga, astfel încât prima pies s se ae pe poziµia 1; a jocul se încheie atunci când se ajunge în una dintre urm toarele situaµii: - pe cel puµin una dintre piese se a înscris valoarea 2048; - valorile înscrise nu se mai pot modica prin mutarea pieselor; - s-au efectuat toate cele M mut ri. Cerinµe Scrieµi un program care s citeasc numerele naturale N (num rul iniµial de piese) ³i M (num rul maxim de mut ri), un ³ir de N numere reprezentând, în ordine, numerele înscrise pe cele N piese ³i cel mult M caractere din mulµimea rS, D x ce reprezint Ada ³i Ben, ³i care determin : 215 mut rile xate de c tre CAPITOLUL 16. 216 ONI 2014 a) num rul X de mut ri efectuate pân la încheierea jocului; b) num rul maxim Y inscris pe una dintre piese la încheierea jocului; c) num rul maxim Z de fuzion ri efectuate la o mutare. Date de intrare Fi³ierul de intrare 2048.in conµine pe prima linie, separate prin câte un spaµiu, numerele N ³i M . A doua linie a ³ierului conµine cele N numere inscrise, în ordine, pe piese, separate prin câte un spaµiu. A treia linie a ³ierului conµine cele M caractere, separate prin câte un spaµiu, ce reprezint cele M direcµii de mutare. Date de ie³ire Fi³ierul de ie³ire 2048.out va conµine pe prima linie num rul X , pe a doua linie num rul Y ³i pe a treia linie num rul Z . Restricµii ³i preciz ri - 2 & N, M & 10000; - caracterul D indic o mutare la dreapta, iar caracterul S indic - pentru rezolvarea cerinµei a) se acord o mutare la stânga; 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 16 4 4 2 2 4 8 32 Au fost efectuate 4 mut ri pân D D S D S D S S D D 2 mai mare valoare inscris în gura 1. la încheierea jocului, cea pe una dintre piese ind 32. Num rul maxim de fuzion ri, dou , a fost obµinut la prima mutare. Timp maxim de executare/test: 0.5 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 5 KB 16.1.1 Indicaµii de rezolvare Se memoreaz ³irul de numere în tabloul unidimensional a de lungime n. Se memoreaz în dou variabile st ³i dr poziµiile de început ³i de sfâr³it ale secvenµei de piese r mase în tablou. Se cite³te, pe rând, câte o mutare, se parcurge tabloul a în sensul mut rii (de la st la dr sau invers) ³i se efectueaz toate fuzion rile posibile, contorizându-se num rul acestora. La încheierea jocului se determin 16.1.2 *Rezolvare detaliat 16.1.3 Cod surs valoarea maxim Listing 16.1.1: 1 2 3 4 5 6 7 8 9 10 11 //Cristina Sichim, C.N. Ferdinand I Bacau #include <fstream> using namespace std; ifstream f("2048.in"); ofstream g("2048.out"); int v[10001],n,m,i,j,k,st,dr,p,X,Y,Z,z,s; char d; care se a 2048.cpp în tablou în intervalul ast, adr . CAPITOLUL 16. 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 217 ONI 2014 int main() { f>>n>>m; for(i=1;i<=n;++i){f>>v[i]; if(v[i]==2048) s=1;} st=1;dr=n; for(i=1;i<=m && !s;i++) { f>>d; z=0; if(d==’D’) {for(j=dr;j>st;j--) if(v[j]==v[j-1]) {v[j]*=2; if(v[j]==2048) s=1; for(k=j-1;k>st;k--)v[k]=v[k-1]; st++; z++; } } else { for(j=st;j<dr;j++) if(v[j]==v[j+1]){ v[j]*=2; if(v[j]==2048) s=1; for(k=j+1;k<dr;k++)v[k]=v[k+1]; dr--; z++; } } X=i; if(z==0) X=i-1,i=m; Z=max(Z,z); if(s)i=m; } Y=v[st]; for(i=st+1;i<=dr;i++) Y=max(Y,v[i]); g<<X<<’\n’<<Y<<’\n’<<Z<<’\n’; f.close();g.close(); return 0; } Listing 16.1.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 2048A.cpp #include <fstream> using namespace std; ifstream f("2048.in"); ofstream g("2048.out"); int p[10001],n,m,k,i,ii,nrfuz,x,y,z,j,in,sf,mutat,gata,P; char d,ud; int main() { //citire f>>n>>m; for(i=1;i<=n;i++){f>>p[i];if(p[i]==2048){gata=1;y=2048;}} in=1;sf=n; for(i=1;i<=m && !gata;i++) { f>>d;nrfuz=0;mutat=0; if(d==’D’) {for(j=sf;j>in;j--) if(p[j]==p[j-1]) { nrfuz++;mutat=1;if(P>=in && P<=j-1)P++; p[j]*=2; for(k=j-1;k>in;k--)p[k]=p[k-1]; in++; } } else CAPITOLUL 16. 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 218 ONI 2014 {for(j=in;j<sf;j++) if(p[j]==p[j+1]) { nrfuz++;mutat=1;if(P<=sf && P>=j+1)P--; p[j]*=2; for(k=j+1;k<sf;k++)p[k]=p[k+1]; sf--; } } if(nrfuz>z)z=nrfuz; if(!mutat)gata=1;else ud=d,x++; for(ii=in;ii<=sf;ii++) if(p[ii]>y)y=p[ii]; if(y==2048)gata=1; } if(ud==’D’)P=P+n-sf; else P=P-(in-1); g<<x<<endl<<y<<endl<<z<<endl; f.close();g.close();return 0; return 0; } Listing 16.1.3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <fstream> using namespace std; int n,i,j,v[10010],p[12],x,y,z,m,k,f=1; char c; int main() { x=y=z=0; ifstream fin("2048.in"); ofstream fout("2048.out"); fin>>n>>m; for(i=1;i<=n;i++) {fin>>v[i]; k=0;x=v[i]; while(x>1) x>>=1,k++; p[k]++; } x=0; while(x<m&&!p[11]&&f) { x++; fin>>c; if(c==’S’) { f=0; for(i=2;i<=n;) if(v[i]==v[i-1]) {v[i-1]*=2; k=0;f++; while(v[i]>1) v[i]>>=1,k++; p[k]-=2;p[k+1]++; for(j=i;j<n;j++) v[j]=v[j+1]; n--;i++; } else i++; if(f>z)z=f; } else { f=0; 2048F.cpp CAPITOLUL 16. 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 219 ONI 2014 for(i=n-1;i>=1;i--) if(v[i]==v[i+1]) {v[i]*=2; k=0;f++; while(v[i+1]>1) v[i+1]>>=1,k++; p[k]-=2;p[k+1]++; for(j=i+1;j<n;j++) v[j]=v[j+1]; n--;i--; } if(f>z)z=f; } //for(i=1;i<=11;i++) fout<<p[i]<<’ ’; fout<<’\n’; //for(i=1;i<=n;i++) fout<<v[i]<<’ ’; fout<<’\n’; } if(p[11]) y=2048; else { for(i=11;!p[i];i--); y=1<<i; } if(!f)x--; fout<<x<<’\n’<<y<<’\n’<<z<<’\n’; fin.close(); fout.close(); return 0; } Listing 16.1.4: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 2048G.cpp #include <fstream> using namespace std; long long a[10001], Y; int z,i,x,Z,j,k,N,M,gata=1; char c; int main() { ifstream f("2048.in"); ofstream g("2048.out"); f>>N>>M;f>>a[1]; for(i=2;i<=N;i++) {f>>a[i];if(a[i]==a[i-1] for(i=1;i<=N;i++) if(a[i]==2048) gata=1; )gata=0;} for(i=1;i<=M && (gata==0);i++) { f>>c; x++;Z=0; if(c==’D’) { int q=N; for(j=N;j>1;j--) if(a[j]==a[j-1]) { a[j]=2*a[j];if(a[j]==2048) gata=1; for(k=j-1;k<N;k++) a[k]=a[k+1]; q--;Z++;j--; } if(q==N) {gata=1;x--;} else N=q; } else { int q=N; for(j=1;j<N;j++) if(a[j]==a[j+1]) { a[j]=2*a[j];if(a[j]==2048)gata=1; for(k=j+1;k<N;k++) a[k]=a[k+1]; CAPITOLUL 16. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 220 ONI 2014 N--;Z++; } if(q==N) {x--;gata=1;} } if(z<Z) z=Z; } Y=a[1];N++; for(i=1;i<=N;i++) { if(a[i]>Y) Y=a[i]; } g<<x<<endl<<Y<<endl<<z<<endl; f.close(); g.close(); return 0; } Listing 16.1.5: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 2048L.cpp #include <fstream> using namespace std; ifstream fin("2048.in"); ofstream fout("2048.out"); int n,m,a[10001],i,x,y,z,st,dr,nr,k,j,p,sch; char c,uc,uuc; int main() { fin>>n>>m; for(i=1;i<=n;i++) fin>>a[i]; x=y=z=0; for(j=1;j<=n;j++) y=max(y,a[j]); if(y!=2048) {x=y=z=0; st=1;dr=n; for(i=1;i<=m;i++) { fin>>c; nr=0; x++; if(c==’S’) { for(j=st;j<dr;j++) if(a[j]==a[j+1]) { a[j]=2*a[j];nr++; if(j+1==p)p--,sch=1; else sch=0; for(k=j+1;k<dr;k++) { a[k]=a[k+1]; if(k+1==p&&!sch){p--;sch=1;} } dr--; } z=max(z,nr); } else { for(j=dr;j>st;j--) CAPITOLUL 16. 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 221 ONI 2014 if(a[j]==a[j-1]) { a[j]=2*a[j];nr++; if(j-1==p)p++,sch=1; else sch=0; for(k=j-1;k>=st;k--) { a[k]=a[k-1]; if(k-1==p&&sch==0){p++;sch=1;} } st++; } z=max(z,nr); } if(nr==0)x--; for(j=1;j<=n;j++) y=max(y,a[j]); if(nr==0)uuc=uc; else uuc=c; if(y==2048||nr==0)break; uc=c; } } fout<<x<<’\n’<<y<<’\n’<<z<<’\n’; fout.close(); return 0; } Listing 16.1.6: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 2048R.cpp //Raluca Costineanu #include <fstream> using namespace std; int a[10001], n, m; char d; ifstream f("2048.in"); ofstream g("2048.out"); int main() { int i, nr=0, p, u, k, max=0, nrf, nrm=0; bool ok=1, e2048=0; f>>n>>m; for(i=1;i<=n;i++){f>>a[i];if(a[i]>nrm)nrm=a[i];} if(nrm==2048)e2048=1,ok=0; p=1; u=n; while(ok) { f>>d; nr++; nrf=0; if(d==’S’) { k=p; for(i=p;i<u;i++) if(a[i]==a[i+1]) {a[k++]=2*a[i]; i++; nrf++; if(a[k-1]>nrm)nrm=a[k-1];} else a[k++]=a[i]; if(i==u)a[k++]=a[i]; u=k-1; } else { CAPITOLUL 16. 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 222 ONI 2014 k=u; for(i=u;i>p;i--) if(a[i]==a[i-1]) {a[k--]=2*a[i]; i--; nrf++;if(a[k+1]>nrm)nrm=a[k+1];} else a[k--]=a[i]; if(i==p) a[k--]=a[i]; p=k+1; } if(nrm==2048)e2048=1; if(nrf==0)ok=0; else if(nrf>max)max=nrf; if(nr==m)ok=0; if(e2048==1)ok=0; //for(i=p;i<=u;i++)g<<a[i]<<’ ’;g<<’\n’; } if(nr==m or e2048==1) g<<nr<<’\n’; else g<<nr-1<<’\n’; g<<nrm<<’\n’<<max<<’\n’; f.close(); g.close(); return 0; } 16.2 babilon - ONI 2014 Problema 2 - babilon 100 de puncte Babilonienii au dezvoltat un sistem poziµional de scriere a numerelor, în care orice num r natural se poate reprezenta utilizând semnele Valorile k (unu), " r2, 3, ..., 9x se obµin scriind semnul (zece) ³i spaµii. de k ori (scrierea babilonian a lui 3 este ). Numerele 11, 12, ..., 59 se obµin ca succesiuni de semne ca urmate de semne (43 se reprezint ). 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 (60 se reprezint Se codic locul semnului ca , 3600 se reprezint scrierea babilonian ca a semnelor se utiliza spaµiu etc.). a unui num r utilizând cifra 1 în locul semnului , cifra 2 în ³i cifra 3 în loc de spaµiu, ca în exemplele de mai jos: Scrierea babilonian Codicarea 1311 12 1221111 123111 1*60+2=62 1*60+10=70 1*60+20+4=84 1*60*60+10*60+3=4203 scrierii babiloniene Valoarea 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: a) num rul maxim de cifre 1 aate pe poziµii consecutive în codicarea scrierii babiloniene date; CAPITOLUL 16. 223 ONI 2014 b) num rul natural din sistemul zecimal corespunz tor scrierii babiloniene date. Date de intrare Fi³ierul de intrare babilon.in conµine: a pe prima linie un num r natural p ( 1 & p & 2 ); a pe a doua linie un num r natural n; a pe a treia linie n cifre separate prin câte un spaµiu, reprezentând codicarea scrierii babilo- niene a unui num r natural. Date de ie³ire Dac valoarea lui p este 1, atunci se va rezolva numai punctul a) din cerinµ . În acest caz, ³ierul de ie³ire babilon.out va conµine pe prima linie un num r natural reprezentând num rul maxim de cifre 1 aate pe poziµii consecutive în codicarea scrierii babiloniene date. Dac valoarea lui p este 2, atunci se va rezolva numai punctul b) din cerinµ . În acest caz, ³ierul de ie³ire babilon.out va conµine pe prima linie num rul natural corespunz tor scrierii babiloniene date. Restricµii ³i preciz ri a 2 & n & 109 ; 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 8 1 1 3 2 1 1 1 2. Cea mai lung secvenµ de cifre 1 are lungimea 3. 1 1 3 2 1 1 1 2 2 7213 7 1 1 3 2 1 1 1 2 se înmulµe³te de dou c ori cu 60 (o dat este urmat de spaµiu ³i înc precede o grup se adun o dat care începe cu semnul pentru pentru c $ ), apoi valoarea 13. 2*60*60+10+3=7213 2 11541 9 1 1 1 2 1 1 2 2 1 3 se înmulµe³te cu 60 de dou precedat de dou apoi se adun ori pentru c grupe care încep cu semnul este $ , 12 înmulµit cu 60 ³i la nal se adun 21. 3*60*60+12*60+21=11541 Timp maxim de executare/test: 0.1 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 5 KB 16.2.1 Indicaµii de rezolvare Prof. Florentina Ungureanu, Colegiul Naµional de Informatic Punctul a): Piatra-Neamµ CAPITOLUL 16. 224 ONI 2014 lungimea ec rei secvenµe de cifre 1 ³i se Se citesc pe rând valorile din ³ier, se determin reµine lungimea maxim . Punctul b): Se cite³te prima cifr semnului ³i se iniµializeaz ), respectiv cu 10 dac o variabil este egal z cu 1 dac cifra este 1 (corespunz tor cu 2 (corespunz tor semnului ). Se continu citirea câte unei cifre ³i la întâlnirea cifrei 3 (corespunz toare unui spaµiu în scrierea babilonian ) sau a cifrei 2 precedat de o cifr 1 (ignorând eventualele cifre 3 corespunz toare spaµiilor) valoarea z se înmulµe³te cu 60. Pentru ecare cifr 1 întâlnit , z se incrementeaz cu 1, iar pentru ecare cifr 2, se incrementeaz cu 10. 16.2.2 *Rezolvare detaliat 16.2.3 Cod surs 16.3 iepurasi - ONI 2014 Problema 3 - iepurasi 100 de puncte Se construie³te un ³ir de numere naturale care respect restricµiile: - primul num r din ³ir este 9; - numerele se genereaz în ordine strict cres- c toare; - ³irul conµine toate numerele formate doar cu cifrele 7, 8 ³i 9 cu proprietatea c num rul cifrelor 9 este mai mare sau egal decât num rul cifrelor 8 ³i num rul cifrelor 8 este mai mare sau egal decât num rul cifrelor 7. Primii 14 termeni ai ³irului, în ordine, sunt: 9, Figura 16.2: iepurasi 89, 98, 99, 789, 798, 879, 897, 899, 978, 987, 989, 998, 999. Pornind de la aceste numere, Liv a inventat un joc interactiv: ecare având câte un cartona³. Fiecare cartona³ are dou un num r din acest ³ir ³i o faµ feµe, o faµ gri, pe care este inscripµionat N iepura³i sunt a³ezaµi în ³ir, alb 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 inscripµionat num rul 789. alb Iepura³ii sunt a³ezaµi într-o ordine oarecare ³i µin cartona³ele astfel încât s gri. Jocul const se vad în a rearanja iepura³ii de la stânga la dreapta, descresc tor dup faµa 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 toµi iepura³ii din acea secvenµ (ca în imaginea de mai sus). Dup µin cartona³ele astfel încât s se vad oglindire, 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 a) Num rul minim de operaµii T AP necesare rearanj rii iepura³ilor; b) Cel mai mic num r aat pe o faµ neîntoarse. Dac alb care nu se vede, în cazul în care au r mas cartona³e toate cartona³ele au fost întoarse (la toate ind vizibil mai mare num r aat pe o faµ alb determine: faµa alb ) se va a³a cel 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. CAPITOLUL 16. 225 ONI 2014 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 a 2 a 1 & N & 10000; & ai & 10000 (1 & i & N ); a N , a1 , a2 , ..., aN sunt numere naturale; a pentru rezolvarea cerinµei a) se acord 50% din punctaj, iar pentru cerinµa b) se acord 50% din punctaj. Exemple iepurasi.in iepurasi.out Explicaµii 5 1 Se aplic 14 5 8 9 10 999 de ordine 5. o singur operaµie TAP pe iepura³ul cu num rul Cartona³ul neîntors are num rul de ordine 14 (999). Timp maxim de executare/test: 1.0 secunde Memorie: total 5 MB din care pentru stiv 5 MB Dimensiune maxim a sursei: 5 KB 16.3.1 Indicaµii de rezolvare Cerinµa a) Întrucât problema cere ca rearanjarea iepura³ilor s se fac de la stânga la dreapta, primul iepura³ care trebuie repoziµionat este iepura³ul cu cel mai mare num r pe faµa gri. Urmând aceea³i idee, la ecare pas i, trebuie repoziµionat iepura³ul cu cel mai mare num r pe faµa gri, care se a pe o poziµie j (i & j & n). Costul unei astfel de repoziµion ri poate 0, 1 sau 2. Soluµia1. Se parcurge tabloul cu numerele de ordine ale iepura³ilor, de la stânga la dreapta, ³i pentru ecare ai se veric se caut dac este maxim pe secvenµa ai ... an. Dac nu este maxim, poziµia elementului maxim aat la dreapta lui i, e aceasta imax ³i se execut pe iepura³ul cu num rul de ordine aimax, dac num rul de ordine ai. un T AP imax j N ³i apoi un T AP pe iepura³ul cu Soluµia2. Se face o copie a tabloului unidimensional cu numerele de ordine ale iepura³ilor citite descresc tor a1 ³i se compar cu ³irul iniµial. În cazul în care ai j a1i se (a1). Se ordoneaz execut T AP pe ai, dac a1N ai sau se face T AP pe aj , dac a1j ai ³i T AP pe ai. Soluµia3. Se realizeaz un precalcul care num r pentru ecare cartona³ gri, câte elemente sunt mai mici ca valoare ³i se reµine într-un tablou poziµia pe care ar ocupa-o în ³irul sortat ³i în alt tablou poziµia pe care o ocup în ³irul actual. Pentru un cartona³ care nu se a pe poziµia T AP din poziµia elementului care ar trebuit s se ae în aceast poziµie. Dac acest element se a în ³irul actual pe poziµia n se face un T AP , iar dac nu, se fac dou T AP -uri (primul ca s ajung pe poziµia n ³i al doilea ca s ajung la locul s u). sa nal se realizeaz Cerinµa b) Soluµia1. Se utilizeaz 4 tablouri unidimensionale, unul pentru memorarea tuturor numerelor ce se pot forma, în ordine cresc toare, cu cifrele 7, 8 ³i 9 ³i trei tablouri unidimensionale în care se memoreaz frecvenµa de apariµie a cifrelor 7, 8 ³i 9 în numerele generate. Soluµia2. Se simuleaz o generare în baza 4 în care resturilor 1, 2, 3 li se asociaz cifrele 7, 8 ³i 9. 16.3.2 *Rezolvare detaliat CAPITOLUL 16. 16.3.3 ONI 2014 Cod surs 226 Capitolul 17 ONI 2013 17.1 greieri - ONI 2013 Problema 1 - greieri Pe o linie orizontal 100 de puncte 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 st Figura 17.1: greieri 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 a 1 & n & 100000 & 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 a ecare linie din ³ierul de intrare se termin 227 se va scrie valoarea 1; cu caracterul sfâr³it de linie 228 CAPITOLUL 17. ONI 2013 Exemple greieri.in greieri.out Explicaµii 12 Dup 4 3 1 2 1 2 3 4 la primul pas sare greierele 3 peste 4, la pasul 2 4 5 cum se vede ³i în imagine pornind de la linia iniµial sare greierele 2 peste 4, la pasul trei sare greierele 1 peste 4, la pasul patru sare greierele 2 peste 3, iar la pasul cinci sare greierele 1 peste 3. Timp maxim de executare/test: 0.4 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 5 KB 17.1.1 *Indicaµii de rezolvare matematic 17.1.2 *Rezolvare detaliat 17.1.3 *Cod surs 17.2 Onigim - ONI 2013 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. 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. Pe prima linie se a Restricµii ³i preciz ri CAPITOLUL 17. 229 ONI 2013 & N & 1000; & pi & 300, (1 & i & N ); a 0 & ai $ 1000, (1 & i & N ); a 3 & K & 300; a 1 a 1 a Pentru prima cerinµ rezolvat corect se acord rezolvat corect se acord 40% din punctaj; pentru a doua cerinµ 30% din punctaj; pentru a treia cerinµ rezolvat corect se acord 30% din punctaj; a R spunsurile la cele trei cerinµe vor scrise exact pe linia indicat ; în cazul în care nu cunoa³teµi rezolvarea la una dintre cerinµe, pe linia respectiv a Fiecare linie din ³ierul de intrare se termin Exemple onigim.in se va scrie valoarea 1; cu caracterul sfâr³it de linie. onigim.out Explicaµii 6 4 200 150 100 100 175 200 Sunt 4 elevi care au punctajul mai mic decât punc- 100 150 175 200 4 tajul elevului cu id-ul 1, 2 elevi cu punctajul mai 4 2 0 0 3 4 2 mic decât punctajul elevului cu id-ul 2, etc. Cele mai mari 3 punctaje sunt obµinute de 4 elevi. Num rul maxim de elevi care au acela³i punctaj este 2. Timp maxim de executare/test: 0.1 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 5 KB 17.2.1 *Indicaµii de rezolvare list , tablou, tablou vector (unidimensional), tablou vector caracteristic (de frecvenµ ) 17.2.2 *Rezolvare detaliat 17.2.3 *Cod surs 17.3 Extraprime - ONI 2013 Problema 3 - Extraprime 100 de puncte Gigel, mare amator de probleme de matematic prime au o proprietate interesant : orice cifr ³i informatic , a observat c unele numere 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 este prim; dac elimin m 1, obµinem 37, care este prim; dac elimin m cifra 3, obµinem 17, care elimin m 7, obµinem 31, care este ³i el num r prim. Cerinµe x este între a ³i b dac x ' a ³i x & b. Fiind date dou valori naturale a ³i b, s se între a ³i b, precum ³i cel mai mic ³i cel mai mare num r extraprim dintre a ³i b. Spunem c determine câte numere extraprime exist Date de intrare Pe prima linie a ³ierului de intrare separate printr-un spaµiu. Date de ie³ire extraprime.in se g sesc cele dou valori naturale a ³i b, CAPITOLUL 17. 230 ONI 2013 Fi³ierul de ie³ire extraprime.out va avea 3 linii. Pe prima linie se va scrie un num r natural nr reprezentând num rul de numere extraprime dintre a ³i b. Pe linia a doua a ³ierului de ie³ire se va scrie cel mai mic num r extraprim dintre a ³i b, iar pe linia a treia a ³ierului de ie³ire se va scrie cel mai mare num r extraprim dintre a ³i b. Restricµii ³i preciz ri a 10 $ a & b $ 10000000 a Num rul 1 nu este prim. a Pentru datele de test exist întotdeauna soluµie. Exemple extraprime.in extraprime.out Explicaµii 10 100 4 Se a 23 mici decât 100: 23, 37, 53 ³i 73. 4 numere extraprime mai mari decât 10 ³i mai 73 Timp maxim de executare/test: 1.1 secunde Memorie: total 32 MB din care pentru stiv 32 MB Dimensiune maxim a sursei: 15 KB 17.3.1 *Indicaµii de rezolvare matematic 17.3.2 *Rezolvare detaliat 17.3.3 *Cod surs Capitolul 18 ONI 2012 18.1 culegere - ONI 2012 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 ordinea apariµiei lor în culegere. Pe prima pagin a culegerii este scris o singur problem (cea cu sunt scrise exact dou probleme (cele cu numerele num rul 1). Pe a doua pagin 2 ³i 3, în aceast Figura 18.1: culegere 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 conµin ³i problema numerotat le aib culegerea, astfel încât aceasta s 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 a 1 & P & 16000; & 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 231 CAPITOLUL 18. 232 ONI 2012 culegere.in culegere.out Explicaµii 5 9 21 Problemele sunt numerotate cu numerele: 4 a 1 a 2, 3 a 4, 5, 6 a 7, 8, 9, 10 a 11, 12, 13, 14, 15 (pagina 1) (pagina 2) (pagina 3) (pagina 4) (pagina 5). În scrierea acestor numere s-au folosit 21 de cifre => T 21. Pentru a conµine ³i problema cu num rul 9, culegerea trebuie s aib minimum 4 pagini => M 4. Timp maxim de executare/test: 0.1 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 10 KB 18.1.1 Indicaµii de rezolvare prof. Carmen Minc , Colegiul Naµional de Informatic O soluµie care obµine 100p poate construit Tudor Vianu, Bucure³ti pe baza urm torului algoritm: Cerinµa a) a Se determin num rul total nt de exerciµii pe care le poate conµine culegerea de P pagini: nt Se observ c P P 1©2 nt & 16000 16001©2 128008000 num rul k de cifre din scrierea zecimal a Se determin a lui nt (k & 9) Figura 18.2: culegereIR1 a Se determin num rul T total de cifre utilizate în scrierea tuturor numerelor naturale nenule cel mult egale cu nt, observând c : Figura 18.3: culegereIR2 Figura 18.4: culegereIR3 CAPITOLUL 18. 233 ONI 2012 Cerinµa b) a Se determin cel mai mic num r natural M cu proprietatea c va reprezenta num rul minim de pagini cerut. Figura 18.5: culegereIR4 18.1.2 *Rezolvare detaliat 18.1.3 Cod surs Listing 18.1.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 //prof.Carmen Minca #include <fstream> using namespace std; int main() { long long nt,p10=1,k=0,M,i,T=0, P,N,x; ifstream f("culegere.in"); ofstream g("culegere.out"); f>>P>>N; nt=P*(P+1)/2; x=nt; while(x) { k++; x/=10; } for(i=1;i<k;i++) { T=T+i*p10; p10*=10; } T=T*9+(nt-p10+1)*k; g<<T<<endl; long long probl=0; for(M=1;probl+M<N;M++) probl+=M; g<<M<<endl; return 0; } Listing 18.1.2: 1 2 3 4 5 6 7 8 culegere_2.cpp culegere_3.cpp //prof.Carmen Minca //solutie care depaseste continutul programei de gimnaziu #include <fstream> #include <cmath> using namespace std; 1 2 3 ... M ' N . Acesta CAPITOLUL 18. 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 234 ONI 2012 int main() { long long n,p=1,k,i,nrc=0, P,N; ifstream f("culegere.in"); ofstream g("culegere.out"); f>>P>>N; n=P*(P+1)/2; k=log10(n*1.0); k++; for(i=1;i<k;i++) { nrc=nrc+i*p; p*=10; } nrc=nrc*9+(n-p+1)*k; g<<nrc<<endl; long long pag=1; if(N>1) { pag=(-1+sqrt(1.+8*N))/2; if(pag*(pag+1)<2*N)pag++; } g<<pag<<endl; return 0; } 18.2 culori - ONI 2012 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 num r natural nenul, ³i inscripµioneaz ec rei culori distincte un cod, reprezentat printr-un 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 ³i K , separate printr- un spaµiu, ³i pe ecare dintre urm toarele N linii, câte un num r natural. Cele N numere reprezint 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 a 2 $ N & 1000; $ 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 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). cel puµin C cartona³e CAPITOLUL 18. Exemple culori.in culori.out 8 5 2 3 4 235 ONI 2012 Explicaµii Sunt doi copii care au, ecare, cartona³e identice cu cei doi vecini (co- 1 pilul 5 ³i copilul 8). 2 Num rul 1 aceea³i 1 maxim culoare a³ezaµi pe K 1 de cartona³e deµinute de de copiii 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 18.6: culori Timp maxim de executare/test: 0.1 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 10 KB 18.2.1 Indicaµii de rezolvare prof. Adriana Simulescu, Liceul GRIGORE MOISIL Timi³oara O soluµie se poate obµine astfel: Codurile culorilor cartona³elor se citesc în vectorul x. Pe m sur calculeaz ce se citesc aceste coduri se num rul de copii nrc care au cartona³e de aceea³i culoare cu cea a cartona³elor vecinilor ³i num rul de culori c determinând maximul din valorile vectorului x. Pentru rezolvarea cerinµei b) vectorul x se dubleaz ..., x2 N 1 astfel: xN 1 x1, xN 2 x2, xN 1 Figura 18.7: culoriIR1 Calcul m num rul pentru cerinµa b) astfel: Pentru copiii cu numerele de ordine de la 1 la K am construit vectorul de apariµii ale codurilor culorilor cartona³elor ap ³i se determin num rul maxim de apariµii maxck . CAPITOLUL 18. 236 ONI 2012 Figura 18.8: culoriIR2 Pentru urm toarele secvenµe de k (i 2, 3, ..., N ) copii al turaµi scad din vectorul de apariµii prezenµa culorii cartona³ului copilului i 1 ³i adun prezenµa culorii cartona³ului copilului i K 1. Pentru ecare secvenµ se actualizeaz maximul cu elementele din vectorul de apariµii. Figura 18.9: culoriIR3 18.2.2 *Rezolvare detaliat 18.2.3 *Cod surs 18.3 stele - ONI 2012 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 Constelaµia Numerelor ³i erau aranjate într-un roi în form de triunghi, pe coloane ³i pe rânduri în cadrul ec rei coloane, ca în desenul al turat. Stelele cu numerele 1, 3, 7, 13, 21, 31, ..., situate pe rândul marcat cu desen, formau centrul roiului de stele. în Coloanele din roi erau numerotate de la stânga la dreapta, începând cu num rul 1, iar rândurile din cadrul ec rei coloane erau numerotate de jos în sus, începând cu num rul 1 (ca în desen). Legenda spune c , pe vremuri, tr ia în µara Numerelor Fermecate o vr jitoare deosebit de rea ³i de puternic . Tot ceea ce atingea aceast magic se pref cea în stan vr jitoare cu bagheta de piatr . Ea î³i propusese Figura 18.10: stele s -i preschimbe în statui pe toµi copiii din µinut. În acea vreme înv µa la ³coal Zâna Cea Bun s-a hot rât s magic , pe care Numerel s Numerel, un b ieµel vrednic ³i curajos. Îl iubea toat o foloseasc împotriva vr jitoarei. Pentru a primi bagheta, Numerel a cules pulberea celei de a K -a stele situat Dar aventura a continuat! g seasc lumea! îl ajute pe Numerel. Aceasta i-a promis inimosului b iat o baghet în centrul roiului pentru a i-o da Zânei. Zâna locuia pe steaua cu num rul N , iar Numerel a trebuit s adresa acesteia, respectiv num rul coloanei, precum ³i num rul rândului din coloan , pe care se g sea aceast Aventura voastr stea. abia acum începe! CAPITOLUL 18. 237 ONI 2012 Cerinµe Scrieµi un program care cite³te dou numere naturale K ³i N ³i determin a) num rul celei de a K -a stele situat b) coloana ³i rândul (din aceast pentru Numerel: în centrul roiului; 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 a 0 $ K & 60000; $ 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 Primele K 21 2 2 2 5 5 stele din centrul roiului au numerele: 1, 3, 7, 13, 21 . 3 se a pe coloana 2 , rândul 2 . Primele K 2 stele din centru roiului au numerele: 1, 3 . Steaua cu num rul N 5 se a pe coloana 3 , rândul 5 . Steaua cu num rul N 3 3 5 Timp maxim de executare/test: 0.5 secunde Memorie: total 2 MB din care pentru stiv 2 MB Dimensiune maxim a sursei: 10 KB 18.3.1 Indicaµii de rezolvare prof. Gina Balacea, Colegiul Naµional Vasile Alecsandri - Galaµi O soluµie pentru 100p se poate obµine astfel: a Se aranjeaz numerele 1, 2, 3, 4, ... în form de triunghi, astfel: Figura 18.11: steleIR a Se observ c num rul de jos al ec rei coloane i (nr. stelei de pe rândul 1, coloana i) este 2 p tratul perfect al num rului coloanei = i . CAPITOLUL 18. 238 ONI 2012 a Toate numerele de pe linia din mijloc se obµin cu formula i 2 coloanei: 3 2 2 1; 7 2 cu formula K K 1. 2 i 1, unde i este num rul 4 4 1. Prin urmare, al K -lea element se determin 2 2 3 3 1; 13 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 . Rândul = Coloana 2 2 N 1. De exemplu, pentru N 3 31 6, avem : 2 2 $ 6 & 32 . Prin urmare coloana este 3 iar rândul este 7 a Nu este necesar ca datele s e memorate într-un tabel. 18.3.2 *Rezolvare detaliat 18.3.3 *Cod surs Capitolul 19 ONI 2011 19.1 Fagure - ONI 2011 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 Mihuµ, fratele lui Ionel, ca s fac numai dou o glum numere. 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 Dac a doi faguri al turaµi. î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 a amestecat numerele. Mihuµ nu are voie s ce Mihuµ amestece numerele: 11, 37, 101, 97, 19, 13. Figura 19.1: fagure Cerinµe Scrieµi un program care s citeasc informaµiile din ³ierul de intrare fagure.in ³i care s determine: a) num rul fagurilor pe care a reu³it Ionel s îi construiasc ; b) cel mai mic num r de ordine al fagurelui pe care Ionel a plasat valoarea amestecarea realizat x, înainte de 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µ; 239 CAPITOLUL 19. 240 ONI 2011 - 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 numerele sau valoarea 0 dac ce a amestecat 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. & n $ 10000 & k & cu num rul de ordine al fagurelui din mijloc a 1 & x $ 30000 a 10 a 2 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 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; num rul fa- 5 reprezint plasat valoarea de Mihuµ pe fagu- rele 2. Timp maxim de executare/test: 1.0 secunde 19.1.1 Indicaµii de rezolvare prof. Daniela Taras - Colegiul Naµional Gheorghe Vr nceanu Bac u prof. Gavril Petru Florin - Colegiul Naµional Roman Vod Roman Punctul a): Fiecare fagure conµine dou valori comune cu fagurele anterior la care se adaug alte patru valori. Num rul fagurilor se obµine cu urm toarea formul : a nr n 2©4; Punctul b): Pentru a determina num rul minim de ordine al fagurelui pe care se aa iniµial valoarea x, se va realiza o c utare secvenµial , determinând poziµia primei apariµii a valorii x. Dac valoarea x este g sit pe latura comuna a doi faguri, atunci se a³eaz numerele de ordine a celor doi faguri (în ordinea cresc toare a lor). Se trateaz separat cazul în care valoarea x apare în primul fagure sau în ultimul. Punctul c): pentru a determina valoarea rezultat dup amestecare, se determin : a num rul de ordine al fagurelui simetric cu fagurele k ; a primalitatea valorilor ce pot amestecate; a cea mai mare dintre valorile prime ce pot amestecate. În cazul în care fagurele k sau nr k 1 nu conµine valori prime ce pot amestecate, se va scrie în ³ierul de ie³ire valoarea 0. 19.1.2 *Rezolvare detaliat CAPITOLUL 19. 19.1.3 241 ONI 2011 Cod surs Listing 19.1.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 fagure.cpp #include<fstream> #include<math.h> using namespace std; ifstream f("fagure.in"); ofstream g("fagure.out"); int v[10001]; int prim (int x) { long d; if(x<2) return 0; for(d=2;d<=sqrt(x);d++) if(x%d==0) return 0; return 1; } int main() { int n,i,nr_fag,k,gasit=0,grupa,nr,poz,fag,x1,x2,x; f>>n>>k; for(i=1;i<=n;i++) f>>v[i]; f>>x; // cerinta 1 calculam si afisam numarul fagurilor construiti nr_fag=(n-6)/4+1; g<<nr_fag<<’\n’; // cerinta 2 cautam prima aparitie a lui x in v for(i=1;i<=n &&!gasit;i++) if(v[i]==x) {gasit=1;poz=i;} // verificam si afisam numarul sau numerele fagurilor din care face parte x if(poz<=6) if(poz==2 ||poz==3) g<<1<<’ ’<<2<<’\n’; else g<<1<<’\n’; else if(poz==n-1 || poz==n-2) g<<nr_fag<<’\n’; else if((poz%4==0 || poz%4==1) && poz/4<nr_fag) g<<poz/4<<’ ’<<poz/4+1<<’\n’; else if(poz%4==3) g<<poz/4+1<<’\n’; else g<<poz/4<<’\n’; // cerinta 3 // fagurele pe care s-a gasit initial numarul prim este fag=nr_fag+1-k; // discutam despre pozitiile fag*4-1, fag*4+2 pentru ca de pozitiile // fag*4 si fag*4+1 nu avem voie sa ne atingem // notam cu x1 si x2 pozitiile pe care le verificam x1=fag*4-1; x2=fag*4+2; if(prim(v[x1])&& prim(v[x2])) if(v[x1]>v[x2]) g<<v[x1]<<’\n’; else g<<v[x2]<<’\n’; else { if(prim(v[x1])) g<<v[x1]<<’\n’; if (prim(v[x2])) g<<v[x2]<<’\n’; } if(prim(v[x1])==0 && prim(v[x2])==0) CAPITOLUL 19. 71 72 73 74 75 76 242 ONI 2011 g<<0<<’\n’; f.close(); g.close(); return 0; } 19.2 Goe - ONI 2011 Problema 2 - Goe 100 de puncte Goe este un copil dr g la³, dar tare lene³. Nu îi place nici s scrie, nici s greu a fost convins de mama sa s dar de scris tot nu poate s numere. Cu înveµe cifrele, 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 în ordinea invers . scrie cifrele De exemplu num rul 138 va scris de Goe 831. Mama lui Goe scrie în ecare zi, în ordine cresc toare, câte 9 numere naturale, s rind îns Figura 19.2: Goe peste orice num r divizibil cu 10, ca în Figura 1. Goe copiaz p cate, el nu î³i îndreapt niciuna dintre gre³eli: copiaz zilnic aceste numere. Din 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. Exemple goe.in goe.out Explicaµii 5 15 15 numere a scris Goe în primele 5 zile. 8 111 Primele 8 palindroame scrise corect de Goe sunt: 3 91 1, 3, 8, 11, 33, 88, 101, 111. Cel mai mare num r scris de Goe în primele 3 zile este 91. Timp maxim de executare/test: 1.0 secunde CAPITOLUL 19. 19.2.1 243 ONI 2011 Indicaµii de rezolvare prof. Ana întuneric, C.N. "Ferdinand I" Bac u prof. Dana Lica, C.N. "I.L.Caragiale" Ploie³ti Cerinµa a): Goe scrie într-o zi 5 numere sau niciunul. Este sucient s numere naturale strict pozitive (zile) nu au în componenµ înmulµeasc se numere câte dintre primele k una dintre cifrele 2, 4, 5 sau 7 ³i s se 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 Se determin 2c 1). 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 2 3, 3 0, 1 1, 8). Cerinµa c): Se observ c num rul maxim scris de Goe are prima cifr cifre, se memoreaz se a³eaz în mod invers. 19.2.2 *Rezolvare detaliat 19.2.3 Cod surs Listing 19.2.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 9. Pentru a determina celelalte cifrele num rul n într-un vector ³i se prelucreaz pe rând cifrele sale. Vectorul GOE.CPP #include <fstream> #include <math.h> using namespace std; ifstream f("goe.in"); ofstream g("goe.out"); long n,k,p,bune,max,nrn,put,x,aux,nrbune,ok,d; int s[11]; long v[11],sum,power; long i,j,nr,nrcif,posib,nrc,schimbat,r,l,inv,pn,un,copie,cifra; int main() { f>>k>>p>>n; //a)************************** nrn=0; for(i=1;i<=k;i++) { aux=i-1;ok=1; while(aux>0) { if(aux % 10 == 2 || aux % 10 == 4 || aux % 10 == 5 || aux % 10 == 7) ok=0; aux/=10; } if(ok)nrn=nrn+5; } g<<nrn<<’\n’; //b)************************** nrc=1; d=3; //d reprezinta cate numere palindroame de nrc cifre exista while(p>d) CAPITOLUL 19. 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 ONI 2011 { p=p-d; nrc++; if(nrc%2) d=d*4; } //d este modificat o data la 2 pasi, intrucat numarul de palindroame este // acelasi pentru o lungime de 2*k si 2*k+1 /*in p avem al catelea numar de nrc cifre trebuie sa determinam in c construim palindromul, dar in baza 4, pentru a face iarasi o bijectie intre baza 4 si o baza cu cifrele 0,1,3,8 (singurele cifre cu care se pot construi palindroame) */ v[1]=1; v[nrc]=1; d=d/3; p--; for(i=2;i<nrc;i++) v[i]=0; i=1; while(d>0) { v[i]=v[nrc-i+1]=v[i]+p/d; p=p%d; d/=4; i++; } //trecem numarul din baza 4 in scrierea necesara for(i=1;i<=nrc;i++) { if(v[i]==2) v[i]=3; else if(v[i]==3) v[i]=8; } for(i=1;i<=nrc;i++) g<<v[i]; g<<’\n’; //c)************************** nrc=log10(n)+1; i=nrc; while(n>0) { s[i]=n%10; n=n/10; i--; } i=1; if(s[1]==1) { i++; while(i<=nrc && s[i]==0)i++; } if(i==nrc+1) { for(j=1;j<=nrc;j++)g<<’9’; g<<’\n’; } else { g<<’9’; if(s[i]>1 && i<nrc && s[i+1]<6 || s[i]==1 && s[i+1]<6 || s[i]!=9) { s[i]--; if(s[i]==2 || s[i]==4 || s[i]==5 || s[i]==7) s[i]--; if(s[i]==4) s[i]=3; } i++; for(;i<=nrc;i++) s[i]=9; for(i=nrc;i>=1;i--) { if(s[i]==6) s[i]=9; g<<s[i]; } 244 CAPITOLUL 19. 112 113 114 115 116 117 118 119 245 ONI 2011 g<<’\n’; } f.close(); g.close(); return 0; } 19.3 P pu³a - ONI 2011 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 19.3: papusa n La un magazin de suveniruri se g sesc 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 a Dac aleag p pu³i din raftul din stânga, iar Ana din raftul din dreapta 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 doua decât cea de a treia ³i a³a mai departe astfel încât ecare p pu³ urm toarea p pu³ ultima p pu³ Ana trebuie s - dac poate introdus în cump rat ; a Ultimele p pu³i cump rate trebuie s - dac decât cea de a doua, a s se situeze doar la capetele rafturilor ³i în plus: de Iulia este pe poziµia 1 atunci ultima p pu³ cump rat cump rat de e pe poziµia n; ultima p pu³ de Ana trebuie s Pentru a putea s li se permite s cump rat de Iulia este pe poziµia n©2 atunci ultima p pu³ cump rat e pe poziµia n©2 1. aleag cât mai multe p pu³i respectând regulile impuse de tat l lor, fetiµelor 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 Fi³ierul text de p pu³i. papusa.in conµine pe prima linie un num r natural par n, reprezentând num rul 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 . CAPITOLUL 19. 246 ONI 2011 Restricµii ³i preciz ri a 2 a 1 & n & 1000, n este num r par & în lµimile p pu³ilor & 10000 a Dac a face operaµii de mutare atunci M num rul maxim de p pu³i se obµine f r a Pentru toate testele de intrare exist o singur 0 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 Pe aceast dup a doua operaµie 2 4 5 7 14 8 6 10. 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 Pe aceast dup a treia operaµie 4 5 7 2 10 14 8 6. a³ezare Iulia ³i Ana pot cump ra p pu³ile cu în l- µimile 2 10 sau 4 6. Deci se pot cump ra cel mult 2 p pu³i. Num rul maxim de p pu³i cump rate este 7 ³i se obµine dup a doua operaµie de mutare. Timp maxim de executare/test: 1.0 secunde 19.3.1 Indicaµii de rezolvare prof. Suzana G l µan Se genereaz concomitent toate permut rile circulare ale primei jum t µi a ³irului, respectiv ale celei de a doua jum t µi. Pentru ecare permutare, se determin urm toarele valori: L1 - lungimea secvenµei descresc toare care începe la poziµia 1 L2 - lungimea secvenµei cresc toare care se termin pe poziµia n L3 - lungimea secvenµei cresc toare care se termin pe poziµia n©2 L4 - lungimea secvenµei descresc toare care începe pe poziµia n©2 1 Num rul maxim de p pu³i cump rate este maximul dintre sumele L1 L2 ³i L3 L4. Num rul de operaµii cerute este egal cu num rul de ordine a permut rii pentru care se obµine num rul maxim de p pu³i. 19.3.2 *Rezolvare detaliat 19.3.3 Cod surs Listing 19.3.1: 1 2 3 4 5 //Suzana Galatan #include <fstream> using namespace std; papusa.cpp CAPITOLUL 19. 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 ONI 2011 int main() { ifstream fin("papusa.in"); ofstream fout("papusa.out"); int n, x[1001]; int l11, l22, ok = 1; fin >> n; int i, pas = 0, l1, l2, aux1, aux2, secv = 0, perm = 0; for(i = 1; i <= n; i++) fin >> x[i]; while(pas < n/2) { l1 = l2 = 1; l11 = 1, l22 = 1; ok = 1; for(i = n/2-1; i > 0 && ok; i--) if(x[i+1] > x[i])l1++; else ok = 0; ok = 1; for(i = n/2+2; i <= n&&ok; i++) if(x[i-1] > x[i])l2++; else ok = 0; if(secv < (l1+l2))secv = l1+l2, perm = pas; ok = 1; for(i = n-1; i >= n/2 && ok; i--) if(x[i+1] > x[i])l22++; else ok = 0; ok = 1; for(i = 2; i <= n/2 && ok; i++) if(x[i-1] > x[i])l11++; else ok = 0; if(secv <(l11+l22))secv =l11+l22, perm = pas; pas++; aux1 = x[1]; aux2 = x[n]; for(i = 1; i < n/2; i++) { x[i] = x[i+1]; x[n-i + 1] = x[n-i]; } x[n/2] = aux1; x[n/2+1] = aux2; } fout << perm<<"\n"<< secv<<"\n"; fin.close(); fout.close(); return 0; } 247 Capitolul 20 ONI 2010 20.1 cluburi - ONI 2010 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 membrilor unui club poate s dou creasc cluburi se pot unica dac continu s prin unicarea cu un alt club dup num rul urm toarea regul : au acela³i num r de membri. Prin unicare, unul dintre cluburi 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 s unice cluburile dup mai bine atunci când clubul are mai mulµi membri, ei au hot rât 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 a) cel mai mic num r natural k de cluburi care continu s determine: 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 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 248 un CAPITOLUL 20. 249 ONI 2010 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 8 16 membri. 12 cluburi cu câte 2 membri, apoi 6 cu câte 4 Din cele 6 cluburi se vor forma apoi 3 cu câte 8 membri. Dou dintre cluburile cu 8 membri se unesc formand unul cu 16 membri. în nal r mân 2 cluburi, unul cu 8, iar cel lalt cu 16 membri. Timp maxim de executare/test: 1.0 secunde 20.1.1 Indicaµii de rezolvare prof. G l µan Suzana - Inspectoratul ³colar Judeµean Bistriµa-N s ud Descrierea soluµiei Num rul de cluburi care se formeaz repetat este egal cu suma resturilor obµinute prin împ rµirea a num rului n la 2, atât timp cât n este diferit de 0. Figura 20.1: cluburiIR1 k1 Num rul de membri ai ec rui club este egal cu 2 , unde k este egal cu num rul de împ rµiri la 2 al lui n ³i la acel pas n%2 este egal cu 1. Figura 20.2: cluburiIR2 Exemplu: Pentru n r k1 13 se obµine: 1 0 0 2 2 2 Num r membri 1 - 1 1 1 2 3 2 2 4 8 CAPITOLUL 20. 250 ONI 2010 Figura 20.3: cluburiIR3 20.1.2 *Rezolvare detaliat 20.1.3 Cod surs Listing 20.1.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 //autor Sichim Cristina - 100p #include<fstream> #include <cstring> using namespace std; int main() { int n,k=0,i; long p=1; char s[50]; ifstream f("cluburi.in"); ofstream g("cluburi.out"); f>>n; itoa(n,s,2); for(i=0;i<strlen(s);i++) if(s[i]==’1’)k++; g<<k<<’\n’; for(i=strlen(s)-1;i>=0;i--) { if(s[i]==’1’) g<<p<<’ ’; p=p*2; } g<<’\n’; f.close();g.close(); return 0; cluburi_CS.cpp CAPITOLUL 20. 34 251 ONI 2010 } Listing 20.1.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 cluburi_fara_vectori.CPP //autor Suzana Galatan #include <fstream> using namespace std; ifstream fin("cluburi.in"); ofstream fout("cluburi.out"); int main() { int N; fin >> N ; int k = 0, c = N, cant = 1; int x = N; while(x) { if(x % 2 == 1)k++; x = x/2; } fout << k <<"\n"; while(c) { if(c % 2 == 0) c = c/2, cant = cant * 2; else { c = c/2; fout << cant <<" "; cant = cant * 2; } } fout << "\n"; fin.close(); fout.close(); return 0; } Listing 20.1.3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 cluburi_SG.CPP //autor Suzana Galatan -100p #include <fstream> using namespace std; ifstream fin("cluburi.in"); ofstream fout("cluburi.out"); int main() { long int N; fin >> N ; long int nr = 0, c = N, cant = 1, gasit = 0, c1; int x[100] = {0}; while(c) { if(c % 2 == 0) c = c/2, cant = cant * 2; else { /* if(gasit == 0) { c1 = cant; gasit = 1; } */ nr = nr + 1; CAPITOLUL 20. 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 252 ONI 2010 c = c/2; x[nr] = cant; cant = cant * 2; } } fout << nr <<"\n"; // fout << c1 << " " << cant/ 2 <<"\n"; for(int i = 1; i < nr; i++) fout << x[i] << " "; fout << x[nr] << ’\n’; fin.close(); fout.close(); return 0; } 20.2 domino - ONI 2010 Problema 2 - domino 100 de puncte Ionel are n piese de domino de diverse în lµimi. În joac , el a³eaz (pe o rigl gradat ), la distanµe nu neap rat egale una faµ aceasta cade ³i poate antrena în c dere dup picioare, el merge la prima pies c dere dup piesele vertical într-un ³ir de alta. Ionel atinge prima pies , ea ³i alte piese din ³ir. Dac mai r mân piese în care nu a c zut ³i o atinge. Aceasta cade ³i poate antrena în ea ³i alte piese. Continu procedeul pân când nu mai r mâne nicio pies în picioare. num rul natural n de piese, poziµia pe rigl ³i în lµimea Cerinµe Scrieµi un program care s ec rei piese, în aceast astfel încât s singur cad citeasc ordine, ³i care s determine num rul minim necesar de atingeri ale pieselor toate piesele de domino precum ³i num rul maxim de piese r sturnate la o 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 spaµiu, p reprezentând pozitia piesei pe rigl numere naturale p ³i h, separate printr-un ³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 naturale a ³i b, în aceast linie pe care sunt scrise dou numere 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 p h 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 a Ionel începe întotdeauna cu piesa a³ezat a Se acord pies de domino. la poziµia cea mai mic 50 din punctaj pentru rezolvarea corect a ec rei cerinµe. CAPITOLUL 20. 253 ONI 2010 Figura 20.4: domino Exemple: domino.in 5 domino.out Explicaµii 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 27 2 Num rul de atingeri este 2 iar num rul maxim de piese 28 10 doborâte la o atingere este 3. ³i pe ultima. 37 5 Timp maxim de executare/test: 1.0 secunde 20.2.1 Indicaµii de rezolvare prof. Adriana Simulescu, Liceul Grigore Moisil Timi³oara Descrierea soluµiei Soluµia propus memoreaz în variabila dist poziµia maxim la care acµioneaz o pies care a c zut, în variabila nd num rul de piese doborâte la o atingere ³i în nmax num rul maxim de piese doborâte la o atingere. Pentru ecare pies tualizeaz de domino se veric dac este doborât num rul de piese doborâte la atingerea curent continuare alte piese. de o pies ³i poziµia pân anterioar , se ac- la care se doboar în CAPITOLUL 20. 254 ONI 2010 Figura 20.5: dominoIR 20.2.2 *Rezolvare detaliat 20.2.3 Cod surs Listing 20.2.1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 // Simulescu Adriana -100p #include<fstream> using namespace std; struct domino{int h,p;}; domino d[1001]; int n,nd,dmax,nmax,nr,dist; ifstream f("domino.in"); ofstream g("domino.out"); int main() { int i; f>>n; for(i=1;i<=n;i++) f>>d[i].p>>d[i].h; f.close(); dist=0; for(i=1;i<=n;i++) if(d[i].p>dist||nd==0) { nd++; if(nr>nmax) nmax=nr; dist=d[i].p+d[i].h; nr=1; } else { nr++; domino_AS_1.CPP CAPITOLUL 20. 35 36 37 38 39 40 41 42 43 44 255 ONI 2010 if(dist< d[i].p+d[i].h ) dist=d[i].p+d[i].h; } if(nr>nmax) nmax=nr; g<<nd<<" "<<nmax; g.close(); return 0; } Listing 20.2.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 //Simulescu Adriana -100p #include<fstream> using namespace std; int n,nd,dmax,nmax,nr,dist,h,p; ifstream f("domino.in"); ofstream g("domino.out"); int main() { int i; f>>n; dist=0; nd=0; for(i=1;i<=n;i++) { f>>p>>h; if(p>dist) { nd++; if(nr>nmax) nmax=nr; dist=p+h; nr=1; } else { nr++; if(dist< p+h ) dist=p+h; } } if(nr>nmax) nmax=nr; g<<nd<<" "<<nmax; g.close(); return 0; } Listing 20.2.3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 domino_AS_2.CPP // Carmen Minca -100p #include<fstream> using namespace std; ifstream fi("domino.in"); ofstream fo("domino.out"); struct interval { int a, b, nr; } v[5000]; int comun(int a, int b, int c, int d) domino_CM.CPP CAPITOLUL 20. 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 256 ONI 2010 { if ((b<c)||(d<a)) return 0; return 1; } void rez(int a, int b, int c, int d, int &e, int &f) { e=a; if(e>c) e=c; f=b; if(f<d) f=d; } int main() { int N,p,h,i,k=0,j,max=1,ok; fi>>N; fi>>p>>h; k++; v[k].a=p; v[k].b=p+h; v[k].nr=1; for(i=2;i<=N;i++) { fi>>p>>h;ok=0; for(j=1;(j<=k)&&(ok==0);j++) if(comun(v[j].a,v[j].b,p,p+h)) { rez(v[j].a, v[j].b,p,p+h,v[j].a,v[j].b); v[j].nr++; if(max<v[j].nr)max=v[j].nr; ok=1; } if(ok==0) { k++; v[k].a=p; v[k].b=p+h; v[k].nr=1; } } fo<<k<<’ ’<<max; fi.close(); fo.close(); return 0; } Listing 20.2.4: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // Cristina Sichim - 100p # include <fstream> using namespace std; int main() { ifstream f("domino.in"); ofstream g("domino.out"); int N,p,h,a=1,b=1,nrb=1,i,unde; f>>N; f>>p>>h; unde=p+h; for(i=2;i<=N;i++) { f>>p>>h; if(p<=unde) { nrb++; if(p+h>unde) unde=p+h; } else domino_CS.CPP CAPITOLUL 20. 26 27 28 29 30 31 32 33 34 35 36 37 38 39 257 ONI 2010 { if (nrb>b) b=nrb; nrb=1;a++; unde=p+h; } } if(nrb>b) b=nrb; g<<a<<’ ’<<b; f.close(); g.close(); return 0; } Listing 20.2.5: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 domino_SG.CPP //Suzana Galatan - 100p #include <fstream> using namespace std; ifstream fin("domino.in"); ofstream fout("domino.out"); int main() { int x[1000]; int p, h, smax = 1, pf, i, sfin = 1, buf = 1; int n; fin >> n; fin >> p >> h; pf = p + h; for(i = 2; i <= n; i++) { fin >> p >> h; if(pf >= p) { smax++; if(p + h > pf)pf = p + h; } else { smax = 1; buf++; pf = p + h; } if(sfin < smax) sfin = smax; } fout << buf << " " <<sfin; fout <<"\n"; return 0; } 20.3 max - ONI 2010 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. T2: Se schimb ordinea numerelor din ³irul obµinut dup aplicarea transform rii T 1 astfel CAPITOLUL 20. 258 ONI 2010 î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 T 1 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 din ³ir ³i care s citeasc num rul natural nenul n ³i cele n numere naturale nenule 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 T 1 - 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 obµine un alt num r care are prima cifr nul iar prin aranjarea cifrelor acestui num r se 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 34 23 9 43 21 67 121 79 213 9977643433232121211 devine: 43, 32, 9, 43, 21, 76, 211, 97, aplicarea transform rii T1, ³irul 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 Timp maxim de executare/test: 1.0 secunde 9977643433232121211 CAPITOLUL 20. 20.3.1 259 ONI 2010 Indicaµii de rezolvare prof. Carmen Minc , Liceul Teoretic Ion Neculce - Bucure³ti Descriere soluµie O soluµie posibil se poate obµine prin utilizarea a doi vectori v ³i p, ecare având maxim 3500 de componente întregi. În vectorul v se vor memora numerele din ³irul obµinut în urma transform rii T 1, rezultate din numerele din ³ierul de intrare. Acestea pot citite succesiv într-o variabil Pentru ecare num r memorat în x se separ în v i. iar num rul obµinut se memoreaz valoarea pi k 10 descresc tor aceste cifre În acela³i timp se memoreaz în componenta pi num rul de cifre ale lui v i, pi ind util , unde k reprezint numerelor rezultate prin alipirea a dou În timp ce se aplic cifrele, se ordoneaz x. T 1, se determin în construirea valori din vectorul v . ³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 alipirea, în aceast 1, .., n 1 ³i j i 1.., n se construiesc cele dou numere rezultate prin prin ordine, a numerelor v i ³i v j , respectiv v j ³i v i, adic ³i v j pi v i. Se selecteaz v i pj v j maximul dintre aceste valori. Num rul x cerut se obµine prin alipirea tuturor numerelor din ³irul maximizat. Acest lucru se realizeaz prin scrierea în ³ierul de ie³ire a tuturor numerelor din ³irul maximizat, în ordinea din acest ³ir, f r spaµii între numere. Figura 20.6: maxIR1 CAPITOLUL 20. 260 ONI 2010 Descriere soluµie O alt soluµie posibil prof. Cristina Sichim, C.N. Ferdinand I Bac u 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 x, dup numerele y cu dou prex num rul y . Figura 20.7: maxIR2 20.3.2 *Rezolvare detaliat 20.3.3 Cod surs Listing 20.3.1: 1 2 3 4 5 6 cifre care au prima cifr ecare dintre ele a³ându-se, în ordine descresc toarele numerele cu trei cifre ce au ca //prof.Carmen Minca #include <fstream> using namespace std; int main() - 100p MAX_CM.CPP CAPITOLUL 20. 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 261 ONI 2010 { int n, v[3505], p[3505]; long d,e; int i, max=0,x,a,b,c,j; ifstream f("max.in"); ofstream g("max.out"); f>>n; for(i=1;i<=n;i++) { f>>x; v[i]=x; if(x<10) p[i]=10; else if(x<100) { a=x/10; b=x%10; p[i]=100; if (a<b)v[i]=b*10+a; } else { a=x/100; x=x%100; b=x/10; c=x%10;p[i]=1000; if(a<b) { x=a; a=b; b=x;} if(a<c) { x=a; a=c; c=x;} if(b<c) { x=b; b=c; c=x;} v[i]=100*a+10*b+c; } if(max<v[i])max=v[i]; } g<<max<<endl; for(i=1;i<n;i++) for(j=i+1;j<=n;j++) { d=v[i];d=d*p[j]+v[j]; e=v[j]; e=e*p[i]+v[i]; if (d<e) { x=v[i]; v[i]=v[j]; v[j]=x; x=p[i]; p[i]=p[j]; p[j]=x; } } for(i=1;i<=n;i++) g<<v[i]; g.close(); return 0; } Listing 20.3.2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 MAX_CS.CPP //prof. Cristina Sichim -100p #include<fstream> using namespace std; int n,v[1001],i,x,aux,maxx,y,z,a,b,c; int main() { ifstream f("max.in"); ofstream g("max.out"); f>>n; for(i=1;i<=n;i++) { f>>x; if(x>9 && x<100 && x/10<x%10) x=x%10*10+x/10; if(x>99) { a=x%10;b=x/10%10;c=x/100; if(a<b) {aux=a;a=b;b=aux;} if(a<c) {aux=a;a=c;c=aux;} if(b<c) {aux=b;b=c;c=aux;} x=a*100+b*10+c; } CAPITOLUL 20. 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 262 ONI 2010 v[x]++; if(maxx<x) maxx=x; } g<<maxx<<’\n’; for(x=9;x>0;x--) { //toate care incep cu cifra x while(v[x]--) g<<x; //cele de o cifra for(y=x*10+9;y>=x*10;y--) { while(v[y]--)g<<y; for(z=y*10+x;z>=y*10;z--) while(v[z]--)g<<z; } } g<<’\n’; f.close(); g.close(); return 0; } Listing 20.3.3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 //prof. Suzana Galatan -100p #include <fstream> using namespace std; void Sorteaza(); int maxim(int nr); void Afiseaza(); ifstream fin ("max.in"); ofstream fout("max.out"); int n, max2, m; int c[1001]; int main() { int nr, m = 0, max2 = 0; fin >> n; for(int i = 1; i <= n; i++) { fin >> nr; nr = maxim(nr); c[nr]++; if(nr > m) m = nr; if(nr < 100 && nr > 9) { if(max2 < nr) max2 = nr; } } fout << m; fout << "\n"; // Sorteaza(); Afiseaza(); fin.close(); fout.close(); return 0; } int maxim(int nr) { int a[10] = {0}; while(nr) { a[nr%10]++; nr/=10; MAX_SG.CPP CAPITOLUL 20. 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 ONI 2010 } for(int i = 9; i >= 0; i--) while(a[i]) { nr = nr*10 + i; a[i]--; } return nr; } void Afiseaza() { int i = 9, j, k; /* for(i = 999; i >= 0; i--) while(c[i]) {fout<< i<< " "; c[i]--; }*/ for(i = 9;i > 0; i--) for(j = i*10 +9; j >= i*10; j--) for(k = j*10+9; k >= j*10; k--) { while(c[i]) { if(i >= j /10 || i >= k/100) { fout << i; c[i]--; } } while(c[j]) if(j >= k/10) { fout << j; c[j]--; } while(c[k]) { fout << k; c[k]--; } } } 263 Glosar ³ir sortat, 225 ³irul Fibonacci, 171 18 cifre, 212 algoritm de sortare, 259 alipirea numerelor, 259 alipirea tuturor numerelor, 259 baza 4, 243 citire caracter, 214 Ciurul lui Eratostene, 169 ciurul lui Eratostene, 172 concatenare, 212 descompunere în factori primi, 194 divizori, 30 factor prim, 194 frecvenµa de apariµie, 225 grnerare în baza 4, 225 list , 229 matematic , 228 maximul, 212 minimul, 212 num r de divizori, 194 num r prim, 202 num rul de cifre, 259 num rul de divizori, 30 numere economice, 171 numere mari, 189, 212 optimizare descompunere în factori primi, 194 ordonare, 199, 225, 259 p strare indicii elementelor ordonate, 199 palindrom, 242 permut ri circulare, 30, 246 precalcul, 225 prex, 260 sortare, 199 suma Gauss, 194 tablou unidimensional, 216, 225 tipul întreg, 3 tipul caracter, 3 vector, 196, 202, 203, 214, 243 vector caracteristic, 229, 260 vector de frecvenµ , 168, 169, 214 vectori, 259 264 Bibliograe [1] Aho, A., Hopcroft, J., Ullman, J.D.; Data strutures and algorithms, Addison Wesley, 1983 [2] Andreica M.I.; Elemente de algoritmic - probleme ³i soluµii, Cibernetica MC, 2011 [3] Andonie R., Gârbacea I.; Algoritmi fundamentali, o perspectiv C++, Ed. Libris, 1995 [4] Atanasiu, A.; Concursuri de informatic . Editura Petrion, 1995 [5] Bell D., Perr M.; Java for Students, Second Edition, Prentice Hall, 1999 [6] Calude C.; Teoria algoritmilor, Ed. Universit µii Bucure³ti, 1987 [7] Cerchez, E.; Informatic - Culegere de probleme pentru liceu, Ed. Polirom, Ia³i, 2002 [8] Cerchez, E., erban, M.; Informatic [9] Cori, R.; Lévy, J.J.; - manual pentru clasa a X-a., Ed. Polirom, Ia³i, 2000 Algorithmes et Programmation, Polycopié, version 1.6; http://w3.edu.polytechnique.fr/informatique/ [10] Cormen, T.H., Leiserson C.E., Rivest, R.L.; Introducere în Algoritmi, Ed Agora, 2000 [11] Cormen, T.H., Leiserson C.E., Rivest, R.L.; Pseudo-Code Language, 1994 [12] Cristea, V.; Giumale, C.; Kalisz, E.; Paunoiu, Al.; Limbajul C standard, Ed. Teora, Bucure³ti, 1992 [13] Erickson J.; Combinatorial Algorithms; http://www.uiuc.edu/~jeffe/ [14] Flanagan, D.; Java in a Nutshell, O'Reilly, 1997. [15] Giumale C., Negreanu L., C linoiu S.; Proiectarea ³i analiza algoritmilor. Algoritmi de sortare, Ed. All, 1997 [16] Halim S., Halim F., Competitive programming, 2013 [17] Knuth, D.E.; Arta program rii calculatoarelor, vol. 1: Algoritmi fundamentali, Ed. Teora, 1999. [18] Knuth, D.E.; Arta programarii calculatoarelor, vol. 2: Algoritmi seminumerici, Ed. Teora, 2000. [19] Knuth, D.E.; Arta programarii calculatoarelor, vol. 3: Sortare ³i c utare, Ed. Teora, 2001. [20] Knuth, D.E.; The art of computer programming, vol. 4A: Combinatorial algorithms, Part 1, Addison Wesley, 2011. [21] Lambert,K. A., Osborne,M.; Java. A Framework for Programming and Problem Solving, PWS Publishing, 1999 [22] Laaksonen A.; Guide to competitive programming, Springer, 2017 [23] Livovschi, L.; Georgescu H.; Analiza ³i sinteza algoritmilor. Ed. Enciclopedic , Bucure³ti, 1986. [24] Niemeyer, P., Peck J.; Exploring Java, O'Reilly, 1997. [25] Od gescu, I., Smeureanu, I., tef nescu, I.; Programarea avansat Ed. Militar , Bucure³ti 1993 265 a calculatoarelor personale, 266 BIBLIOGRAFIE [26] Od gescu, I.; Metode ³i tehnici de programare, Ed. Computer Lobris Agora, Cluj, 1998 [27] Popescu Anastasiu, D.; Puncte de articulaµie ³i punµi în grafuri, Gazeta de Informatic nr. 5/1993 [28] R bâea, A.; https://math.univ-ovidius.ro/Doc/Admitere/CentruPregatire/ 2007/Info/Lista_probleme_2000-2007.pdf [29] R bâea, A.; https://math.univ-ovidius.ro/Doc/Admitere/CentruPregatire/ 2007/Info/Rezolvari_C09.pdf [30] R bâea, A.; https://math.univ-ovidius.ro/Doc/Admitere/CentruPregatire/ 2007/Info/Rezolvari_C10.pdf [31] R bâea, A.; https://math.univ-ovidius.ro/Doc/Admitere/CentruPregatire/ 2007/Info/Rezolvari_C11.pdf [32] R bâea, A.; https://math.univ-ovidius.ro/Doc/Admitere/CentruPregatire/ 2007/Info/Rezolvari_Baraj.pdf [33] Skiena S.S., Revilla M.A.; Programming challenges - The Programming Contest Training Manual, Springer, 2003 [34] Tomescu, I.; Probleme de combinatoric ³i teoria grafurilor, Editura Didactic ³i Pedagogic , Bucure³ti, 1981 [35] Tomescu, I.; Leu, A.; Matematic aplicat în tehnica de calcul, Editura Didactic ³i Pedago- gic , Bucure³ti, 1982 [36] V duva, C.M.; Programarea in JAVA. Microinformatica, 1999 [37] Vi³inescu, R.; Vi³inescu, V.; Programare dinamic - teorie ³i aplicaµii; GInfo nr. 15/4 2005 [38] Vlada, M.; Conceptul de algoritm - abordare modern , GInfo, 13/2,3 2003 [39] Vlada, M.; Grafuri neorientate ³i aplicaµii. Gazeta de Informatic , 1993 [40] Weis, M.A.; Data structures and Algorithm Analysis, Ed. The Benjamin/Cummings Publishing Company. Inc., Redwoods City, California, 1995. [41] Winston, P.H., Narasimhan, S.; On to JAVA, Addison-Wesley, 1996 [42] Wirth N.; Algorithms + Data Structures = Programs, Prentice Hall, Inc 1976 [43] *** - Gazeta de Informatic , Editura Libris, 1991-2005 [44] *** https://github.com/DinuCr/CS/blob/master/Info/stuff%20stuff/ Rezolvari_C09.pdf [45] *** - https://dokumen.tips/documents/rezolvaric09.html [46] *** - https://www.scribd.com/doc/266218102/Rezolvari-C09 [47] *** - https://www.scribd.com/document/396362669/Rezolvari-C10 [48] *** - https://www.scribd.com/document/344769195/Rezolvari-C11 [49] *** - https://www.scribd.com/document/364077679/Rezolvari-C11-pdf