2 - Kule
Vremensko ograničenje | Memorijsko ograničenje |
---|---|
1000ms | 64MB |
Članovi Tajne Komisije, mali Perica i mali Tuks, u pauzama između pripreme zadataka i spremanja ispita vole da igraju društvenu igru ”Kule”. Pravila igre podrazumevaju da u početku na raspolaganju imamo neki broj kockica, naslaganih jedna na drugu, u obliku kule.
Jedan potez podrazumeva da Perica izdeli kulu na dve ili više manjih kula, i poređa takve kule u niz; Tuks zatim mora da odabere jednu od tih manjih kula, koja će se koristiti za naredne poteze (sve ostale kule se odbacuju). Ukoliko je Tuks odabrao \(k\)-tu kulu u nizu, Perica je u obavezi da mu isplati \(k^2\) dinara (npr. ukoliko je Tuks odabrao treću kulu, Perica mora odmah da mu da devet dinara). Igra se završava u onom momentu kada trenutna kula ima samo jednu kockicu.
Kako je odveć poznato da članovi Tajne Komisije nemaju vremena ni za šta (a samim tim ni za igranje igara), Perica i Tuks su odlučili da, umesto da odigraju partiju ”Kula”, poveruju jedan drugom da bi obojica igrali optimalno, i da Perica odmah isplati Tuksu iznos koji bi osvojio pod tim uslovom. Zamolili su vas za pomoć u određivanju ovog iznosa.
Opisi funkcija
Potrebno je implementirati funkciju
- \(Iznos(L,N[…],Sol[…],N_k,N_(C_1 ),C_1 […])\);
ova funkcija se poziva samo jednom na početku programa i označava da treba odrediti iznos koji Perica mora isplatiti Tuksu, ukoliko je početna kula imala \(N\) kockica (\(N\) je zadat kao niz cifara dužine \(L\)). Traženi iznos treba ”popuniti” u niz \(Sol\), takođe u vidu niza cifara. Vaša funkcija mora da kao povratnu vrednost vrati dužinu niza \(Sol\), tj. broj cifara rešenja.
Vaše rešenje takođe treba da odredi prvi potez koji Perica povlači, ukoliko rezultuje u manje od \(1000\) kula. U promenljivu \(N_k\) je potrebno smestiti broj manjih kula u prvoj optimalnoj podeli; ukoliko je ovaj broj veći od \(1000\), upisati \(-1\).
Ukoliko je optimalan broj manjih kula manji ili jednak \(1000\), niz \(C_1\) treba ”popuniti” nizovima cifara visina ovih kula (kraj jednog takvog niza cifara označiti brojem -1). Na primer, ukoliko želite da napravite podelu na kule visina 10 i 4, onda \(C_1=[1,0,-1,4,-1]\). Veličinu niza \(C_1\) treba smestiti u promenljivu \(N_{C_1}\).
Ukoliko ima više optimalnih prvih podela, odredite bilo koju. Nizove indeksirati od 0!
Primer
Pretpostavimo da je vaš program dobio naredbu da izvrši: Iznos(1,[7],Sol,N_k,N_(C_1 ),C_1 )
.
U ovom slučaju, rešenje je \(Sol=[8]\), \(N_k=2\), \(N_{C_1}=4\), \(C_1=[5,-1,2,-1]\); povratna vrednost vaše funkcije treba da bude 1.
U jednom od mogućih optimalnih rešenja, Perica najpre deli kulu na dve kule visina 5 i 2. Ukoliko Tuks odabere drugu kulu (visine 2), dobija odmah 4 dinara, i Perica je nakon toga primoran da ovu kulu podeli na dve kule visine 1, nakon čega Tuks ponovo dobija 4 dinara (8 ukupno). Ukoliko Tuks odabere prvu kulu, Perica može u svakom narednom potezu da deli kulu na dve kule od kojih druga ima visinu 1; u ovom slučaju, Tuks će pri optimalnoj strategiji četiri puta dobiti po jedan dinar, da bi na samom kraju dobio četiri (ponovo 8 ukupno).
Ne postoji početna podela kule visine 7 koja će rezultovati u manjem iznosu.
Ograničenja
- \(2\leq N\leq 10^{100}\)
Podzadaci i bodovanje
Test primeri su podeljeni u pet podzadatka, u kojima važe sledeća dodatna ograničenja:
- PODZADATAK 1 [10 POENA]: \(N\leq 20\).
- PODZADATAK 2 [15 POENA]: \(N\leq 1000\).
- PODZADATAK 3 [20 POENA]: \(N\leq 10^6\).
- PODZADATAK 4 [20 POENA]: \(N\leq 10^18\).
- PODZADATAK 5 [35 POENA]: Nema dodatnih ograničenja.
Ukoliko na svim test primerima jednog podzadatka izračunate tačan iznos koji Perica treba da isplati Tuksu, dobijate 60% poena za taj podzadatak. Ukoliko korektno odredite optimalan prvi Peričin potez na svim test primerima jednog podzadatka, dobijate 40% poena za taj podzadatak.
Detalji implementacije
Potrebno je da pošaljete tačno jedan fajl, pod nazivom kule.c, kule.cpp ili kule.pas, koji implementira gore pomenutu funkciju. Osim tražene funkcije, vaš fajl može sadržati i dodatne globalne promenljive, pomoćne funkcije i dodatne biblioteke.
Zavisno od programskog jezika koji koristite, vaša funkcija/procedura mora biti sledećeg oblika:
C/C++
int Iznos(int L, int* N, int* Sol, int* Nk, int* NC1, int* C1);
Pascal
function Iznos(L : longint; var N, Sol : array of longint; var Nk, NC1 : longint; var C1 : array of longint) : longint;
Ukoliko radite u C/C++-u, potrebno je na početku fajla staviti #include “kule.h”
a ukoliko radite u Pascal-u, potrebno je na početku fajla staviti Unit kule;
(ovo je već dodato u fajlovima koji su vam obezbeđeni).
Testiranje i eksperimentisanje
Uz zadatak, obezbeđeni su vam “template” fajlovi (kule.c, kule.cpp, kule.pas) koje možete koristiti i menjati po potrebi. Takođe su vam obezbeđeni programi (grader.c, grader.cpp, grader.pas) koji služe da lakše testirate kodove. Ovi programi učitavaju sa standardnog ulaza string koji predstavlja niz cifara broja \(N\), \(Cif[...]\).
Zatim pozivaju funkciju \(Iznos(L,Cif,Sol,N_k,N_{C_1},C_1)\) i ispisuju na standardni izlaz sadržaj niza \(Sol\), kao i vrednost promenljive \(N_k\) i sadržaj niza \(C_1\). Nizovi se ispisuju bez razmaka; unutar niza \(C_1\) umesto \(-1\) se ispisuju razmaci.
Autor | Tekst i test primeri | Analiza rеšenja | Testiranje |
---|---|---|---|
Dušan Zdravković | Dragan Urošević | - | Petar Veličković |
02_kule.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 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 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 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 |
|