#ifndef LOCAL
#pragma GCC optimize("O3")
#endif
#include <bits/stdc++.h>
using namespace std;
#define sim template <class c
#define mor > muu & operator<<(
#define ris return *this
#define R22(r) sim>typename enable_if<1 r sizeof(dud<c>(0)),muu&>::type operator<<(c g) {
#define R23(r) sim, size_t N>typename enable_if<N r std::tuple_size<c>::value,muu&>::type operator<<(zub<c,N>
sim> struct rge {c b, e;};
sim> rge<c> range(c i, c j) {return rge<c>{i, j};}
sim> auto dud(c*r)->decltype(cerr << *r);
sim> char dud(...);
sim, size_t N> struct zub {c x;};
struct muu {
#ifdef LOCAL
#define qel(t) sim, class d, class...e mor t<c,d,e...> r){ris << *(d*)&r;}
qel(queue) qel(priority_queue) qel(stack)
stringstream a;
~muu() {cerr << a.str() << endl;}
R22(<) a << boolalpha << g; ris;}
R22(==) ris << range(begin(g), end(g));}
sim mor rge<c> u) {
a << "[";
for (c i = u.b; i != u.e; ++i)
*this << ", " + 2 * (i == u.b) << *i;
ris << "]";
}
sim, class m mor pair <m,c>r){ris << "(" << r.first << ", " << r.second << ")";}
sim, class...m mor tuple<c,m...>r){ris << zub<tuple<c,m...>,0>{r};}
R23(!=) g) {ris << (N ? ", " : "(") << get<N>(g.x) << zub<c, N + 1>{g.x};}
R23(==) ) {ris << ")";}
#else
sim mor const c&){ris;}
#endif
};
#define imie(r...) "[" #r ": " << (r) << "] "
#define arr(a, i) "[" #a imie(i) ": " << a[i] << "] "
#define range(a, b) "[[" #a ", " #b "): " << range(a, b) << "] "
#define debug muu() << __FUNCTION__ << "#" << __LINE__ << ": "
#define arr2(a, i, j) "[" #a imie(i) imie(j) ": " << a[i][j] << "] "
#define imask(r...) "[" #r ": " << bitset<8 * sizeof(r)>(r) << "] "
using pii = pair <int, int>; using ll = long long; using ull = unsigned long long;
using ld = long double; using Pii = pii; using vpii = vector<pii>; using unt = unsigned int;
using vi = vector <int>; using pll = pair <ll, ll>; using vpll = vector <pll>;
sim> void mini(c &a, c b) {if (a > b) a = b;} sim> void maxi(c &a, c b) {if (a < b) a = b;}
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
sim, class cmp = less<c> > using ordered_set = tree<c, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>;
int n, m, k;
const int maxn = 2100;
char tab[maxn][maxn];
int dist[maxn][maxn];
void dijikstra()
{
dist[1][1] = 1;
//~ priority_queue<array<int, 3>> pq;
//~ pq.push({-1,1,1});
vector<vector<Pii>> kolejka(2);
kolejka[1].push_back({1,1});
int ind = 1;
auto jebaj = [&](int x, int y, int p)
{
if(tab[x][y] == '.' && (dist[x][y] == 0 || dist[x][y] > p))
{
dist[x][y] = p;
if((int)kolejka.size() <= p)
kolejka.resize(p+1);
kolejka[p].push_back({x,y});
//~ pq.push({-p, x, y});
}
};
while(true)
{
if(kolejka[ind].empty())
{
++ind;
if((int)kolejka.size() == ind)
break;
}
auto tp = kolejka[ind].back();
kolejka[ind].pop_back();
int x = tp.first, y = tp.second, pr = ind;
//~ debug << imie(x) << imie(y) << imie(pr);
if(dist[x][y] != pr) continue;
//~ debug << imie(pr);
jebaj(x, y+1, pr);
jebaj(x+1,y, pr);
jebaj(x-1, y, pr+1);
jebaj(x,y-1, pr+1);
}
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; ++i)
scanf("%s", &tab[i][1]);
dijikstra();
int odl = dist[n][m] - 1;
ll minres = 1e18;
int ile = 0;
//~ debug << imie(odl);
for(int i = 0; i < k; ++i)
{
int a, b;
scanf("%d%d", &a, &b);
ll res = 1ll * (n - 1 + m - 1 + odl) * a + 1ll * odl * b;
if(res < minres)
{
minres = res;
ile = 0;
}
if(res == minres)
++ile;
}
//~ for(int i = 1; i <= n; ++i)
//~ debug << range(tab[i] + 1, tab[i] + m);
//~ for(int i = 1; i <= n; ++i)
//~ debug << range(dist[i] + 1, dist[i] + m);
printf("%lld %d\n", minres, ile);
}
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 | #ifndef LOCAL #pragma GCC optimize("O3") #endif #include <bits/stdc++.h> using namespace std; #define sim template <class c #define mor > muu & operator<<( #define ris return *this #define R22(r) sim>typename enable_if<1 r sizeof(dud<c>(0)),muu&>::type operator<<(c g) { #define R23(r) sim, size_t N>typename enable_if<N r std::tuple_size<c>::value,muu&>::type operator<<(zub<c,N> sim> struct rge {c b, e;}; sim> rge<c> range(c i, c j) {return rge<c>{i, j};} sim> auto dud(c*r)->decltype(cerr << *r); sim> char dud(...); sim, size_t N> struct zub {c x;}; struct muu { #ifdef LOCAL #define qel(t) sim, class d, class...e mor t<c,d,e...> r){ris << *(d*)&r;} qel(queue) qel(priority_queue) qel(stack) stringstream a; ~muu() {cerr << a.str() << endl;} R22(<) a << boolalpha << g; ris;} R22(==) ris << range(begin(g), end(g));} sim mor rge<c> u) { a << "["; for (c i = u.b; i != u.e; ++i) *this << ", " + 2 * (i == u.b) << *i; ris << "]"; } sim, class m mor pair <m,c>r){ris << "(" << r.first << ", " << r.second << ")";} sim, class...m mor tuple<c,m...>r){ris << zub<tuple<c,m...>,0>{r};} R23(!=) g) {ris << (N ? ", " : "(") << get<N>(g.x) << zub<c, N + 1>{g.x};} R23(==) ) {ris << ")";} #else sim mor const c&){ris;} #endif }; #define imie(r...) "[" #r ": " << (r) << "] " #define arr(a, i) "[" #a imie(i) ": " << a[i] << "] " #define range(a, b) "[[" #a ", " #b "): " << range(a, b) << "] " #define debug muu() << __FUNCTION__ << "#" << __LINE__ << ": " #define arr2(a, i, j) "[" #a imie(i) imie(j) ": " << a[i][j] << "] " #define imask(r...) "[" #r ": " << bitset<8 * sizeof(r)>(r) << "] " using pii = pair <int, int>; using ll = long long; using ull = unsigned long long; using ld = long double; using Pii = pii; using vpii = vector<pii>; using unt = unsigned int; using vi = vector <int>; using pll = pair <ll, ll>; using vpll = vector <pll>; sim> void mini(c &a, c b) {if (a > b) a = b;} sim> void maxi(c &a, c b) {if (a < b) a = b;} #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; sim, class cmp = less<c> > using ordered_set = tree<c, null_type, cmp, rb_tree_tag, tree_order_statistics_node_update>; int n, m, k; const int maxn = 2100; char tab[maxn][maxn]; int dist[maxn][maxn]; void dijikstra() { dist[1][1] = 1; //~ priority_queue<array<int, 3>> pq; //~ pq.push({-1,1,1}); vector<vector<Pii>> kolejka(2); kolejka[1].push_back({1,1}); int ind = 1; auto jebaj = [&](int x, int y, int p) { if(tab[x][y] == '.' && (dist[x][y] == 0 || dist[x][y] > p)) { dist[x][y] = p; if((int)kolejka.size() <= p) kolejka.resize(p+1); kolejka[p].push_back({x,y}); //~ pq.push({-p, x, y}); } }; while(true) { if(kolejka[ind].empty()) { ++ind; if((int)kolejka.size() == ind) break; } auto tp = kolejka[ind].back(); kolejka[ind].pop_back(); int x = tp.first, y = tp.second, pr = ind; //~ debug << imie(x) << imie(y) << imie(pr); if(dist[x][y] != pr) continue; //~ debug << imie(pr); jebaj(x, y+1, pr); jebaj(x+1,y, pr); jebaj(x-1, y, pr+1); jebaj(x,y-1, pr+1); } } int main() { scanf("%d%d%d", &n, &m, &k); for(int i = 1; i <= n; ++i) scanf("%s", &tab[i][1]); dijikstra(); int odl = dist[n][m] - 1; ll minres = 1e18; int ile = 0; //~ debug << imie(odl); for(int i = 0; i < k; ++i) { int a, b; scanf("%d%d", &a, &b); ll res = 1ll * (n - 1 + m - 1 + odl) * a + 1ll * odl * b; if(res < minres) { minres = res; ile = 0; } if(res == minres) ++ile; } //~ for(int i = 1; i <= n; ++i) //~ debug << range(tab[i] + 1, tab[i] + m); //~ for(int i = 1; i <= n; ++i) //~ debug << range(dist[i] + 1, dist[i] + m); printf("%lld %d\n", minres, ile); } |
English