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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
using namespace std;

struct NODE {
  int x, y, cost, bit;
  NODE(int x, int y, int cost, int bit) : x(x), y(y), cost(cost), bit(bit) {}
};

bool done[30][30][1 << 8];

int main() {
  char c[30][30];
  int W, H;
  while (cin >> W >> H && W) {
    int sx, sy;
    map<char, int> dd;
    set<char> exist;
    for (int i = 0; i < H; i++)
      for (int j = 0; j < W; j++) {
        cin >> c[i][j];
        if (c[i][j] == '@') {
          c[i][j] = '.';
          sx = j, sy = i;
        }
        if (islower(c[i][j])) {
          char t = c[i][j] | 32;
          int w = dd.size();
          if (!dd.count(t))
            dd[t] = w;
        }

        exist.insert(c[i][j]);
      }
    queue<NODE> Q;
    Q.push(NODE(sx, sy, 0, 0));
    memset(done, 0, sizeof(done));
    while (Q.size()) {
      NODE q = Q.front();
      Q.pop();
      if (done[q.y][q.x][q.bit])
        continue;
      else
        done[q.y][q.x][q.bit] = true;
      if (c[q.y][q.x] == '<') {
        cout << q.cost << endl;
        goto end;
      }
      int dx[] = {-1, 0, 1, 0}, dy[] = {0, -1, 0, 1};
      for (int i = 0; i < 4; i++) {
        int tx = q.x + dx[i], ty = q.y + dy[i];
        char t = c[ty][tx];
        if (t == '#')
          continue;
        if (isupper(t) && !exist.count(c[ty][tx] | 32))
          continue;
        if (isupper(t)) {
          if (!(q.bit & (1 << (dd[t | 32]))))
            continue;
        }
        int bit = q.bit;
        if (islower(t)) {
          bit ^= 1 << dd[t | 32];
        }
        Q.push(NODE(tx, ty, q.cost + 1, bit));
      }
    }
    cout << -1 << endl;
  end:;
  }
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
using namespace std;

struct NODE {
  int x, y, cost, bit;
  NODE(int x, int y, int cost, int bit) : x(x), y(y), cost(cost), bit(bit) {}
};

bool done[30][30][1 << 8];

int main() {
  char c[30][30];
  int W, H;
  while (cin >> W >> H && W) {
    int sx, sy;
    map<char, int> dd;
    for (int i = 0; i < H; i++)
      for (int j = 0; j < W; j++) {
        cin >> c[i][j];
        if (c[i][j] == '@') {
          c[i][j] = '.';
          sx = j, sy = i;
        }
        if (isupper(c[i][j]) || islower(c[i][j])) {
          char t = c[i][j] | 32;
          int w = dd.size();
          if (!dd.count(t))
            dd[t] = w;
        }
      }
    assert(dd.size() <= 8);
    queue<NODE> Q;
    Q.push(NODE(sx, sy, 0, 0));
    memset(done, 0, sizeof(done));
    while (Q.size()) {
      NODE q = Q.front();
      Q.pop();
      if (done[q.y][q.x][q.bit])
        continue;
      else
        done[q.y][q.x][q.bit] = true;
      if (c[q.y][q.x] == '<') {
        cout << q.cost << endl;
        goto end;
      }
      int dx[] = {-1, 0, 1, 0}, dy[] = {0, -1, 0, 1};
      for (int i = 0; i < 4; i++) {
        int tx = q.x + dx[i], ty = q.y + dy[i];
        char t = c[ty][tx];
        if (t == '#')
          continue;
        if (isupper(t)) {
          if (!(q.bit & (1 << (dd[t | 32]))))
            continue;
        }
        int bit = q.bit;
        if (islower(t)) {
          bit ^= 1 << dd[t | 32];
        }
        Q.push(NODE(tx, ty, q.cost + 1, bit));
      }
    }
    cout << -1 << endl;
  end:;
  }
}