Problem p00178 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <iostream>
using namespace std;

const int LIMIT = 5001;

int main() {
  int n;

  while (cin >> n && n) {
    bool map[LIMIT][5] = {0};
    int h[5] = {0};
    for (int i = 0; i < n; ++i) {
      int d, p, q;
      cin >> d >> p >> q;
      q -= 1;

      int w = (d == 1 ? p : 1);
      int hh = 0;
      for (int i = 0; i < w; ++i) {
        hh = max(hh, h[q + i]);
      }
      if (d == 1) {
        for (int i = 0; i < w; ++i) {
          map[hh][q + i] = true;
          h[q + i] = hh + 1;
        }
      } else {
        for (int i = 0; i < p; ++i) {
          map[hh + i][q] = true;
        }
        h[q] = hh + p;
      }

      for (int i = 0; i < 5; ++i) {
        hh = max(hh, h[i]);
      }
      for (int i = 0; i < hh; ++i) {
        bool full = true;
        for (int j = 0; j < 5; ++j) {
          if (!map[i][j]) {
            full = false;
            break;
          }
        }
        if (full) {
          for (int j = i; j < hh; ++j) {
            for (int k = 0; k < 5; ++k) {
              map[j][k] = map[j + 1][k];
            }
          }
          for (int j = 0; j < 5; ++j) {
            int p = hh;
            while (p >= 0 && !map[p][j]) {
              --p;
            }
            h[j] = p + 1;
          }
          --hh;
          --i;
        }
      }
    }
    int hh = 0;
    for (int i = 0; i < 5; ++i) {
      hh = max(hh, h[i]);
    }
    int ans = 0;
    for (int i = 0; i < hh; ++i) {
      for (int j = 0; j < 5; ++j) {
        if (map[i][j])
          ++ans;
      }
    }
    cout << ans << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <string.h>
using namespace std;

const int WIDTH = 5;
const int BLOCK_LENGTH_MAX = 5;

class Tetoris {
public:
  Tetoris(int num)
      : m_numBlocks(num), m_pField(NULL), m_heightMax(0), m_cellCount(0) {
    memset(m_heights, 0, sizeof(m_heights));
    m_pField = new bool[num * BLOCK_LENGTH_MAX * WIDTH]();
    m_pFullLine = new bool[num * BLOCK_LENGTH_MAX]();
  }
  ~Tetoris() {
    delete[] m_pField;
    delete[] m_pFullLine;
  }
  void dropBlock(int direction, int length, int position) {
    m_cellCount += length;
    int h = 0;
    if (direction == 1) {
      for (int i = 0; i < length; ++i) {
        if (h < m_heights[i + position])
          h = m_heights[i + position];
      }
      for (int i = 0; i < length; ++i) {
        m_pField[h * WIDTH + i + position] = true;
        m_heights[i + position] = h + 1;
      }
      if (isFilled(h)) {
        m_pFullLine[h] = true;
      }
      detectHeights(m_heightMax + 1);
    } else {
      h = m_heights[position];
      int up = 0;
      for (int i = 0; i < length; ++i) {
        while (m_pFullLine[h + i + up]) {
          ++up;
        }
        m_pField[(h + i + up) * WIDTH + position] = true;
      }
      m_heights[position] += length + up;
      for (int i = 0; i < length + up; ++i) {
        if (isFilled(h + i)) {
          m_pFullLine[h + i] = true;
        }
      }
      detectHeights(m_heightMax + length);
    }
  }
  bool isFilled(int h) {
    for (int i = 0; i < WIDTH; ++i) {
      if (!m_pField[h * WIDTH + i]) {
        return false;
      }
    }
    return true;
  }
  void detectHeights(int h) {
    m_heightMax = 0;
    for (int i = 0; i < WIDTH; ++i) {
      int p = h;
      while (p >= 0 && (!m_pField[p * WIDTH + i] || m_pFullLine[p])) {
        --p;
      }
      p += 1;
      while (p < m_numBlocks * BLOCK_LENGTH_MAX && m_pField[p * WIDTH + i]) {
        ++p;
      }
      m_heights[i] = p;
      if (m_heightMax < m_heights[i]) {
        m_heightMax = m_heights[i];
      }
    }
  }
  int getResult() {
    int countFilledLine = 0;
    for (int i = 0; i < m_heightMax; ++i) {
      if (m_pFullLine[i])
        ++countFilledLine;
    }
    return m_cellCount - countFilledLine * WIDTH;
  }
  void outputState() {
    for (int i = m_heightMax - 1; i >= 0; --i) {
      for (int j = 0; j < WIDTH; ++j) {
        cout << (m_pField[i * WIDTH + j] ? 'o' : '.');
      }
      cout << endl;
    }
    cout << "heights:" << endl;
    for (int i = 0; i < WIDTH; ++i) {
      cout << m_heights[i] << ' ';
    }
    cout << endl;
    cout << "heightMax : " << m_heightMax << endl << endl;
  }

private:
  int m_numBlocks;
  bool *m_pField;
  int m_heightMax;
  int m_heights[WIDTH];
  bool *m_pFullLine;
  int m_cellCount;
};

int main() {
  int n;

  while (cin >> n && n) {
    Tetoris t(n);
    for (int i = 0; i < n; ++i) {
      int d, l, p;
      cin >> d >> l >> p;
      t.dropBlock(d, l, p - 1);
      t.outputState();
    }
    cout << t.getResult() << endl;
  }

  return 0;
}