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

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 28)

using namespace std;
typedef pair<int, int> ii;
int field[5010][5];
int top[5];
int n, d, p, q;
vector<ii> input;

void print() {
  int st = 0;
  rep(i, 5) st = max(st, top[i]);
  for (int y = st; y >= 0; y--) {
    rep(x, 5) { cout << field[y][x] << " "; }
    cout << endl;
  }
}

bool checkX(int y) {
  rep(x, 5) if (!field[y][x]) return false;
  return true;
}

void updateD(int x, int y) {
  ii info = input[field[y][x]];
  if (info.first == 1) { // yoko
    // while(true)
    //{
    bool check = true;
    rep(i, 5) {
      if (field[y][x] != field[y][i])
        continue;
      if (y - 1 >= 0 && field[y - 1][i] != 0) {
        check = false;
        break;
      }
    }
    if (!check)
      return;
    int v = field[y][x];
    rep(i, 5) {
      if (v != field[y][i])
        continue;
      assert(field[y - 1][i] == 0);
      field[y - 1][i] = field[y][i];
      field[y][i] = 0;
    }
    y = y - 1;
    if (y <= 0)
      return;
    //}
  } else {
    int v = field[y][x];

    int bot = 0;
    int py = y;
    while (py - 1 >= 0 && field[py - 1][x] == 0)
      py--;
    bot = y - py;

    if (bot == 0)
      return;
    bot = 1; // fewafaw
    while (v == field[y][x]) {
      assert(y - bot >= 0);
      assert(field[y - bot][x] == 0);
      field[y - bot][x] = field[y][x];
      field[y][x] = 0;
      y++;
    }
  }
}

