#include <array> #include <iostream> #include <tuple> #include <string> #include <vector> using namespace std; using czas_t = long long; struct Znajomy { int gora; int dol; }; struct Punkt { int x; int y; }; bool operator== (Punkt const& a, Punkt const&b) { return tie(a.x, a.y) == tie(b.x, b.y); } struct Delta { int delta_x; int delta_y; }; struct Kroki { int gora; int dol; }; struct Rozwiazanie { czas_t czas; int ilu; }; struct Tresc { vector< string > mapa; vector< Znajomy > znajomi; }; Tresc wczytaj_dane() { Tresc tr; int h, m, l_znaj; cin >> h >> m >> l_znaj; tr.mapa.resize(h+2); tr.mapa.front() = string(m+2, 'X'); for(int i = 1; i < h + 1; ++i) { string wiersz; cin >> wiersz; tr.mapa[i] = 'X' + wiersz + 'X'; } tr.mapa.back() = string(m+2, 'X'); tr.znajomi.resize(l_znaj); for(int i = 0; i < tr.znajomi.size(); ++i) { cin >> tr.znajomi[i].gora >> tr.znajomi[i].dol; } return tr; } int oblicz_droge(Tresc& tr) { Punkt poczatek = { 1, 1 }; Punkt koniec = { static_cast< int >(tr.mapa[0].size()) - 2, static_cast< int >(tr.mapa.size()) - 2 }; vector< Punkt > kolejka = { poczatek }; array< Delta, 4 > kroki = { Delta{-1, 0}, Delta{1, 0}, Delta{0, -1}, Delta{0, 1} }; int odleglosc = 0; while(kolejka.size()) { vector< Punkt > nastepna; odleglosc += 1; while(kolejka.size()) { Punkt p = kolejka.back(); kolejka.pop_back(); for( auto&& k : kroki ) { Punkt sasiad = { p.x + k.delta_x, p.y + k.delta_y }; if( tr.mapa[sasiad.y][sasiad.x] == '.' ) { tr.mapa[sasiad.y][sasiad.x] = '0' + (odleglosc % 10); nastepna.push_back(sasiad); if( sasiad == koniec) { return odleglosc; } } } } swap(kolejka, nastepna); } return odleglosc; } Kroki policz_kroki(Tresc const& tr, int odl) { int wzniesienie_poludnie = tr.mapa.size() - 1 - 2; int wzniesienie_wschod = tr.mapa.front().size() - 1 - 2; int wzniesienie = wzniesienie_wschod + wzniesienie_poludnie; int kroki_nadmiarowe = odl - wzniesienie; Kroki wynik; wynik.gora = wzniesienie + kroki_nadmiarowe / 2; wynik.dol = kroki_nadmiarowe / 2; return wynik; } czas_t policz_czas(Znajomy const& z, Kroki const& kr) { return static_cast< czas_t >(kr.gora) * static_cast< czas_t >(z.gora) + static_cast< czas_t >(kr.dol) * static_cast< czas_t >(z.dol); } Rozwiazanie policz_czasy(Tresc const& tr, Kroki const& kr) { Rozwiazanie wynik { policz_czas(tr.znajomi.front(), kr), 0 }; for( auto&& z : tr.znajomi) { czas_t czas = policz_czas(z, kr); if(wynik.czas == czas) { wynik.ilu += 1; } else if(czas < wynik.czas) { wynik.czas = czas; wynik.ilu = 1; } } return wynik; } int main() { Tresc tr = wczytaj_dane(); int odl = oblicz_droge(tr); Kroki kroki = policz_kroki(tr, odl); Rozwiazanie wynik = policz_czasy(tr, kroki); cout << wynik.czas << " " << wynik.ilu << "\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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | #include <array> #include <iostream> #include <tuple> #include <string> #include <vector> using namespace std; using czas_t = long long; struct Znajomy { int gora; int dol; }; struct Punkt { int x; int y; }; bool operator== (Punkt const& a, Punkt const&b) { return tie(a.x, a.y) == tie(b.x, b.y); } struct Delta { int delta_x; int delta_y; }; struct Kroki { int gora; int dol; }; struct Rozwiazanie { czas_t czas; int ilu; }; struct Tresc { vector< string > mapa; vector< Znajomy > znajomi; }; Tresc wczytaj_dane() { Tresc tr; int h, m, l_znaj; cin >> h >> m >> l_znaj; tr.mapa.resize(h+2); tr.mapa.front() = string(m+2, 'X'); for(int i = 1; i < h + 1; ++i) { string wiersz; cin >> wiersz; tr.mapa[i] = 'X' + wiersz + 'X'; } tr.mapa.back() = string(m+2, 'X'); tr.znajomi.resize(l_znaj); for(int i = 0; i < tr.znajomi.size(); ++i) { cin >> tr.znajomi[i].gora >> tr.znajomi[i].dol; } return tr; } int oblicz_droge(Tresc& tr) { Punkt poczatek = { 1, 1 }; Punkt koniec = { static_cast< int >(tr.mapa[0].size()) - 2, static_cast< int >(tr.mapa.size()) - 2 }; vector< Punkt > kolejka = { poczatek }; array< Delta, 4 > kroki = { Delta{-1, 0}, Delta{1, 0}, Delta{0, -1}, Delta{0, 1} }; int odleglosc = 0; while(kolejka.size()) { vector< Punkt > nastepna; odleglosc += 1; while(kolejka.size()) { Punkt p = kolejka.back(); kolejka.pop_back(); for( auto&& k : kroki ) { Punkt sasiad = { p.x + k.delta_x, p.y + k.delta_y }; if( tr.mapa[sasiad.y][sasiad.x] == '.' ) { tr.mapa[sasiad.y][sasiad.x] = '0' + (odleglosc % 10); nastepna.push_back(sasiad); if( sasiad == koniec) { return odleglosc; } } } } swap(kolejka, nastepna); } return odleglosc; } Kroki policz_kroki(Tresc const& tr, int odl) { int wzniesienie_poludnie = tr.mapa.size() - 1 - 2; int wzniesienie_wschod = tr.mapa.front().size() - 1 - 2; int wzniesienie = wzniesienie_wschod + wzniesienie_poludnie; int kroki_nadmiarowe = odl - wzniesienie; Kroki wynik; wynik.gora = wzniesienie + kroki_nadmiarowe / 2; wynik.dol = kroki_nadmiarowe / 2; return wynik; } czas_t policz_czas(Znajomy const& z, Kroki const& kr) { return static_cast< czas_t >(kr.gora) * static_cast< czas_t >(z.gora) + static_cast< czas_t >(kr.dol) * static_cast< czas_t >(z.dol); } Rozwiazanie policz_czasy(Tresc const& tr, Kroki const& kr) { Rozwiazanie wynik { policz_czas(tr.znajomi.front(), kr), 0 }; for( auto&& z : tr.znajomi) { czas_t czas = policz_czas(z, kr); if(wynik.czas == czas) { wynik.ilu += 1; } else if(czas < wynik.czas) { wynik.czas = czas; wynik.ilu = 1; } } return wynik; } int main() { Tresc tr = wczytaj_dane(); int odl = oblicz_droge(tr); Kroki kroki = policz_kroki(tr, odl); Rozwiazanie wynik = policz_czasy(tr, kroki); cout << wynik.czas << " " << wynik.ilu << "\n"; } |