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

#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
using namespace std;

template <typename T> ostream &operator<<(ostream &os, vector<T> &v) {
  rep(i, v.size()) { os << v[i] << (i == v.size() - 1 ? "" : " "); }
  return os;
}
template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &x : v) {
    is >> x;
  }
  return is;
}

typedef vector<vector<char>> Line;
typedef vector<Line> Block;

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

int h, n;
int ans;

Block getMovedBlock(const Block &b, int dir) {
  Block res(2, Line(2, vector<char>(2, '.')));
  rep(i, 2) {
    rep(j, 2) {
      rep(k, 2) {
        if (b[i][j][k] == '#') {
          int ny = j + dy[dir];
          int nx = k + dx[dir];
          if (ny < 0 || ny >= 2 || nx < 0 || nx >= 2)
            return Block();
          res[i][ny][nx] = '#';
        }
      }
    }
  }
  return res;
}

bool canDown(const vector<Line> &m, const Block &b, int h) {
  rep(i, 2) {
    if (h == m.size() and i == 1)
      break;
    rep(j, 2) {
      rep(k, 2) {
        if (m[h - 1 + i][j][k] == '#' and b[i][j][k] == '#') {
          return false;
        }
      }
    }
  }
  return true;
}

void output(Block d) {
  show("JI") rep(i, 2) {
    rep(j, 2) {
      rep(k, 2) { cout << d[i][j][k]; }
      cout << endl;
    }
  }
  show("JI")
}

void dfs(vector<Line> &m, const vector<Block> &d, int idx, int cnt) {
  if (idx == n) {
    ans = max(ans, cnt);
    return;
  }

  // show(idx)
  const auto &b = d[idx];
  // output(b);

  vector<Line> save = m;
  rep(dir, 9) {
    Block moved = getMovedBlock(b, dir);
    // show(dir)
    if (moved.empty())
      continue;

    // output(moved);

    int h = 1;
    for (int i = m.size(); i >= 1; i--) {
      if (not canDown(m, moved, i)) {
        h = i + 1;
        break;
      }
    }

    if (h == m.size() + 1) {
      m.emplace_back(moved[0]);
      m.emplace_back(moved[1]);
    } else if (h == m.size()) {
      rep(j, 2) {
        rep(k, 2) {
          if (moved[0][j][k] == '#')
            m[h - 1][j][k] = '#';
        }
      }
      m.emplace_back(moved[1]);
    } else {
      rep(i, 2) {
        rep(j, 2) {
          rep(k, 2) {
            if (moved[i][j][k] == '#')
              m[h - 1 + i][j][k] = '#';
          }
        }
      }
    }

    int deleteLine = 0;
    for (auto it = next(m.begin(), 1); it != m.end();) {
      Line &tmp = *it;
      if (tmp[0][0] == '#' and tmp[0][1] == '#' and tmp[1][0] == '#' and
          tmp[1][1] == '#') {
        it = m.erase(it);
        deleteLine++;
      } else {
        it++;
      }
    }

    // rep(i,m.size()){ rep(j,2){ rep(k,2){ cout << m[i][j][k]; } cout << endl;
    // } }

    dfs(m, d, idx + 1, deleteLine + cnt);
    m = save;
  }
}

int main() {
  while (cin >> h >> n, h || n) {
    vector<Line> m;
    m.emplace_back(Line(2, vector<char>(2, '#')));

    rep(i, h) {
      Line a(2, vector<char>(2));
      rep(i, 2) {
        rep(j, 2) { cin >> a[i][j]; }
      }
      m.emplace_back(a);
    }

    vector<Block> d;
    rep(i, n) {
      Block a(2, Line(2, vector<char>(2)));
      rep(i, 2) {
        rep(j, 2) {
          rep(k, 2) { cin >> a[i][j][k]; }
        }
      }
      d.emplace_back(a);
    }

    ans = 0;
    dfs(m, d, 0, 0);
    cout << ans << endl;
  }
}


