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

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};

struct bubble {
  int y;
  int x;
  int way;
};

void move(vector<vector<int>> &field, vector<bubble> &bs) {
  vector<bubble> nbs;
  for (auto b : bs) {
    b.y += dy[b.way];
    b.x += dx[b.way];
    if (b.x >= 0 && b.x <= 3 && b.y >= 0 && b.y <= 3)
      nbs.push_back(b);
  }
  bs = nbs;
}

void update(vector<vector<int>> &field, vector<bubble> &bs) {
  vector<bubble> nbs;
  for (auto b : bs) {
    const int x = b.x;
    const int y = b.y;
    if (field[y][x]) {
      field[y][x]++;
    } else {
      nbs.push_back(b);
    }
  }
  bs = nbs;
}

void bomb(vector<vector<int>> &field, vector<bubble> &bs) {
  for (int y = 0; y < 4; ++y) {
    for (int x = 0; x < 4; ++x) {
      if (field[y][x] > 4) {
        field[y][x] = 0;
        for (int i = 0; i < 4; ++i) {
          bs.push_back(bubble{y, x, i});
        }
      }
    }
  }
}

void put(vector<vector<int>> &field, const int x, const int y) {
  vector<bubble> bs;
  bs.push_back(bubble{x, y, 0});
  while (1) {
    assert(bs.size() < 70);
    update(field, bs);
    assert(bs.size() < 70);
    bomb(field, bs);
    assert(bs.size() < 70);
    move(field, bs);
    assert(bs.size() < 70);
    if (bs.empty())
      break;
  }
}

int main() {
  vector<vector<int>> field(4, vector<int>(4));
  for (size_t i = 0; i < 4; i++) {
    for (size_t j = 0; j < 4; j++) {
      cin >> field[i][j];
    }
  }
  {
    bool ok = true;
    for (int i = 0; i < 4; ++i) {
      for (int j = 0; j < 4; ++j) {
        if (field[i][j])
          ok = false;
      }
    }
    if (ok) {
      cout << 0 << endl;
      return 0;
    }
  }

  // map < vector<pair<int,int>>, vector<vector<int>>>mp;
  // mp[vector<pair<int,int>>(0)] = field;
  for (int atime = 1; atime <= 5; ++atime) {
    for (int n = 0; n < 1 << (atime * 4); ++n) {
      int num = n;
      vector<pair<int, int>> ps(atime);
      for (int i = 0; i < atime; ++i) {
        ps[i].second = num % 4;
        num /= 4;
        ps[i].first = num % 4;
        num /= 4;
      }
      // auto nfield(mp[{ps.begin(), ps.end()-1}]);
      auto nfield(field);
      for (int i = 0; i < atime; ++i) {
        put(nfield, ps[i].second, ps[i].first);
      }
      // put(nfield, ps[i].second, ps[i].first);
      bool ok = true;
      for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
          if (nfield[i][j])
            ok = false;
        }
      }
      if (ok) {
        cout << atime << endl;
        return 0;
      }
      // mp[ps] = nfield;
    }
  }
  cout << -1 << endl;
  return 0;
}

Error: MLE

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};

struct bubble {
  int y;
  int x;
  int way;
};

void move(vector<vector<int>> &field, vector<bubble> &bs) {
  vector<bubble> nbs;
  for (auto b : bs) {
    b.y += dy[b.way];
    b.x += dx[b.way];
    if (b.x >= 0 && b.x <= 3 && b.y >= 0 && b.y <= 3)
      nbs.push_back(b);
  }
  bs = nbs;
}

void update(vector<vector<int>> &field, vector<bubble> &bs) {
  vector<bubble> nbs;
  for (auto b : bs) {
    const int x = b.x;
    const int y = b.y;
    if (field[y][x]) {
      field[y][x]++;
    } else {
      nbs.push_back(b);
    }
  }
  bs = nbs;
}

void bomb(vector<vector<int>> &field, vector<bubble> &bs) {
  for (int y = 0; y < 4; ++y) {
    for (int x = 0; x < 4; ++x) {
      if (field[y][x] > 4) {
        field[y][x] = 0;
        for (int i = 0; i < 4; ++i) {
          bs.push_back(bubble{y, x, i});
        }
      }
    }
  }
}

void put(vector<vector<int>> &field, const int x, const int y) {
  vector<bubble> bs;
  bs.push_back(bubble{x, y, 0});
  while (1) {
    assert(bs.size() < 70);
    update(field, bs);
    assert(bs.size() < 70);
    bomb(field, bs);
    assert(bs.size() < 70);
    move(field, bs);
    assert(bs.size() < 70);
    if (bs.empty())
      break;
  }
}

int main() {
  vector<vector<int>> field(4, vector<int>(4));
  for (size_t i = 0; i < 4; i++) {
    for (size_t j = 0; j < 4; j++) {
      cin >> field[i][j];
    }
  }
  map<vector<pair<int, int>>, vector<vector<int>>> mp;
  mp[vector<pair<int, int>>(0)] = field;
  for (int atime = 1; atime <= 5; ++atime) {
    for (int n = 0; n < 1 << (atime * 4); ++n) {
      int num = n;
      vector<pair<int, int>> ps(atime);
      for (int i = 0; i < atime; ++i) {
        ps[i].second = num % 4;
        num /= 4;
        ps[i].first = num % 4;
        num /= 4;
      }
      // auto nfield(mp[{ps.begin(), ps.end()-1}]);
      auto nfield(field);
      for (int i = 0; i < atime; ++i) {
        put(nfield, ps[i].second, ps[i].first);
      }
      // put(nfield, ps[i].second, ps[i].first);
      bool ok = true;
      for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
          if (nfield[i][j])
            ok = false;
        }
      }
      if (ok) {
        cout << atime << endl;
        return 0;
      }
      mp[ps] = nfield;
    }
  }
  cout << -1 << endl;
  return 0;
}