Problem p00822 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
#define REP(i, j) for (int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for (int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
typedef complex<double> P;
const int N = 16;
const int L = 6;
const int MAX_A = 366;
const int MAX_B = 9;
const int MAX_C = 7 * 7 * 7 * 7;

int D;
bool v[MAX_A][4][4], dp[MAX_A][MAX_B][MAX_C];

int vtoi(int *h) {
  int res = 0;
  for (int i = 3; i >= 0; --i) {
    res *= 7;
    res += h[i];
  }
  return res;
}

void itov(int c, int *h) {
  REP(i, 4) {
    h[i] = c % 7;
    c /= 7;
  }
}

int check(int d, int y, int x, int c) {
  int h[4];
  itov(c, h);
  h[0] = (y == 0 && x == 0 ? 0 : h[0] + 1);
  h[1] = (y == 0 && x == 2 ? 0 : h[1] + 1);
  h[2] = (y == 2 && x == 0 ? 0 : h[2] + 1);
  h[3] = (y == 2 && x == 2 ? 0 : h[3] + 1);
  REP(i, 4) if (h[i] >= 7) return -1;
  REP(i, 2) REP(j, 2) if (v[d][y + i][x + j]) return -1;
  return vtoi(h);
}

int solve() {
  if (v[0][1][1] || v[0][1][2] || v[0][2][1] || v[0][2][2])
    return 0;
  memset(dp, 0, sizeof(dp));
  dp[0][4][400] = 1;
  REP(a, D - 1) {
    REP(b, MAX_B) {
      REP(c, MAX_C) {
        if (!dp[a][b][c])
          continue;
        int nc;
        if ((nc = check(a + 1, b / 3, b % 3, c)) != -1)
          dp[a + 1][b][nc] = 1;
        for (int i = -1; i <= 1; ++i) {
          for (int j = -1; j <= 1; ++j) {
            if ((i != 0 && j != 0) || (i == 0 && j == 0))
              continue;
            int y = b / 3 + i, x = b % 3 + j;
            while (y >= 0 && y <= 2 && x >= 0 && x <= 2) {
              if ((nc = check(a + 1, y, x, c)) != -1)
                dp[a + 1][y * 3 + x][nc] = 1;
              y += i;
              x += j;
            }
          }
        }
      }
    }
  }
  bool res = 0;
  REP(i, MAX_B) REP(j, MAX_C) if (dp[D - 1][i][j]) res = 1;
  return res;
}

int main() {
  while (cin >> D && D) {
    REP(i, D) REP(j, 4) REP(k, 4) cin >> v[i][j][k];
    cout << solve() << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
#define REP(i, j) for (int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for (int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
typedef complex<double> P;
const int N = 16;
const int L = 6;
const int MAX_A = 370;
const int MAX_B = 9;
const int MAX_C = 7778;

int dp[MAX_A][MAX_B][MAX_C], D;

int m[9][5] = {{0, 1, 2, 3, 6}, {1, 3, 4, 7, 0}, {2, 5, 8, 0, 1},
               {3, 0, 4, 5, 6}, {4, 1, 5, 3, 7}, {5, 2, 8, 3, 4},
               {6, 0, 3, 7, 8}, {7, 1, 4, 8, 6}, {8, 2, 5, 6, 7}};
int d[16][4] = {
    {0},          {0, 1}, {1, 2}, {2},          {0, 3},       {0, 1, 3, 4},
    {1, 2, 4, 5}, {2, 5}, {3, 6}, {3, 4, 6, 7}, {4, 5, 7, 8}, {5},
    {6},          {6, 7}, {7, 8}, {8},
};
int l[16]{1, 2, 2, 1, 2, 4, 3, 2, 2, 4, 4, 1, 1, 2, 2, 1};

int check(int a, int b, int c, int n, vector<vector<int>> &v) {
  int _h = c, tmp = 1000;
  while (_h) {
    if (tmp == 1000 && _h % 10 == 6 && n != 8)
      return -1;
    if (tmp == 100 && _h % 10 == 6 && n != 6)
      return -1;
    if (tmp == 10 && _h % 10 == 6 && n != 2)
      return -1;
    if (tmp == 1 && _h % 10 == 6 && n != 0)
      return -1;
    _h /= 10;
    tmp /= 10;
  }
  REP(i, v[a].size()) {
    if (!v[a][i])
      continue;
    bool f = true;
    REP(j, l[i]) if (d[i][j] == n) f = false;
    if (!f)
      return -1;
  }
  if (n != 0)
    c += 1000;
  if (n != 2)
    c += 100;
  if (n != 6)
    c += 10;
  if (n != 8)
    c += 1;
  if (n == 0)
    c %= 1000;
  if (n == 2)
    c = c - (c % 1000) + (c % 100);
  if (n == 6)
    c = c - (c % 100) + (c % 10);
  if (n == 8)
    c -= c % 10;
  return c;
}

int solve() {
  vector<vector<int>> v(D, vector<int>(N));
  REP(i, D) REP(j, N) cin >> v[i][j];
  memset(dp, 0, sizeof(dp));
  if (v[0][5] || v[0][6] || v[0][9] || v[0][10])
    return 0;
  dp[1][4][1111] = 1;
  FOR(a, 1, D) {
    REP(b, MAX_B) {
      REP(c, MAX_C) {
        if (!dp[a][b][c])
          continue;
        REP(i, 5) {
          int nb = m[b][i], nc;
          if ((nc = check(a, b, c, nb, v)) == -1)
            continue;
          dp[a + 1][nb][nc] = true;
        }
      }
    }
  }
  bool ans = false;
  REP(b, MAX_B) REP(c, MAX_C) if (dp[D][b][c]) ans = true;
  return (ans ? 1 : 0);
}

int main() {
  while (cin >> D && D)
    cout << solve() << endl;
  return 0;
}