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

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

typedef pair<int, int> P;
typedef pair<P, P> P2;

int h, w;

string s[N];

bool check(int y1, int x1, int y2, int x2) {

  queue<P> q;

  bool used[N][N];

  memset(used, 0, sizeof(used));

  q.push(P(y1, x1));

  while (!q.empty()) {

    P t = q.front();
    q.pop();

    int y = t.first, x = t.second;

    if (s[y][x] == '#')
      continue;

    if (used[y][x])
      continue;

    used[y][x] = true;

    if (y + 1 < h)
      q.push(P(y + 1, x));

    if (x + 1 < w)
      q.push(P(y, x + 1));
  }

  return used[y2][x2];
}

vector<P2> rec;

void addrec() {

  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++) {

      if (!('a' <= s[i][j] && s[i][j] <= 'z'))
        continue;

      for (int k = i; k < h; k++)
        for (int l = j; l < w; l++)

          if (s[k][l] == 'A' + s[i][j] - 'a' && check(i, j, k, l))
            if (check(0, 0, i, j) && check(k, l, h - 1, w - 1))
              rec.push_back(P2(P(i, j), P(k, l)));
    }
}

int dp[1005][N][N];
bool used[1005][N][N];

void dfs(int num, int y, int x, bool dr) {

  if (used[num][y][x])
    return;

  used[num][y][x] = true;

  int y1 = rec[num].first.first, x1 = rec[num].first.second;

  int y2 = rec[num].second.first, x2 = rec[num].second.second;

  if (!check(y2, x2, y, x))
    return;

  dp[num][y][x] = 0;

  int res1 = 0, res2 = 0;

  for (int i = 0; i < rec.size(); i++) {

    int sy, sx, gy, gx;

    sy = rec[i].first.first;
    sx = rec[i].first.second;
    gy = rec[i].second.first;
    gx = rec[i].second.second;

    if (num == i)
      continue;

    if (y1 <= sy && x1 <= sx && gy <= y2 && gx <= x2) {
      if (!(y1 == sy && x1 == sx) && !(gy == y2 && gx == x2)) {
        if (check(y1, x1, sy, sx) && check(gy, gx, y2, x2)) {
          dfs(i, y2, x2, 1);
          res1 = max(res1, dp[i][y2][x2]);
        }
      }
    }

    if (dr && gy == y && gx == x)
      continue;

    if (y2 <= sy && x2 <= sx && gy <= y && gx <= x) {
      if (!(y2 == sy && x2 == sx)) {
        if (check(y2, x2, sy, sx) && check(gy, gx, y, x)) {
          dfs(i, y, x, 0);
          res2 = max(res2, dp[i][y][x]);
        }
      }
    }
  }

  dp[num][y][x] = res1 + res2 + 1;
}

int main() {

  while (1) {

    cin >> h >> w;
    if (!h && !w)
      break;

    for (int i = 0; i < h; i++)
      cin >> s[i];

    memset(dp, -1, sizeof(dp));
    memset(used, 0, sizeof(used));

    addrec();

    for (int i = 0; i < rec.size(); i++) {

      if (!check(0, 0, rec[i].first.first, rec[i].first.second))
        continue;
      if (!check(rec[i].second.first, rec[i].second.second, h - 1, w - 1))
        continue;

      dfs(i, h - 1, w - 1, 0);
    }

    int ans = -1;

    for (int i = 0; i < rec.size(); i++)
      ans = max(ans, dp[i][h - 1][w - 1]);

    if (ans == -1 && check(0, 0, h - 1, w - 1))
      ans = 0;

    cout << ans << endl;

    rec.clear();
  }

  return 0;
}

Error: WA

Fixed submission:

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

typedef pair<int, int> P;
typedef pair<P, P> P2;

int h, w;

string s[N];

bool check(int y1, int x1, int y2, int x2) {

  queue<P> q;

  bool used[N][N];

  memset(used, 0, sizeof(used));

  q.push(P(y1, x1));

  while (!q.empty()) {

    P t = q.front();
    q.pop();

    int y = t.first, x = t.second;

    if (s[y][x] == '#')
      continue;

    if (used[y][x])
      continue;

    used[y][x] = true;

    if (y + 1 < h)
      q.push(P(y + 1, x));

    if (x + 1 < w)
      q.push(P(y, x + 1));
  }

  return used[y2][x2];
}

vector<P2> rec;

void addrec() {

  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++) {

      if (!('a' <= s[i][j] && s[i][j] <= 'z'))
        continue;

      for (int k = i; k < h; k++)
        for (int l = j; l < w; l++)

          if (s[k][l] == 'A' + s[i][j] - 'a' && check(i, j, k, l))
            if (check(0, 0, i, j) && check(k, l, h - 1, w - 1))
              rec.push_back(P2(P(i, j), P(k, l)));
    }
}

int dp[505][N][N];
bool used[505][N][N];

void dfs(int num, int y, int x) {

  if (used[num][y][x])
    return;

  used[num][y][x] = true;

  int y1 = rec[num].first.first, x1 = rec[num].first.second;

  int y2 = rec[num].second.first, x2 = rec[num].second.second;

  if (!check(y2, x2, y, x))
    return;

  dp[num][y][x] = 0;

  int res1 = 0, res2 = 0;

  for (int i = 0; i < rec.size(); i++) {

    int sy, sx, gy, gx;

    sy = rec[i].first.first;
    sx = rec[i].first.second;
    gy = rec[i].second.first;
    gx = rec[i].second.second;

    if (num == i)
      continue;

    if (y1 <= sy && x1 <= sx && gy <= y2 && gx <= x2) {
      dfs(i, y2, x2);
      res1 = max(res1, dp[i][y2][x2]);
    }

    if (y2 <= sy && x2 <= sx && gy <= y && gx <= x) {
      dfs(i, y, x);
      res2 = max(res2, dp[i][y][x]);
    }
  }

  dp[num][y][x] = res1 + res2 + 1;
}

int main() {

  while (1) {

    cin >> h >> w;
    if (!h && !w)
      break;

    for (int i = 0; i < h; i++)
      cin >> s[i];

    memset(dp, -1, sizeof(dp));
    memset(used, 0, sizeof(used));

    addrec();

    for (int i = 0; i < rec.size(); i++)
      dfs(i, h - 1, w - 1);

    int ans = -1;

    for (int i = 0; i < rec.size(); i++)
      ans = max(ans, dp[i][h - 1][w - 1]);

    if (ans == -1 && check(0, 0, h - 1, w - 1))
      ans = 0;

    cout << ans << endl;

    rec.clear();
  }

  return 0;
}