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

#include <algorithm>
#include <cctype>
#include <cstdio>
#include <queue>
#include <vector>

using namespace std;
#define reps(i, f, n) for (int i = f; i < int(n); ++i)
#define rep(i, n) reps(i, 0, n)

typedef vector<int> vi;
typedef vector<vi> vvi;

const int INF = 1001001001;

struct Data {
  int y, x;
  int cost;
  bool nextr;
  Data(int y, int x, int c, bool n) : y(y), x(x), cost(c), nextr(n) {}
  bool operator<(const Data &d) const { return cost > d.cost; }
};

int w, h;
bool valid(int y, int x) { return 0 <= y && y < h && 0 <= x && x < w; }

const int dy[] = {-2, -1, -1, 0, 0, 0, 1, 1, 2};
const int drx[] = {-1, -2, -1, -3, -2, -1, -2, -1, -1};
bool visited[2][100][100];
int main() {
  while (scanf("%d%d", &w, &h), w) {
    rep(i, 2) rep(j, 100) rep(k, 100) visited[i][j][k] = false;

    char field[100][100];
    rep(i, h) rep(j, w) {
      char tmp[100];
      scanf("%s", tmp);
      field[i][j] = tmp[0];
    }

    priority_queue<Data> Q;
    rep(i, w) {
      if (field[h - 1][i] == 'S') {
        Q.push(Data(h - 1, i, 0, false));
        Q.push(Data(h - 1, i, 0, true));
      }
    }

    int ans = -1;
    while (!Q.empty()) {
      Data d = Q.top();
      Q.pop();
      if (visited[d.nextr][d.x][d.y])
        continue;
      visited[d.nextr][d.x][d.y] = true;
      if (field[d.y][d.x] == 'T') {
        ans = d.cost;
        break;
      }
      rep(i, 9) {
        int py = d.y + dy[i];
        int px = d.x + drx[i] * (d.nextr ? 1 : -1);
        if (!valid(py, px))
          continue;

        char c = field[py][px];
        if (c == 'X')
          continue;

        int pc = d.cost + (isdigit(c) ? c - '0' : 0);
        Q.push(Data(py, px, pc, !d.nextr));
      }
    }
    printf("%d\\n", ans);
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cstdio>
#include <queue>
#include <vector>

using namespace std;
#define reps(i, f, n) for (int i = f; i < int(n); ++i)
#define rep(i, n) reps(i, 0, n)

typedef vector<int> vi;
typedef vector<vi> vvi;

const int INF = 1001001001;

struct Data {
  int ry, rx, ly, lx;
  int cost;
  bool nextr;
  Data(int ry, int rx, int ly, int lx, int c, bool n)
      : ry(ry), rx(rx), ly(ly), lx(lx), cost(c), nextr(n) {}
  bool operator<(const Data &d) const { return cost > d.cost; }
};

int w, h;
bool valid(int y, int x) { return 0 <= y && y < h && 0 <= x && x < w; }

const int dy[] = {-2, -1, -1, 0, 0, 0, 1, 1, 2};
const int drx[] = {-1, -2, -1, -3, -2, -1, -2, -1, -1};
bool visited[100][100][100][100];
int main() {
  while (scanf("%d%d", &w, &h), w) {
    rep(i, 100) rep(j, 100) rep(k, 100) rep(l, 100) visited[i][j][k][l] = false;

    char field[100][100];
    rep(i, h) rep(j, w) {
      char tmp[100];
      scanf("%s", tmp);
      field[i][j] = tmp[0];
    }

    priority_queue<Data> Q;
    rep(i, w) {
      if (field[h - 1][i] == 'S') {
        Q.push(Data(h - 1, i, 99, 99, 0, false));
        Q.push(Data(99, 99, h - 1, i, 0, true));
      }
    }

    int ans = -1;
    while (!Q.empty()) {
      Data d = Q.top();
      Q.pop();
      if (visited[d.ry][d.rx][d.ly][d.lx])
        continue;
      visited[d.ry][d.rx][d.ly][d.lx] = true;
      if (field[d.ry][d.rx] == 'T' || field[d.ly][d.lx] == 'T') {
        ans = d.cost;
        break;
      }
      rep(i, 9) {
        int pry, prx, ply, plx;
        if (d.nextr) {
          if (d.ly == 99)
            continue;
          pry = d.ly + dy[i];
          prx = d.lx + drx[i];
          ply = d.ly;
          plx = d.lx;
        } else {
          if (d.ry == 99)
            continue;
          pry = d.ry;
          prx = d.rx;
          ply = d.ry + dy[i];
          plx = d.rx - drx[i];
        }
        if (!valid(pry, prx) || !valid(ply, plx))
          continue;

        char c = d.nextr ? field[pry][prx] : field[ply][plx];
        if (c == 'X')
          continue;

        int pc = d.cost + (isdigit(c) ? c - '0' : 0);
        Q.push(Data(pry, prx, ply, plx, pc, !d.nextr));
      }
    }
    printf("%d\\n", ans);
  }
  return 0;
}