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
#include <cstdio>
#include <cstring>
#include <vector>

using i64 = long long;

const int N = 2000 + 10;

char grid[N][N];
int dis[N][N];

const int dx[4] = {1, 0, 0, -1};
const int dy[4] = {0, 1, -1, 0};

int main() {
  int n, m, k;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < n; ++i) scanf("%s", grid[i]);
  memset(dis, -1, sizeof(dis));
  std::vector<int> queue = {0};
  dis[0][0] = 0;
  while (!queue.empty()) {
    for (size_t i = 0; i < queue.size(); ++i) {
      int x = queue[i] / m, y = queue[i] % m;
      for (int k = 0; k < 2; ++k) {
        int xx = x + dx[k], yy = y + dy[k];
        if (xx < n && yy < m && grid[xx][yy] == '.' && dis[xx][yy] == -1) {
          dis[xx][yy] = dis[x][y];
          queue.push_back(xx * m + yy);
        }
      }
    }
    std::vector<int> buffer;
    for (size_t i = 0; i < queue.size(); ++i) {
      int x = queue[i] / m, y = queue[i] % m;
      for (int k = 2; k < 4; ++k) {
        int xx = x + dx[k], yy = y + dy[k];
        if (xx >= 0 && yy >= 0 && grid[xx][yy] == '.' && dis[xx][yy] == -1) {
          dis[xx][yy] = dis[x][y] + 1;
          queue.push_back(xx * m + yy);
          buffer.push_back(xx * m + yy);
        }
      }
    }
    queue.swap(buffer);
  }
  i64 mx = -1, cnt = 0;
  for (int i = 0; i < k; ++i) {
    i64 a, b;
    scanf("%lld%lld", &a, &b);
    i64 now = (a + b) * dis[n - 1][m - 1] + (n + m - 2) * a;
    if (mx == -1 || now < mx) mx = now, cnt = 0;
    if (now == mx) ++cnt;
  }
  printf("%lld %lld\n", mx, cnt);
  return 0;
}