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

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

int main() {
  int h, w, r, c;
  while (cin >> h >> w >> r >> c, h) {
    r--, c--;
    vector<vector<int>> horz(h + 1, vector<int>(w));
    vector<vector<int>> vert(h, vector<int>(w + 1));
    for (int i = 0; i < 2 * h + 1; i++) {
      if (i % 2 == 0) {
        // horz
        int index = i / 2;
        for (int j = 0; j < w; j++)
          cin >> horz[index][j];
      } else {
        int index = i / 2;
        for (int j = 0; j < w + 1; j++)
          cin >> vert[index][j];
      }
    }

    if (h == 1) {
      bool res = false;
      res |= !(horz[0][0] == horz[1][0] && vert[0][0] == horz[0][0]);
      for (int j = 1; j < w - 1; j++) {
        res |= (horz[0][j] != horz[1][j]);
      }
      res |=
          !(horz[0][w - 1] == horz[1][w - 1] && horz[0][w - 1] == vert[0][w]);
      if (res) {
        cout << "Yes" << endl;
        continue;
      }
    }
    if (w == 1) {
      bool res = false;
      res |= !(vert[0][0] == vert[0][1] && horz[0][0] == vert[0][0]);
      for (int j = 1; j < h - 1; j++) {
        res |= (vert[j][0] != vert[j][1]);
      }
      res |=
          !(vert[h - 1][0] == vert[h - 1][1] && horz[h][0] == vert[h - 1][0]);
      if (res) {
        cout << "Yes" << endl;
        continue;
      }
    }
    queue<pair<int, int>> que;
    vector<vector<int>> ok_area(h, vector<int>(w, 0));
    if (vert[0][0] != horz[0][0]) {
      que.push({0, 0});
      ok_area[0][0] = true;
    }
    if (vert[0][w] != horz[0][w - 1]) {
      que.push({0, w - 1});
      ok_area[0][w - 1] = true;
    }
    if (vert[h - 1][0] != horz[h][0]) {
      que.push({h - 1, 0});
      ok_area[h - 1][0] = true;
    }
    if (vert[h - 1][w] != horz[h][w - 1]) {
      que.push({h - 1, w - 1});
      ok_area[h - 1][w - 1] = true;
    }

    const int dh[] = {1, -1, 0, 0};
    const int dw[] = {0, 0, 1, -1};
    auto isrange = [h, w](int i, int j) {
      return 0 <= i && i < h && 0 <= j && j < w;
    };

    while (!que.empty()) {
      auto st = que.front();

      que.pop();
      for (int i = 0; i < 4; i++) {
        int toh = st.first + dh[i];
        int tow = st.second + dw[i];
        if (!isrange(toh, tow) || ok_area[toh][tow])
          continue;
        int cnt[2] = {0, 0};
        for (int j = 0; j < 4; j++) {
          int wall;
          if (dh[j] != 0) {
            wall = horz[toh + (dh[j] + 1) / 2][tow];
          } else {
            wall = vert[toh][tow + (dw[j] + 1) / 2];
          }
          if (!isrange(toh + dh[j], tow + dw[j]) ||
              ok_area[toh + dh[j]][tow + dw[j]]) {
            cnt[wall]++;
          }
        }
        if (cnt[0] && cnt[1]) {
          ok_area[toh][tow] = true;
          que.push({toh, tow});
        }
      }
    }
    bool res = false;
    res |= ok_area[r][c];
    for (int i = 0; i < 4; i++) {
      int toh = r + dh[i];
      int tow = c + dw[i];
      if (isrange(toh, tow)) {
        if (dh[i] != 0) {
          if (!horz[r + (dh[i] + 1) / 2][c])
            res |= ok_area[toh][tow];
        } else {
          if (!vert[r][c + (dw[i] + 1) / 2])
            res |= ok_area[toh][tow];
        }
      } else {
        if (dh[i] != 0) {
          if (!horz[r + (dh[i] + 1) / 2][c])
            res |= true;
        } else {
          if (!vert[r][c + (dw[i] + 1) / 2])
            res |= true;
        }
      }
    }
    cout << (res ? "Yes" : "No") << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

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

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;

int h, w, r, c;
vector<vector<int>> horz;
vector<vector<int>> vert;
vector<vector<vector<vector<int>>>> dp;

int dh[] = {1, -1, 0, 0};
int dw[] = {0, 0, 1, -1};

bool isrange(int i, int j) { return 0 <= i && i < h && 0 <= j && j < w; }

bool dfs(short ih, short jw, bool wall, bool turn) {
  if (!isrange(ih, jw))
    return 1;
  if (dp[ih][jw][wall][turn] != -1) {
    return dp[ih][jw][wall][turn];
  }
  bool res;
  dp[ih][jw][wall][turn] = 0;
  if (turn == 0) {
    // KOMA turn
    res = 0;
    for (int dir = 0; dir < 4; dir++) {
      if (dh[dir] != 0) {
        short val = ih + (dh[dir] + 1) / 2;
        if (val < 0 && val >= horz.size())
          return true;
        short iswall = horz[val][jw];
        if (wall)
          iswall = !iswall;
        if (!iswall) {
          short toh = ih + dh[dir];
          short tow = jw + dw[dir];
          if (!isrange(toh, tow))
            return 1;
          res |= dfs(toh, tow, wall, !turn);
        }
      } else {
        short val = jw + (dw[dir] + 1) / 2;
        if (val < 0 || val >= vert[ih].size())
          return true;
        bool iswall = vert[ih][val];
        if (wall)
          iswall = !iswall;
        if (!iswall) {
          short toh = ih + dh[dir];
          short tow = jw + dw[dir];
          if (!isrange(toh, tow))
            return 1;
          res |= dfs(toh, tow, wall, !turn);
        }
      }
    }
  } else {
    // wall turn
    res = 1;
    res &= dfs(ih, jw, wall, !turn);
    res &= dfs(ih, jw, !wall, !turn);
  }
  return dp[ih][jw][wall][turn] = res;
}

int main() {
  while (cin >> h >> w >> r >> c, h) {
    r--, c--;
    horz.clear();
    vert.clear();
    dp.clear();
    horz.resize(h * 3);
    vert.resize(h * 2);
    for (int i = 0; i < 2 * h + 1; i++) {
      if (i % 2 == 0) {
        int index = i / 2;
        horz[index].resize(w * 2);
        for (int j = 0; j < w; j++)
          cin >> horz[index][j];
      } else {
        int index = i / 2;
        vert[index].resize((w + 1) * 2);
        for (int j = 0; j < w + 1; j++)
          cin >> vert[index][j];
      }
    }
    dp.resize(h * 2, vvvi(w * 2, vvi(2, vi(2, -1))));
    bool res = dfs(r, c, 0, 0);
    cout << (res ? "Yes" : "No") << endl;
  }
  return 0;
}