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

#include <algorithm>
#include <cassert>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>

#define rep(i, n) for (int i = 0; i < (int)n; i++)
#define all(c) (c).begin(), (c).end()
#define mp make_pair
#define pb push_back
#define each(i, c)                                                             \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define dbg(x) cerr << __LINE__ << ": " << #x << " = " << (x) << endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;

const int dy[] = {-1, 0, 1, 0}, dx[] = {0, -1, 0, 1};
vector<vi> move(const vector<vi> &a, int y, int x, int co) {
  vector<vi> b = a;
  int f[4][4] = {};

  if (++b[y][x] == 5) {
    b[y][x] = 0;
    f[y][x] = (1 << 4) - 1;
  }
  while (1) {
    bool update = 0;
    int pf[4][4];
    rep(i, 4) rep(j, 4) pf[i][j] = f[i][j], f[i][j] = 0;
    rep(i, 4) rep(j, 4) if (pf[i][j]) {
      update = 1;
      rep(d, 4) if (pf[i][j] & 1 << d) {
        int ny = i + dy[d], nx = j + dx[d];
        if (ny < 0 || nx < 0 || ny >= 4 || nx >= 4)
          continue;
        f[ny][nx] |= 1 << d;
      }
    }
    if (!update)
      break;
    rep(i, 4) rep(j, 4) if (b[i][j]) {
      b[i][j] += __builtin_popcount(f[i][j]);
      if (b[i][j] >= 5) {
        b[i][j] = 0;
        f[i][j] = (1 << 4) - 1;
      } else
        f[i][j] = 0;
    }
  }
  rep(i, 4) rep(j, 4) if (b[i][j]) return b;
  cout << co + 1 << endl;
  exit(0);
}

int main() {
  bool ng = 0;
  vector<vi> a(4, vi(4));
  rep(i, 4) rep(j, 4) cin >> a[i][j], ng |= a[i][j];
  queue<pair<int, vector<vi>>> q;
  set<vector<vi>> s;
  s.insert(a);
  q.push(mp(0, a));

  if (!ng) {
    cout << 0 << endl;
    return 0;
  }

  while (!q.empty()) {
    a = q.front().second;
    int co = q.front().first;
    q.pop();

    int mx = 0;
    rep(i, 4) rep(j, 4) mx = max(mx, a[i][j]);
    if (co > mx)
      continue;

    rep(i, 4) rep(j, 4) {
      if (a[i][j] == 0) {
        a[i][j] = 1;
        if (!s.count(a)) {
          q.push(mp(co + 1, a));
          s.insert(a);
        }
        a[i][j] = 0;
      } else {
        vector<vi> b = move(a, i, j, co);
        if (co == 4 || s.count(b))
          continue;
        s.insert(b);
        q.push(mp(co + 1, b));
      }
    }
  }
  cout << -1 << endl;

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>

#define rep(i, n) for (int i = 0; i < (int)n; i++)
#define all(c) (c).begin(), (c).end()
#define mp make_pair
#define pb push_back
#define each(i, c)                                                             \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define dbg(x) cerr << __LINE__ << ": " << #x << " = " << (x) << endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;

const int dy[] = {-1, 0, 1, 0}, dx[] = {0, -1, 0, 1};
vector<vi> move(const vector<vi> &a, int y, int x, int co) {
  vector<vi> b = a;
  int f[4][4] = {};

  if (++b[y][x] == 5) {
    b[y][x] = 0;
    f[y][x] = (1 << 4) - 1;
  }
  while (1) {
    bool update = 0;
    int pf[4][4];
    rep(i, 4) rep(j, 4) pf[i][j] = f[i][j], f[i][j] = 0;
    rep(i, 4) rep(j, 4) if (pf[i][j]) {
      update = 1;
      rep(d, 4) if (pf[i][j] & 1 << d) {
        int ny = i + dy[d], nx = j + dx[d];
        if (ny < 0 || nx < 0 || ny >= 4 || nx >= 4)
          continue;
        f[ny][nx] |= 1 << d;
      }
    }
    if (!update)
      break;
    rep(i, 4) rep(j, 4) if (b[i][j]) {
      b[i][j] += __builtin_popcount(f[i][j]);
      if (b[i][j] >= 5) {
        b[i][j] = 0;
        f[i][j] = (1 << 4) - 1;
      } else
        f[i][j] = 0;
    }
  }
  rep(i, 4) rep(j, 4) if (b[i][j]) return b;
  cout << co + 1 << endl;
  exit(0);
}

int main() {
  bool ng = 0;
  vector<vi> a(4, vi(4));
  rep(i, 4) rep(j, 4) cin >> a[i][j], ng |= a[i][j];
  queue<pair<int, vector<vi>>> q;
  set<vector<vi>> s;
  s.insert(a);
  q.push(mp(0, a));

  if (!ng) {
    cout << 0 << endl;
    return 0;
  }

  while (!q.empty()) {
    a = q.front().second;
    int co = q.front().first;
    q.pop();

    rep(i, 4) rep(j, 4) {
      if (a[i][j] == 0) {
        a[i][j] = 1;
        q.push(mp(co + 1, a));
      } else {
        vector<vi> b = move(a, i, j, co);
        if (co == 4 || s.count(b))
          continue;
        s.insert(b);
        q.push(mp(co + 1, b));
      }
    }
  }
  cout << -1 << endl;

  return 0;
}