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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
const int INF = 100000000;
const double EPS = 1e-10;
const int MOD = 1000000007;
using namespace std;
typedef pair<int, int> P;

int dh[4] = {0, 1, 0, -1};
int dw[4] = {1, 0, -1, 0};

int w, h, s;
int st, go;
char m[50][50], tmp[(1 << 10)][50][50];
char ms[10][50][50];
int dp[(1 << 10) * 50 * 50 * 2 + 50 * 50 * 2 + 50 * 50 + 50];

int main() {
  rep(i, (1 << 10) * 50 * 50 * 2 + 50 * 50 * 2 + 50 * 50 + 50) dp[i] = INF;
  cin >> w >> h;
  rep(i, h) rep(j, w) {
    cin >> m[i][j];
    if (m[i][j] == '%') {
      st = i * 50 + j;
      m[i][j] = '_';
    }
    if (m[i][j] == '&') {
      go = i * 50 + j;
      m[i][j] = '_';
    }
  }
  cin >> s;
  rep(i, s) rep(j, h) rep(k, w) cin >> ms[i][j][k];
  rep(i, (1 << s)) {
    rep(j, h) rep(k, w) tmp[i][j][k] = m[j][k];
    int I = i;
    rep(j, s) {
      if (I & 1) {
        rep(k, h) rep(l, w) {
          if (ms[j][k][l] == '*') {
            if (tmp[i][k][l] == '_')
              tmp[i][k][l] = '^';
            else if (tmp[i][k][l] == '^')
              tmp[i][k][l] = '_';
            else if ('a' <= tmp[i][k][l] && tmp[i][k][l] <= 'z') {
              tmp[i][k][l] = toupper(tmp[i][k][l]);
            } else {
              tmp[i][k][l] = tolower(tmp[i][k][l]);
            }
          }
        }
      }
      I >>= 1;
    }
  }
  queue<int> que;
  que.push(st);
  dp[st] = 0;
  while (!que.empty()) {
    int q = que.front();
    que.pop();
    int i = q / (2 * 50 * 50), j = (q % (50 * 50)) / 50, k = q % 50,
        f = (q % (2 * 50 * 50)) / (50 * 50);
    if (tmp[i][j][k] == '#')
      continue;
    if (!f) {
      rep(l, 4) {
        int J = j + dh[l], K = k + dw[l];
        if (0 > J || J >= h)
          continue;
        if (0 > K || K >= w)
          continue;
        if (tmp[i][J][K] == '|' || tmp[i][J][K] == '_' ||
            ('a' <= tmp[i][J][K] && tmp[i][J][K] <= 'z')) {
          if (dp[i * 2 * 50 * 50 + 50 * J + K] != INF)
            continue;
          dp[i * 2 * 50 * 50 + 50 * J + K] = dp[q] + 1;
          que.push(i * 2 * 50 * 50 + 50 * J + K);
        }
      }
      if (tmp[i][j][k] == '|' &&
          dp[i * 2 * 50 * 50 + 50 * 50 + 50 * j + k] == INF) {
        dp[i * 2 * 50 * 50 + 50 * 50 + 50 * j + k] = dp[q] + 1;
        que.push(i * 2 * 50 * 50 + 50 * 50 + 50 * j + k);
      }
    }
    if (f) {
      rep(l, 4) {
        int J = j + dh[l], K = k + dw[l];
        if (0 > J || J >= h)
          continue;
        if (0 > K || K >= w)
          continue;
        if (tmp[i][J][K] == '|' || tmp[i][J][K] == '^' ||
            ('A' <= tmp[i][J][K] && tmp[i][J][K] <= 'Z')) {
          if (dp[i * 2 * 50 * 50 + 50 * 50 + 50 * J + K] != INF)
            continue;
          dp[i * 2 * 50 * 50 + 50 * 50 + 50 * J + K] = dp[q] + 1;
          que.push(i * 2 * 50 * 50 + 50 * 50 + 50 * J + K);
        }
      }
      if (tmp[i][j][k] == '|' && dp[i * 2 * 50 * 50 + 50 * j + k] == INF) {
        dp[i * 2 * 50 * 50 + 50 * j + k] = dp[q] + 1;
        que.push(i * 2 * 50 * 50 + 50 * j + k);
      }
    }
    if (!f && 'a' <= tmp[i][j][k] && tmp[i][j][k] <= 'z') {
      int z = tmp[i][j][k] - 'a';
      int flo = 0;
      if (ms[z][j][k] == '*')
        flo = 1;
      if (i & (1 << z)) {
        if (dp[(i - (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k] ==
            INF) {
          dp[(i - (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k] =
              dp[q] + 1;
          que.push((i - (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k);
        }
      } else {
        if (dp[(i + (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k] ==
            INF) {
          dp[(i + (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k] =
              dp[q] + 1;
          que.push((i + (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k);
        }
      }
    }
    if (f && 'A' <= tmp[i][j][k] && tmp[i][j][k] <= 'Z') {
      int z = tmp[i][j][k] - 'A';
      int flo = 1;
      if (ms[z][j][k] == '*')
        flo = 0;
      if (i & (1 << z)) {
        if (dp[(i - (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k] ==
            INF) {
          dp[(i - (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k] =
              dp[q] + 1;
          que.push((i - (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k);
        }
      } else {
        if (dp[(i + (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k] ==
            INF) {
          dp[(i + (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k] =
              dp[q] + 1;
          que.push((i + (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k);
        }
      }
    }
  }
  int ans = INF;
  rep(i, (1 << 10) * 50 * 50 * 2 + 50 * 50 * 2 + 50 * 50 + 50) {
    if (i % (50 * 50) != go)
      continue;
    ans = min(ans, dp[i]);
  }
  if (ans == INF)
    ans = -1;
  cout << ans << endl;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
const int INF = 100000000;
const double EPS = 1e-10;
const int MOD = 1000000007;
using namespace std;
typedef pair<int, int> P;

int dh[4] = {0, 1, 0, -1};
int dw[4] = {1, 0, -1, 0};

int w, h, s;
int st, go;
char m[50][50], tmp[50][50];
char ms[10][50][50];
// int dp[(1<<10)*2*50*50+2*50*50+50*50+50];
// vector<int> e[(1<<10)*2*50*50+2*50*50+50*50+50];
unordered_map<int, int> dp;
unordered_map<int, int>::iterator it;
unordered_map<int, vector<int>> e;

int main() {
  cin >> w >> h;
  rep(i, h) rep(j, w) {
    cin >> m[i][j];
    if (m[i][j] == '%') {
      st = i * 50 + j;
      m[i][j] = '_';
    }
    if (m[i][j] == '&') {
      go = i * 50 + j;
      m[i][j] = '_';
    }
  }
  cin >> s;
  rep(i, s) rep(j, h) rep(k, w) cin >> ms[i][j][k];
  rep(i, (1 << s)) {
    rep(j, h) rep(k, w) tmp[j][k] = m[j][k];
    int I = i;
    rep(j, s) {
      if (I & 1) {
        rep(k, h) rep(l, w) {
          if (ms[j][k][l] == '*') {
            if (tmp[k][l] == '_')
              tmp[k][l] = '^';
            else if (tmp[k][l] == '^')
              tmp[k][l] = '_';
            else if ('a' <= tmp[k][l] && tmp[k][l] <= 'z') {
              tmp[k][l] = toupper(tmp[k][l]);
            } else {
              tmp[k][l] = tolower(tmp[k][l]);
            }
          }
        }
      }
      I >>= 1;
    }
    rep(j, h) rep(k, w) {
      if (tmp[j][k] == '#')
        continue;
      if (tmp[j][k] == '|' || tmp[j][k] == '_' ||
          ('a' <= tmp[j][k] && tmp[j][k] <= 'z')) {
        rep(l, 4) {
          int J = j + dh[l], K = k + dw[l];
          if (0 > J || J >= h)
            continue;
          if (0 > K || K >= w)
            continue;
          if (tmp[J][K] == '|' || tmp[J][K] == '_' ||
              ('a' <= tmp[J][K] && tmp[J][K] <= 'z')) {
            e[i * 2 * 50 * 50 + 50 * j + k].push_back(i * 2 * 50 * 50 + 50 * J +
                                                      K);
          }
        }
      }
      if (tmp[j][k] == '|' || tmp[j][k] == '^' ||
          ('A' <= tmp[j][k] && tmp[j][k] <= 'Z')) {
        rep(l, 4) {
          int J = j + dh[l], K = k + dw[l];
          if (0 > J || J >= h)
            continue;
          if (0 > K || K >= w)
            continue;
          if (tmp[J][K] == '|' || tmp[J][K] == '^' ||
              ('A' <= tmp[J][K] && tmp[J][K] <= 'Z')) {
            e[i * 2 * 50 * 50 + 50 * 50 + 50 * j + k].push_back(
                i * 2 * 50 * 50 + 50 * 50 + 50 * J + K);
          }
        }
      }
      if (tmp[j][k] == '|') {
        e[i * 2 * 50 * 50 + 50 * j + k].push_back(i * 2 * 50 * 50 + 50 * 50 +
                                                  50 * j + k);
        e[i * 2 * 50 * 50 + 50 * 50 + 50 * j + k].push_back(i * 2 * 50 * 50 +
                                                            50 * j + k);
      }
      if ('a' <= tmp[j][k] && tmp[j][k] <= 'z') {
        int z = tmp[j][k] - 'a';
        int flo = 0;
        if (ms[z][j][k] == '*')
          flo = 1;
        if (i & (1 << z)) {
          e[i * 2 * 50 * 50 + 50 * j + k].push_back(
              (i - (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k);
        } else {
          e[i * 2 * 50 * 50 + 50 * j + k].push_back(
              (i + (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k);
        }
      }
      if ('A' <= tmp[j][k] && tmp[j][k] <= 'Z') {
        int z = tmp[j][k] - 'A';
        int flo = 1;
        if (ms[z][j][k] == '*')
          flo = 0;
        if (i & (1 << z)) {
          e[i * 2 * 50 * 50 + 50 * 50 + 50 * j + k].push_back(
              (i - (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k);
        } else {
          e[i * 2 * 50 * 50 + 50 * 50 + 50 * j + k].push_back(
              (i + (1 << z)) * 2 * 50 * 50 + flo * 50 * 50 + 50 * j + k);
        }
      }
    }
  }
  queue<int> que;
  que.push(st);
  dp[st] = 0;
  while (!que.empty()) {
    int q = que.front();
    que.pop();
    rep(i, e[q].size()) {
      if (dp.count(e[q][i]))
        continue;
      dp[e[q][i]] = dp[q] + 1;
      que.push(e[q][i]);
    }
  }
  int ans = INF;
  for (it = dp.begin(); it != dp.end(); it++) {
    if ((*it).first % (50 * 50) != go)
      continue;
    ans = min(ans, (*it).second);
  }
  if (ans == INF)
    ans = -1;
  cout << ans << endl;
}