Error: 0
idx = 0
i = 0
"block" = block
"ikko" = ikko
"next" = next
deleteCnt = 0
i = 1
"block" = block
"ikko" = ikko
"next" = next
deleteCnt = 0
i = 2
"block" = block
"ikko" = ikko
"next" = next
deleteCnt = 0
i = 3
"block" = block
"next" = next
deleteCnt = 1
idx = 0
i = 0
"block" = block
"ikko" = ikko
"next" = next
deleteCnt = 0
i = 1
i = 2
i = 3
idx = 0
i = 0
"block" = block
"ikko" = ikko
"next" = next
deleteCnt = 1
idx = 1
i = 0
"block" = block
"next" = next
deleteCnt = 0
i = 1
"block" = block
"next" = next
deleteCnt = 0
i = 2
"block" = block
"next" = next
deleteCnt = 0
i = 3
"block" = block
"next" = next
deleteCnt = 2
i = 1
i = 2
i = 3
idx = 0
i = 0
"block" = block
"next" = next
deleteCnt = 2
idx = 1
i = 0
"block" = block
"next" = next
deleteCnt = 2
idx = 2
i = 0
"block" = block
"next" = next
deleteCnt = 2
i = 1
i = 2
i = 3
i = 1
i = 2
i = 3
i = 1
i = 2
i = 3
idx = 0
i = 0
"block" = block
"next" = next
deleteCnt = 2
idx = 1
i = 0
"block" = block
"next" = next
deleteCnt = 2
idx = 2
i = 0
"block" = block
"next" = next
deleteCnt = 0
i = 1
"block" = block
"next" = next
deleteCnt = 2
i = 2
"block" = block
"next" = next
deleteCnt = 0
i = 3
"block" = block
"next" = next
deleteCnt = 0
i = 1
"block" = block
"next" = next
deleteCnt = 0
idx = 2
i = 0
"block" = block
"next" = next
deleteCnt = 0
i = 1
"block" = block
"next" = next
deleteCnt = 0
i = 2
"block" = block
"next" = next
deleteCnt = 0
i = 3
"block" = block
"next" = next
deleteCnt = 0
i = 2
"block" = block
"next" = next
deleteCnt = 0
idx = 2
i = 0
"block" = block
"next" = next
deleteCnt = 0
i = 1
"block" = block
"next" = next
deleteCnt = 0
i = 2
"block" = block
"next" = next
deleteCnt = 0
i = 3
"block" = block
"next" = next
deleteCnt = 0
i = 3
"block" = block
"next" = next
deleteCnt = 0
idx = 2
i = 0
"block" = block
"next" = next
deleteCnt = 0
i = 1
"block" = block
"next" = next
deleteCnt = 0
i = 2
"block" = block
"next" = next
deleteCnt = 0
i = 3
"block" = block
"next" = next
deleteCnt = 0
i = 1
i = 2
i = 3
idx = 0
i = 0
"block" = block
"ikko" = ikko
"next" = next
deleteCnt = 0
idx = 1
i = 0
"block" = block
"next" = next
deleteCnt = 0
idx = 2
i = 0
"block" = block
"next" = next
deleteCnt = 0
i = 1
i = 2
i = 3
i = 1
"block" = block
"next" = next
deleteCnt = 0
idx = 2
i = 0
"block" = block
"next" = next
deleteCnt = 0
i = 1
i = 2
i = 3
i = 2
i = 3
i = 1
i = 2
i = 3


Fixed submission:

#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
using namespace std;

template <typename T> ostream &operator<<(ostream &os, vector<T> &v) {
  rep(i, v.size()) { os << v[i] << (i == v.size() - 1 ? "" : " "); }
  return os;
}
template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &x : v) {
    is >> x;
  }
  return is;
}

template <typename X, typename T> auto vectors(X x, T a) {
  return vector<T>(x, a);
}

template <typename X, typename Y, typename Z, typename... Zs>
auto vectors(X x, Y y, Z z, Zs... zs) {
  auto cont = vectors(y, z, zs...);
  return vector<decltype(cont)>(x, cont);
}

