Problem p01561 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

#define all(v) begin(v), end(v)
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define min(...) min({__VA_ARGS__})
#define max(...) max({__VA_ARGS__})

template <class T1, class T2> void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <class T1, class T2> void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

using pint = pair<int, int>;
using tint = tuple<int, int, int>;
using vint = vector<int>;

const int mod = 1e9 + 7;

int W, H, S;
char M[55][55];
char MS[11][55][55];
bool flr[55][55];
int sy, sx, gy, gx;

int dist[2][55][55][1 << 10];
int dy[] = {0, 1, 0, -1};
int dx[] = {1, 0, -1, 0};

bool in(int y, int x) { return 0 <= y && y < H && 0 <= x && x < W; }

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  cin >> W >> H;
  rep(i, H) rep(j, W) {
    cin >> M[i][j];
    if (M[i][j] == '%')
      sy = i, sx = j;
    else if (M[i][j] == '&')
      gy = i, gx = j;
    else if (M[i][j] == '_' || islower(M[i][j]))
      flr[i][j] = 0;
    else if (M[i][j] == '^' || isupper(M[i][j]))
      flr[i][j] = 1;
  }
  cin >> S;
  rep(i, S) rep(j, H) rep(k, W) cin >> MS[i][j][k];

  queue<tuple<int, int, int, int>> que;

  memset(dist, -1, sizeof(dist));
  dist[0][sy][sx][0] = 0;
  que.emplace(0, sy, sx, 0);

  while (que.size()) {
    int f, y, x, bit;
    tie(f, y, x, bit) = que.front();
    que.pop();
    if (y == gy && x == gx) {
      cout << dist[f][y][x][bit] << endl;
      return 0;
    }
    if (M[y][x] == '|' && dist[!f][y][x][bit] == -1) {
      dist[!f][y][x][bit] = dist[f][y][x][bit] + 1;
      que.emplace(!f, y, x, bit);
    }
    if (isalpha(M[y][x])) {
      int g = flr[y][x];
      rep(j, S) if (((bit >> j) & 1) && MS[j][y][x] == '*') g = !g;
      if (f == g) {
        int nf = f, ny = y, nx = x, nbit = bit;
        int digit = M[ny][nx] - (islower(M[ny][nx]) ? 'a' : 'A');
        nbit ^= 1 << digit;
        if (MS[digit][ny][nx] == '*')
          nf = !nf;
        if (dist[nf][ny][nx][nbit] == -1) {
          dist[nf][ny][nx][nbit] = dist[f][y][x][bit] + 1;
          que.emplace(nf, ny, nx, nbit);
        }
      }
    }
    rep(i, 4) {
      int nf = f, ny = y + dy[i], nx = x + dx[i], nbit = bit;
      if (!in(ny, nx) || M[ny][nx] == '#')
        continue;
      int g = flr[ny][nx];
      rep(j, S) if (((nbit >> j) & 1) && MS[j][ny][nx] == '*') g = !g;
      if (nf == g || M[ny][nx] == '|') {
        dist[nf][ny][nx][nbit] = dist[f][y][x][bit] + 1;
        que.emplace(nf, ny, nx, nbit);
      }
    }
  }
  cout << -1 << endl;

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;

#define all(v) begin(v), end(v)
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define min(...) min({__VA_ARGS__})
#define max(...) max({__VA_ARGS__})

template <class T1, class T2> void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <class T1, class T2> void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

using pint = pair<int, int>;
using tint = tuple<int, int, int>;
using vint = vector<int>;

const int mod = 1e9 + 7;

int W, H, S;
char M[55][55];
char MS[11][55][55];
bool flr[55][55];
int sy, sx, gy, gx;

int dist[2][55][55][1 << 10];
int dy[] = {0, 1, 0, -1};
int dx[] = {1, 0, -1, 0};

bool in(int y, int x) { return 0 <= y && y < H && 0 <= x && x < W; }

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  cin >> W >> H;
  rep(i, H) rep(j, W) {
    cin >> M[i][j];
    if (M[i][j] == '%')
      sy = i, sx = j;
    else if (M[i][j] == '&')
      gy = i, gx = j;
    else if (M[i][j] == '_' || islower(M[i][j]))
      flr[i][j] = 0;
    else if (M[i][j] == '^' || isupper(M[i][j]))
      flr[i][j] = 1;
  }
  cin >> S;
  rep(i, S) rep(j, H) rep(k, W) cin >> MS[i][j][k];

  queue<tuple<int, int, int, int>> que;

  memset(dist, -1, sizeof(dist));
  dist[0][sy][sx][0] = 0;
  que.emplace(0, sy, sx, 0);

  while (que.size()) {
    int f, y, x, bit;
    tie(f, y, x, bit) = que.front();
    que.pop();
    if (y == gy && x == gx) {
      cout << dist[f][y][x][bit] << endl;
      return 0;
    }
    if (M[y][x] == '|' && dist[!f][y][x][bit] == -1) {
      dist[!f][y][x][bit] = dist[f][y][x][bit] + 1;
      que.emplace(!f, y, x, bit);
    }
    if (isalpha(M[y][x])) {
      int g = flr[y][x];
      rep(j, S) if (((bit >> j) & 1) && MS[j][y][x] == '*') g = !g;
      if (f == g) {
        int nf = f, ny = y, nx = x, nbit = bit;
        int digit = M[ny][nx] - (islower(M[ny][nx]) ? 'a' : 'A');
        nbit ^= 1 << digit;
        if (MS[digit][ny][nx] == '*')
          nf = !nf;
        if (dist[nf][ny][nx][nbit] == -1) {
          dist[nf][ny][nx][nbit] = dist[f][y][x][bit] + 1;
          que.emplace(nf, ny, nx, nbit);
        }
      }
    }
    rep(i, 4) {
      int nf = f, ny = y + dy[i], nx = x + dx[i], nbit = bit;
      if (!in(ny, nx) || M[ny][nx] == '#' || ~dist[nf][ny][nx][nbit])
        continue;
      int g = flr[ny][nx];
      rep(j, S) if (((nbit >> j) & 1) && MS[j][ny][nx] == '*') g = !g;
      if (nf == g || M[ny][nx] == '|') {
        dist[nf][ny][nx][nbit] = dist[f][y][x][bit] + 1;
        que.emplace(nf, ny, nx, nbit);
      }
    }
  }
  cout << -1 << endl;

  return 0;
}