#include <iostream>
#include <vector>
#include <climits>
#include <cmath>
using namespace std;
struct A {
A() : minimum(LLONG_MAX) {}
long long minimum;
long long po_calosci;
};
vector<unsigned> oszczednosci;
vector<int> cykl;
vector<A*> wyniki;
long long ObliczDlugoscCalegoCyklu(unsigned ile_kolegow, unsigned dlugosc_cyklu)
{
long long dlugosc = 0;
unsigned n = 0;
do {
n = (n + ile_kolegow) % dlugosc_cyklu;
++dlugosc;
} while(n != 0);
return dlugosc;
}
void ObliczCykl(unsigned n, unsigned ile_kolegow, long long dlugosc_calosci, unsigned dlugosc_cyklu) {
A* a = new A();
long long wartosc = 0;
if (wyniki[n])
return;
for (long long i = 0; i < dlugosc_calosci; ++i) {
wartosc += cykl[n];
n = (n + ile_kolegow) % dlugosc_cyklu;
if (wartosc < a->minimum)
a->minimum = wartosc;
wyniki[n] = a;
}
a->po_calosci = wartosc;
cerr << n << " min: " << a->minimum << " po: " << a->po_calosci << "\n";
}
long long ObliczIleDoZera(unsigned n, long long wartosc) {
long long ile = 0;
while (wartosc) {
wartosc += cykl[n];
n = (n + oszczednosci.size()) % cykl.size();
++ile;
}
return ile;
}
long long ObliczIloscGier(unsigned k, long long dlugosc) {
long long ile_calosci = 0;
long long n = k % cykl.size();
if (oszczednosci[k] <= wyniki[n]->minimum) {
ile_calosci = 0;
} else if (wyniki[n]->po_calosci <= 0) {
return LLONG_MAX;
} else {
ile_calosci = ceil(((double)(oszczednosci[k] - wyniki[n]->minimum)) / wyniki[n]->po_calosci);
}
long long ile = ObliczIleDoZera(n, oszczednosci[k] - (ile_calosci * wyniki[n]->po_calosci));
cerr << k <<"\n";
return k + 1 + (ile_calosci * dlugosc + ile - 1) * oszczednosci.size();
}
int main() {
unsigned ile_kolegow, dlugosc_cyklu;
cin >> ile_kolegow ;
oszczednosci.reserve(ile_kolegow);
for (unsigned k = 0; k < ile_kolegow; ++k) {
unsigned o;
cin >> o;
oszczednosci.push_back(o);
}
cin >> dlugosc_cyklu;
wyniki.resize(dlugosc_cyklu);
cykl.reserve(dlugosc_cyklu);
for (unsigned c = 0; c < dlugosc_cyklu; ++c) {
char ch;
cin >> ch;
if (ch == 'P')
cykl.push_back(-1);
else
cykl.push_back(1);
}
long long dlugosc = ObliczDlugoscCalegoCyklu(ile_kolegow, dlugosc_cyklu);
cerr << dlugosc << "\n";
for (unsigned n = 0; n < dlugosc_cyklu; ++n) {
ObliczCykl(n, ile_kolegow, dlugosc, dlugosc_cyklu);
}
cerr << "juz\n";
for (A* a : wyniki) {
a->minimum *= -1;
a->po_calosci *= -1;
}
long long minimum = LLONG_MAX;
for (unsigned k = 0; k < ile_kolegow; ++k) {
long long ile_gier = ObliczIloscGier(k, dlugosc);
if (ile_gier < minimum)
minimum = ile_gier;
}
if (minimum == LLONG_MAX)
cout << -1 << "\n";
else
cout << minimum << "\n";
}
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 | #include <iostream> #include <vector> #include <climits> #include <cmath> using namespace std; struct A { A() : minimum(LLONG_MAX) {} long long minimum; long long po_calosci; }; vector<unsigned> oszczednosci; vector<int> cykl; vector<A*> wyniki; long long ObliczDlugoscCalegoCyklu(unsigned ile_kolegow, unsigned dlugosc_cyklu) { long long dlugosc = 0; unsigned n = 0; do { n = (n + ile_kolegow) % dlugosc_cyklu; ++dlugosc; } while(n != 0); return dlugosc; } void ObliczCykl(unsigned n, unsigned ile_kolegow, long long dlugosc_calosci, unsigned dlugosc_cyklu) { A* a = new A(); long long wartosc = 0; if (wyniki[n]) return; for (long long i = 0; i < dlugosc_calosci; ++i) { wartosc += cykl[n]; n = (n + ile_kolegow) % dlugosc_cyklu; if (wartosc < a->minimum) a->minimum = wartosc; wyniki[n] = a; } a->po_calosci = wartosc; cerr << n << " min: " << a->minimum << " po: " << a->po_calosci << "\n"; } long long ObliczIleDoZera(unsigned n, long long wartosc) { long long ile = 0; while (wartosc) { wartosc += cykl[n]; n = (n + oszczednosci.size()) % cykl.size(); ++ile; } return ile; } long long ObliczIloscGier(unsigned k, long long dlugosc) { long long ile_calosci = 0; long long n = k % cykl.size(); if (oszczednosci[k] <= wyniki[n]->minimum) { ile_calosci = 0; } else if (wyniki[n]->po_calosci <= 0) { return LLONG_MAX; } else { ile_calosci = ceil(((double)(oszczednosci[k] - wyniki[n]->minimum)) / wyniki[n]->po_calosci); } long long ile = ObliczIleDoZera(n, oszczednosci[k] - (ile_calosci * wyniki[n]->po_calosci)); cerr << k <<"\n"; return k + 1 + (ile_calosci * dlugosc + ile - 1) * oszczednosci.size(); } int main() { unsigned ile_kolegow, dlugosc_cyklu; cin >> ile_kolegow ; oszczednosci.reserve(ile_kolegow); for (unsigned k = 0; k < ile_kolegow; ++k) { unsigned o; cin >> o; oszczednosci.push_back(o); } cin >> dlugosc_cyklu; wyniki.resize(dlugosc_cyklu); cykl.reserve(dlugosc_cyklu); for (unsigned c = 0; c < dlugosc_cyklu; ++c) { char ch; cin >> ch; if (ch == 'P') cykl.push_back(-1); else cykl.push_back(1); } long long dlugosc = ObliczDlugoscCalegoCyklu(ile_kolegow, dlugosc_cyklu); cerr << dlugosc << "\n"; for (unsigned n = 0; n < dlugosc_cyklu; ++n) { ObliczCykl(n, ile_kolegow, dlugosc, dlugosc_cyklu); } cerr << "juz\n"; for (A* a : wyniki) { a->minimum *= -1; a->po_calosci *= -1; } long long minimum = LLONG_MAX; for (unsigned k = 0; k < ile_kolegow; ++k) { long long ile_gier = ObliczIloscGier(k, dlugosc); if (ile_gier < minimum) minimum = ile_gier; } if (minimum == LLONG_MAX) cout << -1 << "\n"; else cout << minimum << "\n"; } |
English