int main() {
  while (cin >> n, n) {
    input.clear();
    input.resize(1010, ii(-1, -1));
    rep(i, 5010) rep(j, 5) field[i][j] = 0;
    rep(i, 5) top[i] = 0;
    REP(i, 1, n + 1) {
      cin >> d >> p >> q;
      if (d == 1 && p == 5)
        continue;
      q--;
      input[i] = ii(d, p);
      int cyb, cyt;
      if (d == 2) {
        cyb = top[q], cyt = top[q] + p;
        REP(j, top[q], top[q] + p) field[j][q] = i;
        top[q] += p;
      } else {
        int mexico = -inf;
        REP(j, q, q + p) mexico = max(mexico, top[j]);
        REP(j, q, q + p) field[mexico][j] = i;
        cyb = cyt = mexico;
        REP(j, q, q + p) top[j] = mexico + 1;
      }

      bool update = true;
      while (update) {
        update = false;
        vector<int> erasedY;
        REP(y, cyb, cyt + 1) {
          if (checkX(y)) {
            update = true;
            erasedY.push_back(y);
            rep(x, 5) field[y][x] = 0;
          }
        }

        // print();
        // down
        if (!erasedY.empty()) {

          int yt = 0;
          rep(j, 5) yt = max(yt, top[j]);
          rep(j, erasedY.size()) {
            REP(y, erasedY[j], yt) {
              int pre = -1;
              rep(x, 5) {
                if (field[y][x] == pre)
                  continue;
                if (field[y][x] == 0 || y - 1 < 0)
                  continue;

                pre = field[y][x];
                updateD(x, y);
              }
            }
          }
        }
        // update top

        rep(j, 5) {
          int y = top[j];
          while (y >= 0 && field[y][j] == 0)
            y--;
          top[j] = y + 1;
        }
        /*
        cout << "top = ";
        rep(j,5)cout << top[j] << " ";
        cout << endl;
        print();

        cout << "----------------" << endl;
        */
      }
    }
    int yt = 0;
    rep(i, 5) yt = max(yt, top[i]);
    int ans = 0;
    rep(y, yt) rep(x, 5) if (field[y][x] != 0) ans++;
    cout << ans << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 28)

using namespace std;
typedef pair<int, int> ii;
int field[5010][5];
int top[5];
int n, d, p, q;
vector<ii> input;

void print() {
  int st = 0;
  rep(i, 5) st = max(st, top[i]);
  for (int y = st; y >= 0; y--) {
    rep(x, 5) { cout << field[y][x] << " "; }
    cout << endl;
  }
}

bool checkX(int y) {
  rep(x, 5) if (!field[y][x]) return false;
  return true;
}

void updateD(int x, int y) {
  ii info = input[field[y][x]];
  if (info.first == 1) { // yoko
    while (true) {
      bool check = true;
      rep(i, 5) {
        if (field[y][x] != field[y][i])
          continue;
        if (y - 1 >= 0 && field[y - 1][i] != 0) {
          check = false;
          break;
        }
      }
      if (!check)
        return;
      int v = field[y][x];
      rep(i, 5) {
        if (v != field[y][i])
          continue;
        assert(field[y - 1][i] == 0);
        field[y - 1][i] = field[y][i];
        field[y][i] = 0;
      }
      y = y - 1;
      if (y <= 0)
        return;
    }
  } else {
    int v = field[y][x];

    int bot = 0;
    int py = y;
    while (py - 1 >= 0 && field[py - 1][x] == 0)
      py--;
    bot = y - py;

    if (bot == 0)
      return;

    while (v == field[y][x]) {
      assert(y - bot >= 0);
      assert(field[y - bot][x] == 0);
      field[y - bot][x] = field[y][x];
      field[y][x] = 0;
      y++;
    }
  }
}

int main() {
  while (cin >> n, n) {
    input.clear();
    input.resize(1010, ii(-1, -1));
    rep(i, 5010) rep(j, 5) field[i][j] = 0;
    rep(i, 5) top[i] = 0;
    int cyb, cyt;
    REP(i, 1, n + 1) {
      cin >> d >> p >> q;

      if (d == 1 && p == 5)
        continue;
      q--;
      input[i] = ii(d, p);

      if (d == 2) {
        cyb = top[q], cyt = top[q] + p;
        REP(j, top[q], top[q] + p) field[j][q] = i;
        top[q] += p;
      } else {
        int mexico = -inf;
        REP(j, q, q + p) mexico = max(mexico, top[j]);
        REP(j, q, q + p) field[mexico][j] = i;
        cyb = cyt = mexico;
        REP(j, q, q + p) top[j] = mexico + 1;
      }

      // update top

      rep(j, 5) {
        int y = top[j];
        while (y >= 0 && field[y][j] == 0)
          y--;
        top[j] = y + 1;
      }
      /*
cout << "top = ";
      rep(j,5)cout << top[j] << " ";
      cout << endl;
      print();

      cout << "----------------" << endl;
      */
    }
    cyb = 0;
    rep(i, 5) cyt = max(cyt, top[i]);

    bool update = true;
    int cnt = 0;
    while (update) {
      assert(cnt < 2);
      cnt++;
      update = false;
      // check
      vector<int> erasedY;
      REP(y, cyb, cyt + 1) {
        if (checkX(y)) {
          erasedY.push_back(y);
          rep(x, 5) field[y][x] = 0;
        }
      }

      // print();
      // down
      if (!erasedY.empty()) {
        update = true;

        int yt = 0;
        rep(j, 5) yt = max(yt, top[j]);
        rep(j, erasedY.size()) {
          REP(y, erasedY[j], yt) {
            int pre = -1;
            rep(x, 5) {
              if (field[y][x] == pre)
                continue;
              if (field[y][x] == 0 || y - 1 < 0)
                continue;

              pre = field[y][x];
              updateD(x, y);
            }
          }
        }
      }

      // print();
    }

    int yt = 0;
    rep(i, 5) yt = max(yt, top[i]);
    int ans = 0;
    rep(y, yt) rep(x, 5) if (field[y][x] != 0) ans++;
    cout << ans << endl;
  }
  return 0;
}