Problem p01650 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;

#define rep(i, x, y) for (int i = (x); i < (y); ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define show(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define show(x)
#endif

typedef long long int ll;
typedef pair<int, int> pii;
template <typename T> using vec = std::vector<T>;

const int inf = 1 << 16;
const long long int infll = 1LL << 62;
const double eps = 1e-9;
const int dx[] = {1, 0}, dy[] = {0, 1};

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

void solve(int h, int w) {
  vector<string> c(h);
  rep(i, 0, h) cin >> c[i];

  auto ok = [&](int y, int x) {
    return 0 <= y and y < h and 0 <= x and x < w and c[y][x] != '#';
  };
  auto is_adjacent = [](int y1, int x1, int y2, int x2) {
    return (y1 + 1 == y2 and x1 == x2) or (y1 == y2 and x1 + 1 == x2);
  };

  static bool can_move[50][50][50][50];
  vector<pii> ps[26];
  fill_n((bool *)can_move, 50 * 50 * 50 * 50, false);
  for (int y = h - 1; y >= 0; --y)
    for (int x = w - 1; x >= 0; --x) {
      if ('A' <= c[y][x] and c[y][x] <= 'Z')
        ps[c[y][x] - 'A'].push_back(make_pair(y, x));
      can_move[y][x][y][x] = true;
      rep(i, 0, 2) {
        int ny = y + dy[i], nx = x + dx[i];
        if (!ok(ny, nx))
          continue;
        can_move[y][x][ny][nx] = true;
        rep(y_, ny, h) rep(x_, nx, w) can_move[y][x][y_][x_] |=
            can_move[ny][nx][y_][x_];
      }
    }

  static int memo[50][50][50][50];
  static bool done[50][50][50][50];
  fill_n((bool *)done, 50 * 50 * 50 * 50, false);
  function<int(int, int, int, int)> rec = [&](int y1, int x1, int y2, int x2) {
    if (done[y1][x1][y2][x2])
      return memo[y1][x1][y2][x2];
    done[y1][x1][y2][x2] = true;
    if (y1 == y2 and x1 == x2)
      return memo[y1][x1][y2][x2] = 0;
    if (!can_move[y1][x1][y2][x2])
      return memo[y1][x1][y2][x2] = -inf;
    int res = -1;
    if (ok(y1 + 1, x1))
      res = max(res, rec(y1 + 1, x1, y2, x2));
    if (ok(y1, x1 + 1))
      res = max(res, rec(y1, x1 + 1, y2, x2));
    if ('a' <= c[y1][x1] and c[y1][x1] <= 'z') {
      for (pii &p : ps[c[y1][x1] - 'a']) {
        int y = p.first, x = p.second;
        if (!can_move[y1][x1][y][x] or !can_move[y][x][y2][x2])
          continue;
        if (is_adjacent(y1, x1, y, x)) {
          res = max(res, rec(y, x, y2, x2) + 1);
          continue;
        }
        rep(i, 0, 2) {
          int y1_ = y1 + dy[i], x1_ = x1 + dx[i];
          if (!ok(y1_, x1_))
            continue;
          rep(j, 0, 2) {
            int y_ = y - dy[j], x_ = x - dx[j];
            if (!ok(y_, x_) or !can_move[y1_][x1_][y_][x_])
              continue;
            res = max(res, rec(y1_, x1_, y_, x_) + rec(y, x, y2, x2) + 1);
          }
        }
      }
    }
    return memo[y1][x1][y2][x2] = res;
  };
  int ans = rec(0, 0, h - 1, w - 1);
  cout << (ans < 0 ? -1 : ans) << endl;
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(10);
  for (;;) {
    int h, w;
    cin >> h >> w;
    if (h == 0 and w == 0)
      break;
    solve(h, w);
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define rep(i, x, y) for (int i = (x); i < (y); ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define show(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define show(x)
#endif

typedef long long int ll;
typedef pair<int, int> pii;
template <typename T> using vec = std::vector<T>;

const int inf = 1 << 16;
const long long int infll = 1LL << 62;
const double eps = 1e-9;
const int dx[] = {1, 0}, dy[] = {0, 1};

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

void solve(int h, int w) {
  vector<string> c(h);
  rep(i, 0, h) cin >> c[i];

  auto ok = [&](int y, int x) {
    return 0 <= y and y < h and 0 <= x and x < w and c[y][x] != '#';
  };
  auto is_adjacent = [](int y1, int x1, int y2, int x2) {
    return (y1 + 1 == y2 and x1 == x2) or (y1 == y2 and x1 + 1 == x2);
  };

  static bool can_move[50][50][50][50];
  vector<pii> ps[26];
  fill_n((bool *)can_move, 50 * 50 * 50 * 50, false);
  rep(y, 0, h) rep(x, 0, w) {
    if ('A' <= c[y][x] and c[y][x] <= 'Z')
      ps[c[y][x] - 'A'].push_back(make_pair(y, x));
    queue<pii> que;
    que.push(make_pair(y, x));
    while (!que.empty()) {
      pii p = que.front();
      que.pop();
      int y_ = p.first, x_ = p.second;
      can_move[y][x][y_][x_] = true;
      rep(i, 0, 2) {
        int ny = y_ + dy[i], nx = x_ + dx[i];
        if (!ok(ny, nx))
          continue;
        que.push(make_pair(ny, nx));
      }
    }
  }

  static int memo[50][50][50][50];
  static bool done[50][50][50][50];
  fill_n((bool *)done, 50 * 50 * 50 * 50, false);
  function<int(int, int, int, int)> rec = [&](int y1, int x1, int y2, int x2) {
    if (done[y1][x1][y2][x2])
      return memo[y1][x1][y2][x2];
    done[y1][x1][y2][x2] = true;
    if (y1 == y2 and x1 == x2)
      return memo[y1][x1][y2][x2] = 0;
    if (!can_move[y1][x1][y2][x2])
      return memo[y1][x1][y2][x2] = -inf;
    int res = -1;
    if (ok(y1 + 1, x1))
      res = max(res, rec(y1 + 1, x1, y2, x2));
    if (ok(y1, x1 + 1))
      res = max(res, rec(y1, x1 + 1, y2, x2));
    if ('a' <= c[y1][x1] and c[y1][x1] <= 'z') {
      for (pii &p : ps[c[y1][x1] - 'a']) {
        int y = p.first, x = p.second;
        if (!can_move[y1][x1][y][x] or !can_move[y][x][y2][x2])
          continue;
        if (is_adjacent(y1, x1, y, x)) {
          res = max(res, rec(y, x, y2, x2) + 1);
          continue;
        }
        rep(i, 0, 2) {
          int y1_ = y1 + dy[i], x1_ = x1 + dx[i];
          if (!ok(y1_, x1_))
            continue;
          rep(j, 0, 2) {
            int y_ = y - dy[j], x_ = x - dx[j];
            if (!ok(y_, x_) or !can_move[y1_][x1_][y_][x_])
              continue;
            res = max(res, rec(y1_, x1_, y_, x_) + rec(y, x, y2, x2) + 1);
          }
        }
      }
    }
    return memo[y1][x1][y2][x2] = res;
  };
  int ans = rec(0, 0, h - 1, w - 1);
  cout << (ans < 0 ? -1 : ans) << endl;
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(10);
  for (;;) {
    int h, w;
    cin >> h >> w;
    if (h == 0 and w == 0)
      break;
    solve(h, w);
  }
  return 0;
}