Problem p01014 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)

using namespace std;

struct State {
  int x, y, s, w, c; // (x, y), state, sWitch, cost
  bool operator<(const State &st) const {
    if (c != st.c)
      return c > st.c;
    return make_tuple(x, y, s, w) < make_tuple(st.x, st.y, st.s, st.w);
  }
};
void print(const State &s) {
  printf("x = %d y = %d s = %d w = %x c = %d\\n", s.x, s.y, s.s, s.w, s.c);
}

int main() {
  int H, W, L;
  while (cin >> H >> W >> L) {

    string grid[25];
    priority_queue<State> que;
    static bool used[25][25][3][1 << 5] = {};
    memset(used, 0, sizeof(used));

    int dx[3][4] = {{1, 0, -L, 0}, {L, 0, -1, 0}, {1, 0, -1, 0}};
    int dy[3][4] = {{0, 1, 0, -L}, {0, 1, 0, -1}, {0, L, 0, -1}};
    int ds[3][4] = {{1, 2, 1, 2}, {0, 1, 0, 1}, {2, 0, 2, 0}};

    auto valid = [&](const State &st) {
      int x = st.x, y = st.y, s = st.s, w = st.w;
      assert(0 <= s && s < 3);
      for (int cy = y; cy < y + (s == 2 ? L : 1); cy++) {
        for (int cx = x; cx < x + (s == 1 ? L : 1); cx++) {
          if (cx < 0 || W <= cx)
            return false;
          if (cy < 0 || H <= cy)
            return false;
          if (grid[cy][cx] == '#')
            return false;
          if (s == 0 && grid[cy][cx] == '^')
            return false;
          if (islower(grid[cy][cx]) && !(w >> (grid[cy][cx] - 'a') & 1)) {
            return false;
          }
        }
      }
      return true;
    };
    auto push = [&](const State &s) {
      bool &u = used[s.y][s.x][s.s][s.w];
      if (!u) {
        u = true;
        que.push(s);
      }
    };

    REP(y, H) cin >> grid[y];
    State init;
    REP(y, H) REP(x, W) if (grid[y][x] == 'S') init.x = x, init.y = y;
    init.s = init.w = init.c = 0;
    push(init);

    int ans = -1;

    while (!que.empty()) {
      State s = que.top();
      que.pop();
      // print(s);
      if (s.s == 0 && grid[s.y][s.x] == 'G') {
        ans = s.c;
        break;
      }
      for (int r = 0; r < 4; r++) {
        State ns = s;
        ns.x += dx[s.s][r];
        ns.y += dy[s.s][r];
        ns.s = ds[s.s][r];
        if (!valid(ns))
          continue;
        if (ns.s == 0 && 'A' <= grid[ns.y][ns.x] && grid[ns.y][ns.x] <= 'E') {
          ns.w ^= (1 << (grid[ns.y][ns.x] - 'A'));
        }
        ns.c += 1;
        push(ns);
      }
    }

    cout << ans << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)

using namespace std;

struct State {
  int x, y, s, w, c; // (x, y), state, sWitch, cost
  bool operator<(const State &st) const {
    if (c != st.c)
      return c > st.c;
    return make_tuple(x, y, s, w) < make_tuple(st.x, st.y, st.s, st.w);
  }
};
void print(const State &s) {
  printf("x = %d y = %d s = %d w = %x c = %d\\n", s.x, s.y, s.s, s.w, s.c);
}

int main() {
  int H, W, L;
  cin >> H >> W >> L;

  string grid[25];
  priority_queue<State> que;
  static bool used[25][25][3][1 << 5] = {};
  memset(used, 0, sizeof(used));

  int dx[3][4] = {{1, 0, -L, 0}, {L, 0, -1, 0}, {1, 0, 1, 0}};
  int dy[3][4] = {{0, 1, 0, -L}, {0, 1, 0, -1}, {0, L, 0, -1}};
  int ds[3][4] = {{1, 2, 1, 2}, {0, 1, 0, 1}, {2, 0, 2, 0}};

  auto valid = [&](const State &st) {
    int x = st.x, y = st.y, s = st.s, w = st.w;
    assert(0 <= s && s < 3);
    for (int cy = y; cy < y + (s == 2 ? L : 1); cy++) {
      for (int cx = x; cx < x + (s == 1 ? L : 1); cx++) {
        if (cx < 0 || W <= cx)
          return false;
        if (cy < 0 || H <= cy)
          return false;
        if (grid[cy][cx] == '#')
          return false;
        if (s == 0 && grid[cy][cx] == '^')
          return false;
        if (islower(grid[cy][cx]) && !(w >> (grid[cy][cx] - 'a') & 1)) {
          return false;
        }
      }
    }
    return true;
  };
  auto push = [&](const State &s) {
    bool &u = used[s.y][s.x][s.s][s.w];
    if (!u) {
      u = true;
      que.push(s);
    }
  };

  REP(y, H) cin >> grid[y];
  State init;
  REP(y, H) REP(x, W) if (grid[y][x] == 'S') init.x = x, init.y = y;
  init.s = init.w = init.c = 0;
  push(init);

  assert(H == 5 && W == 5 && L == 2);
  string hoge[5] = {"#####", "#S.G#", "#...#", "#...#", "#####"};
  REP(i, 5) assert(grid[i] == hoge[i]);
  int ans = -1;

  while (!que.empty()) {
    State s = que.top();
    que.pop();
    // print(s);
    if (s.s == 0 && grid[s.y][s.x] == 'G') {
      ans = s.c;
      break;
    }
    for (int r = 0; r < 4; r++) {
      State ns = s;
      ns.x += dx[s.s][r];
      ns.y += dy[s.s][r];
      ns.s = ds[s.s][r];
      if (!valid(ns))
        continue;
      if (ns.s == 0 && 'A' <= grid[ns.y][ns.x] && grid[ns.y][ns.x] <= 'E') {
        ns.w ^= (1 << (grid[ns.y][ns.x] - 'A'));
      }
      ns.c += 1;
      push(ns);
    }
  }

  cout << ans << endl;
  return 0;
}