4 - Mudrac
Vremensko ograničenje | Memorijsko ograničenje |
---|---|
500ms | 64MB |
Tajna komisija nema vremena ni za šta a samim tim ni za smišljanje zadataka za SIO. Zbog toga su prevalili daleki put do Kazahstanskih planina (za to imaju vremena) i zatražili od čuvenog mudraca-programera iz pećine Didžita Programbajeva da im smisli zadatak. I on im reče:
“Ljudi, na početku, prvog dana, imao sam \(A\) kamila. Svakog narednog dana dobijam još onoliko kamila koliko je jednaka najveća cifra broja mojih kamila dan pre toga. Obratite pažnju da ja sve to stalno posmatram po modulu \(M\) tj. ukoliko je \(a_i\) broj kamila koje imam \(i\)-tog dana, tada važi
Ukoliko je prošlo \(N\) dana, odrediti koliko ima kilometara između Astane i Alma-Atija. Eto.”
Članovi komisije su se malo zbunili neočekivanim krajem zadatka pa su rešili da ga malo izmene: za date prirodne brojeve \(A\), \(M\) i \(N\), izračunajte koliko kamila ima mudrac na kraju \(N\)-tog dana.
Opisi funkcija
Potrebno je da implementirate funkciju
- BrojKamila(A,M,N)
gde je \(A\) – broj kamila prvog dana, \(M\) – moduo po kome se posmatraju članovi niza i \(N\) – broj dana koji su prošli. Ova funkcija mora da vrati jedan ceo broj iz segmenta \([0,M-1]\) – broj kamila koje poseduje mudrac na kraju \(N\)-tog dana.
Primer
Neka je \(A=123\), \(M=134\) i \(N=6\). Ukoliko sa \(a_i\) označimo broj kamila \(i\)-tog dana, tada važi: \(a_1=A=123\), \(a_2=(123+3) \text{ mod } 134=126\), \(a_3=(126+6) \text{ mod } 134=132\), \(a_4=(132+3) \text{ mod } 134=1\), \(a_5=(1+1) \text{ mod } 134=2\), \(a_6=(2+2) \text{ mod }134=4\). Prema tome, u ovom slučaju vaša funkcija mora da vrati broj \(4\).
Ograničenja
- \(1\leq A < M\leq 10^{18}\)
- \(1\leq N\leq 10^{18}\)
Podzadaci i bodovanje
- PODZADATAK 1 [5 POENA]: \(N\leq 10^6\)
- PODZADATAK 2 [12 POENA]: \(M\leq 10^6\)
- PODZADATAK 3 [25 POENA]: \(A=1\), \(M=201520152015\) i \(N\leq 10^9\).
- PODZADATAK 4 [41 POENA]: \(A,N\leq 10^{17}\), \(M=10^{18}\).
- PODZADATAK 5 [17 POENA]: Nema dodatnih ograničenja.
Detalji implementacije
Potrebno je da pošaljete tačno jedan fajl, pod nazivom mudrac.c, mudrac.cpp ili mudrac.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++
long long BrojKamila(long long A, long long M, long long N);
Pascal
function BrojKamila(A, M, N : int64) : int64;
Ukoliko radite u C/C++-u, potrebno je na početku fajla staviti #include “mudrac.h”
a ukoliko radite u Pascal-u, potrebno je na početku fajla staviti Unit mudrac;
(ovo je već dodato u fajlovima koji su vam obezbeđeni).
Testiranje i eksperimentisanje
Uz zadatak, obezbeđeni su vam “template” fajlovi (mudrac.c, mudrac.cpp, mudrac.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 sledeće podatke:
- U prvom i jedinom redu brojeve \(A\), \(M\) i \(N\), redom, razdvojene razmakom
a zatim pozivaju vašu funkciju \(BrojKamila\) iz odgovarajućeg fajla (mudrac.c, mudrac.cpp, mudrac.pas) sa učitanim parametrima i na kraju vrednost koju vaša funkcija vraća ispisuju na standardni izlaz. Kodove ovih programa možete menjati po potrebi.
Autor | Tekst i test primeri | Analiza rеšenja | Testiranje |
---|---|---|---|
Nikola Milosavljević | Nikola Milosavljević | Mihail Tihomirov | Aleksandar Ivanović |
For now, ignore the modulo. Suppose that the current number \(x = a\cdot 10^p + d\) for some non-negative integers \(a\), \(p\) and \(0 \leq d < 10\).
Until \(x\) reaches \(\geq (a + 1)\cdot 10^p\), the sequence of changes to \(x\) depends only on \(p\), \(d\), and \(k\) — the largest digit of \(a\). Right after that we will have \((a+1)\cdot 10^p \leq x < (a+1)\cdot 10^p+10\), since each increase is by at most \(9\).
Let \(steps_{p,d,k}\) and \(delta_{p,d,k}\) be the number of steps and total change made to \(x\) until \(x\) reaches \(\geq (a + 1) \cdot 10^p\). We can calculate \(steps_{p,d,k}\) and \(delta_{p,d,k}\) for all \(p > 0\), \(d\), \(m\) by using \(steps_{p−1,\ldots,\ldots}\) and \(delta_{p−1,\ldots,\ldots}\) to quickly skip stages of the process.
Note that \(steps_{p,0,0}\) and \(delta_{p,0,0}\) are undefined since no increases are ever made.
Using \(steps_{p,d,k}\) and \(delta_{p,d,k}\) we can quickly calculate:
- the value of any \(x\) after \(n\) steps (provided \(x\) never exceeds \(m\));
- the number of steps we take starting from \(x\) until \(x > m\), and the resulting value of \(x\).
To do this, find the largest \(p\) such that \(x \text{ mod } 10^p < 10\), and also, if \(p > 0\), \(steps_{p,x \text{ mod } 10^p,k} \leq n\) or \(x+ delta_{p,x \text{ mod } 10^p,k} \leq m\) (\(k\) being the largest digit of \(\lfloor x/10^p\rfloor\)), and use this to skip ahead in the process. Only \(O(\log m)\) of such skips are required.
Now we can solve the problem. Whenever we skip ahead, we assume that \(x\) and the remaining number of steps \(n\) decrease accordingly. Whenever \(n = 0\), we terminate.
One method is to repeatedly find the first moment when either \(x > m\) or \(n = 0\). After that, if \(n > 0\), we take \(x \text{ mod } m\) and go again. If at any point \(x = 0\), we immedaitely terminate.
This may work very slow when \(n\) is much larger than \(m\). However, by looking at the values of \(x\) after taking modulo \(m\), we notice that the process becomes periodic after at most \(10\) loops.
If the period takes \(z\) steps, take \(n\) modulo \(z\) to skip many periods ahead. After this, at most \(10\) further loops are required.
04_mudrac.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 |
|