4 - Antimaterijski top
Vremensko ograničenje | Memorijsko ograničenje |
---|---|
1000ms | 256MB |
Profesor Đurić, sada već malo nagluv, je na Tavanu pronašao svoj antimaterijski top iz mladih dana. Oduvavši prašinu, prisetio se eksperimenta koji je nekada izvodio sa njim.
U poljima matrice sa \(N\) redova i \(M\) kolona nalazili su se pozitroni, elektroni i gravitoni. Svako polje sadržalo je tačno jednu od čestica. Namena antimaterijskog topa bila je da promeni sve elemente u jednom redu njihovim odgovarajućim antičesticama. Pozitron je antičestica elektrona, i ubrnuto, dok je graviton antičestica sam sebi. Cilj eksperimenta bio je da primenom antimaterijskog topa na neke vrste dobijemo unapred određeni broj pozitrona u svakoj koloni. Sada se profesor Đirić pita na koliko načina je to moglo da se uradi.
Izračunajte traženi broj umesto profesora i time mu pomozite da što pre siđe sa Tavana.
Opisi funkcija
Potrebno je da implementirate funkciju:
BrojNacina(N, M, matrica, vektor)
gde je \(N\) - broj redova u matrici, \(M\) - broj kolona u matrici, \(matrica\) – matrica karaktera dimenzija \(N\times M\) gde se na polju \((i,j)\) matrice može nalaziti jedan od sledeća tri karaktera p
, e
, g
koji redom označavaju da se na polju \((i,j)\) nalazi pozitron, elektron ili graviton, \(vektor\) – niz dužine \(M\) gde \(i\)-ti broj označava da se nakon upotrebe antimaterijskog topa u koloni \(i\) treba nalaziti \(vektor[i]\) pozitrona.
Primer 1
Neka je \(N = 5\), \(M = 3\), a matrica neka je data sledećom tabelom:
\(vector = \{1, 2, 2\}\)
Traženi broj pozitrona po kolona se može dobiti na \(3\) načina:
- Ako primenimo antimaterijski top na vrste \(3\) i \(5\);
- Ako primenimo antimaterijski top na vrste \(1\), \(2\) i \(3\);
- Ako primenimo antimaterijski top na vrste \(1\), \(3\), \(4\) i \(5\).
Primer 2
Neka je \(N = 2\), \(M = 2\), a matrica data sledećom tabelom:
\(vector = \{1,1\}\)
Traženi broj pozitrona po kolona se ne može dobiti.
Ograničenja
- \(1 \leq N, M \leq 30\).
- Svaki element matrice će biti iz skupa {
p
,e
,g
}.
Podzadaci:
- PODZADATAK \(1\) [\(11\) POENA]: \(1\leq N, M\leq 15\).
- PODZADATAK \(2\) [\(15\) POENA]: \(M = 1\).
- PODZADATAK \(3\) [\(19\) POENA]: Dovoljno je odgovoriti da li postoji barem jedan način da se dobije zadati raspored pozitrona po kolonama. Poeni se dobijaju u slučaju da je broj načina \(0\) i vaš program je ispisao \(0\), ili ukoliko je broj načina veći od \(0\), a vaš program je ispisao prirodan broj manji od \(10^18\).
- PODZADATAK \(4\) [\(55\) POENA] : Nema dodatnih ograničenja.
Detalji implementacije
Potrebno je da pošaljete tačno jedan fajl, pod nazivom top.c
, top.cpp
ili top.pas
, koji implementira gore pomenuty funkcijy. 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še funkcije/procedure moraju biti sledećeg oblika:
C/C++:
long long BrojNacina(int N, int M, char **mapa, int *vektor);
Pascal:
function BrojNacina(N: integer; M: integer; mapa: array of array of char; vector: array of integer)
Testiranje i eksperimentisanje
Uz zadatak, obezbeđeni su vam “template” fajlovi (top.c
, top.cpp
, top.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 redu brojeve \(N\), \(M\) razdvojene razmakom;
- U narednih \(N\) redova po \(M\) odgovarajućih karaktera;
- U poslednjoj liniji \(M\) celih brojeva koji predstavljaju promenljivu \(vektor\);
zatim pozivaju vašu funkciju BrojNacina
iz odgovarajućeg fajla (top.c
, top.cpp
, top.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 |
---|---|---|---|
Marko Savić | Demjan Grubić | Aleksandar Višnjić | Marko Savić |
Prvi podzadatak
Generišimo svih \(2^N\) vektora koji predstavljaju krajnje zbirove po kolonama nakon korišćenja antimaterijskog topa. Potrebno je za svaki proveriti da li se podudara sa traženim vektorom. Složenost je \(O(2^N \cdot M)\).
Drugi podzadatak
Potrebno je proveriti na koliko načina možemo izabrati podskup našeg skupa tako da je njegov zbir jednak traženom broju. Pošto je \(n\leq 30\), to radimo tehnikom meet in the middle: Podelimo naš skup na dve jednake polovine, generižemo svih \(2^{\frac{N}{2}}\) mogućnosti za oba skupa, i preko sortiranja i dva pokazivača odredimo koliko ima zbirova dva broja iz oba skupa koji su jednaki datom broju. Složenost je \(O(2^{\frac{N}{2}} \cdot N)\).
Glavno rešenje
Opet koristimo meet in the middle, ali ovaj put mapiramo vektore. Deljenjem matrice na gornji i donji deo koji su približno jednaki možemo generisati sve moguće vektore. Zatim je potrebno proveriti za dva skupa na koliko načina možemo izabrati po jedan vektor iz svakog tako da njihov zbir bude jednak traženom vektoru. To radimo tako što za prvi skup mapiramo sve vektore (map<vector< int>, int>, brojimo koliko ima svakog od vektora) a za svaki vektor iz drugog skupa proveravamo koliko ima vektora iz prvog koji su jednaki razlici traženog vektora i vektora iz drugog skupa. Složenost je \(O(2^{\frac{N}{2}}\cdot N \cdot M)\).
04_antimaterijski_top.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 |
|