// a, b
// c, d

int h, n;
vector<vector<vector<char>>> v;
vector<vector<vector<vector<char>>>> d;

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

vector<vector<vector<char>>> getMovedBlock(vector<vector<vector<char>>> f,
                                           int d) {
  auto res = vectors<char>(2, 2, 2, '.');
  rep(i, 2) {
    rep(j, 2) {
      rep(k, 2) {
        if (f[i][j][k] == '#') {
          int ny = j + dy[d];
          int nx = k + dx[d];
          if (ny < 0 || ny >= 2 || nx < 0 || nx >= 2) {
            return vector<vector<vector<char>>>();
          }
          res[i][ny][nx] = '#';
        }
      }
    }
  }
  return res;
}
void output(vector<vector<char>> a) {
  rep(i, 2) {
    rep(j, 2) { cout << a[i][j]; }
    cout << endl;
  }
}

bool canDown(vector<vector<char>> &a, vector<vector<char>> &b) {
  rep(i, 2) {
    rep(j, 2) {
      if (a[i][j] == '#' and b[i][j] == '#') {
        return false;
      }
      if (a[i][j] == '@' and b[i][j] == '#') {
        return false;
      }
    }
  }
  return true;
}

bool canDelete(vector<vector<char>> &a, char t = '#') {
  rep(i, 2) {
    rep(j, 2) {
      if (a[i][j] != t)
        return false;
    }
  }
  return true;
}

int dfs(vector<vector<vector<char>>> f, int idx, int cnt) {
  if (idx == n)
    return cnt;
  show(idx)
      // rep(i,f.size()){ output(f[i]); }

      if (canDelete(f.back(), '.')) {
    f.pop_back();
  }

  auto p = d[idx];

  int res = 0;
  rep(i, 4) {
    show(i) auto nxtf = f;

    auto block = getMovedBlock(p, i);
    if (block.empty())
      continue;
    show("block")
        // output(block[0]);
        // output(block[1]);

        if (canDown(f.back(), block[0])) {
      if (canDown(*prev(f.end(), 2), block[0]) and
          canDown(f.back(), block[1])) {
        range(k, f.size() - 2, f.size()) {
          rep(l, 2) {
            rep(m, 2) {
              if (block[k - f.size() + 2][l][m] == '#') {
                nxtf[k][l][m] = '#';
              }
            }
          }
        }

      } else {
        show("ikko") rep(l, 2) {
          rep(m, 2) {
            if (block[0][l][m] == '#') {
              nxtf.back()[l][m] = '#';
            }
          }
        }
        nxtf.emplace_back(block[1]);
      }
    }
    else {
      nxtf.emplace_back(block[0]);
      nxtf.emplace_back(block[1]);
    }

    int deleteCnt = 0;
    if (canDelete(*prev(nxtf.end(), 2))) {
      deleteCnt++;
      nxtf.erase(prev(nxtf.end(), 2));
    }
    if (canDelete(nxtf.back())) {
      deleteCnt++;
      nxtf.pop_back();
    }
    show("next")
        // rep(i,nxtf.size()){ output(nxtf[i]); }
        show(deleteCnt)

            res = max(res, dfs(nxtf, idx + 1, deleteCnt + cnt));
  }
  return res;
}

int main() {
  while (cin >> h >> n, h || n) {
    v.clear();
    d.clear();

    auto tmp = vectors<char>(2, 2, '@');
    v.emplace_back(tmp);
    v.emplace_back(tmp);
    rep(i, h) {
      auto a = vectors<char>(2, 2, '.');
      rep(j, 2) rep(k, 2) cin >> a[j][k];
      v.emplace_back(a);
    }

    rep(i, n) {
      auto a = vectors<char>(2, 2, 2, '.');
      rep(j, 2) rep(k, 2) rep(l, 2) cin >> a[j][k][l];
      d.emplace_back(a);
    }

    cout << dfs(v, 0, 0) << endl;
  }
}