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

#include <iostream>
#include <queue>
#include <string>
using namespace std;
int bit_in[16][3][7][7], bit_out[16][3][7][7];
int main() {
  int N;
  cin >> N;
  vector<int> X(N), Y(N);
  for (int i = 0; i < N; ++i)
    cin >> X[i] >> Y[i];
  vector<string> BV(4);
  cin >> BV[0] >> BV[1] >> BV[2] >> BV[3];
  string B = BV[0] + BV[1] + BV[2] + BV[3];
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < 3; ++j) {
      char c = (j == 0 ? 'R' : (j == 1 ? 'G' : 'B'));
      for (int k = 0; k < 4 + X[i]; ++k) {
        for (int l = 0; l < 4 + Y[i]; ++l) {
          for (int p = 0; p < X[i]; ++p) {
            for (int q = 0; q < Y[i]; ++q) {
              int tx = k - p, ty = l - q;
              if (0 <= tx && tx < 4 && 0 <= ty && ty < 4) {
                if (B[tx * 4 + ty] == c)
                  bit_in[i][j][k][l] |= 1 << (tx * 4 + ty);
                else
                  bit_out[i][j][k][l] |= 1 << (tx * 4 + ty);
              }
            }
          }
        }
      }
    }
  }
  queue<int> que;
  que.push(0);
  vector<int> dist(1 << 16, -1);
  dist[0] = 0;
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    for (int i = 0; i < N; ++i) {
      for (int j = 0; j < 3; ++j) {
        char c = (j == 0 ? 'R' : (j == 1 ? 'G' : 'B'));
        for (int k = 0; k < 4 + X[i]; ++k) {
          for (int l = 0; l < 4 + Y[i]; ++l) {
            int bit = u;
            bit |= bit_in[i][j][k][l];
            bit &= ~bit_out[i][j][k][l];
            if (dist[bit] == -1) {
              dist[bit] = dist[u] + 1;
              que.push(bit);
            }
          }
        }
      }
    }
  }
  cout << dist[(1 << 16) - 1] << endl;
  return 0;
}


Error: MLE

Fixed submission:

#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>

#pragma warning(disable : 4996)

using namespace std;

int n, a, b;
vector<int> x, y;
string tmp;

map<unsigned, bool> D;

int main() {
  scanf("%d", &n);

  for (int i = 0; i < n; i++) {
    scanf("%d", &a);
    y.push_back(a);
    scanf("%d", &b);
    x.push_back(b);
  }

  unsigned finish = 0;

  for (int i = 0; i < 4; i++) {
    cin >> tmp;

    for (int j = 0; j < 4; j++) {
      switch (tmp[j]) {
      case 'R':
        finish += (1 << (i * 8 + j * 2)) * 1;
        break;
      case 'G':
        finish += (1 << (i * 8 + j * 2)) * 2;
        break;
      case 'B':
        finish += (1 << (i * 8 + j * 2)) * 3;
        break;
      }
    }
  }

  queue<pair<unsigned, int>> que;

  que.push(make_pair(0, 0));
  D[0] = true;

  while (true) {
    unsigned M1 = que.front().first;
    int dist = que.front().second;
    que.pop();

    if (finish == M1) {
      printf("%d\\n", dist);
      break;
    }

    int count_ = 0;

    for (int i = 0; i < 32; i += 2) {
      int bit1 = finish / (1 << i) % 4;
      int bit2 = M1 / (1 << i) % 4;

      if (bit1 == bit2)
        count_++;
    }

    for (int i = 0; i < n; i++) {
      for (int j = 0; j < 4; j++) {
        for (int k = 0; k < 4; k++) {
          for (int c = 1; c < 4; c++) {
            unsigned M2 = M1;

            for (int l = j; l < j + y[i]; l++) {
              if (l == 4)
                break;

              for (int m = k; m < k + x[i]; m++) {
                if (m == 4)
                  break;

                int bit = 1 << (l * 8 + m * 2);

                M2 -= M2 / bit % 4;
                M2 += bit * c;
              }
            }

            int count2 = 0;

            for (int l = 0; l < 32; l += 2) {
              int bit1 = finish / (1 << i) % 4;
              int bit2 = M2 / (1 << i) % 4;

              if (bit1 == bit2)
                count2++;
            }

            if (!D[M2] && count_ >= count2) {
              D[M2] = true;

              que.push(make_pair(M2, dist + 1));
            }
          }
        }
      }
    }
  }

  return 0;
}