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

#include <cstdio>
#include <cstring>
#include <map>
#include <queue>

#define fst first
#define snd second

using namespace std;
typedef pair<int, int> pt;
typedef pair<pt, pt> state;
typedef pair<int, state> que;

char cmap[100][100];
int w, h;

bool valid(pt p) {
  int x = p.fst, y = p.snd;
  return (0 <= x) && (x < w) && (0 <= y) && (y < h);
}

void pushone(priority_queue<que> &q, state st, char c, int d) {
  if (valid(st.fst) && valid(st.snd) && c != 'X') {
    if (c == 'T' || c == 'S')
      q.push(que(-d, st));
    else
      q.push(que(-(d + c), st));
  }
}

void push(priority_queue<que> &q, state st, int d) {
  const int dx[] = {1, 2, 3, 1, 2, 1, 1, 2, 1};
  const int dy[] = {0, 0, 0, -1, -1, -2, 1, 1, 2};

  for (int i = 0; i < 9; i++) {
    if (valid(pt(st.fst.fst + dx[i], st.fst.snd + dy[i])))
      pushone(q, state(st.fst, pt(st.fst.fst + dx[i], st.fst.snd + dy[i])),
              cmap[st.fst.fst + dx[i]][st.fst.snd + dy[i]], d);
    if (valid(pt(st.snd.fst - dx[i], st.snd.snd + dy[i])))
      pushone(q, state(pt(st.snd.fst - dx[i], st.snd.snd + dy[i]), st.snd),
              cmap[st.snd.fst - dx[i]][st.snd.snd + dy[i]], d);
  }
}

int main(void) {
  while (1) {
    scanf("%d%d", &w, &h);
    if (!w)
      break;

    priority_queue<que> q;
    map<state, int> dmap;
    memset(cmap, 0, sizeof(cmap));

    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        char s[5];
        scanf("%s", s);
        switch (s[0]) {
        case 'S':
          cmap[j][i] = 'S';
          break;
        case 'T':
          cmap[j][i] = 'T';
          break;
        case 'X':
          cmap[j][i] = 'X';
          break;
        default:
          cmap[j][i] = s[0] - '0';
          break;
        }
      }

    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
        if (cmap[j][i] == 'S')
          push(q, state(pt(j, i), pt(-100, -100)), 0),
              push(q, state(pt(-100, -100), pt(j, i)), 0);

    int res = -1;
    while (q.size()) {
      que now = q.top();
      q.pop();
      state st = now.snd;
      int d = -now.fst;

      if (dmap.find(st) != dmap.end())
        continue;
      dmap[st] = d;

      if (cmap[st.fst.fst][st.fst.snd] == 'T' ||
          cmap[st.snd.fst][st.snd.snd] == 'T') {
        res = d;
        break;
      }

      push(q, st, d);
    }
    printf("%d\\n", res);
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>

using namespace std;

typedef pair<int, int> P;
typedef pair<P, P> PP;
typedef pair<bool, PP> S;

#define fir first
#define sec second

char cmap[100][100];
int w, h;

bool chk(int x, int y) { return x >= 0 && y >= 0 && x < w && y < h; }
bool chk2(int lx, int ly, int rx, int ry) {
  return abs(lx - rx) + abs(ly - ry) <= 3;
}
int c2c(char c) { // char 2 cost
  switch (c) {
  case 'S':
    return 0;
    break;
  case 'X':
    return 100000;
    break;
  case 'T':
    return 0;
    break;
  default:
    return c - '0';
    break;
  }
}

int main(void) {
  while (true) {
    int res;
    map<S, int> cost;

    scanf("%d%d", &w, &h);
    if (!w)
      break;

    memset(cmap, 0, sizeof(cmap));

    for (int j = 0; j < h; j++)
      for (int i = 0; i < w; i++) {
        char in[2];
        scanf("%s", in);
        cmap[i][j] = in[0];
      }

    priority_queue<pair<int, S>> q;
    q.push(pair<int, S>(0, S(0, PP(P(0, h - 1), P(1, h - 1)))));

    res = 1000000;
    while (!q.empty()) {
      int d = q.top().fir;
      S stat = q.top().sec;
      q.pop();
      printf(":%d\\n", d);

      if (cost[stat])
        if (cost[stat] <= d)
          continue;
      cost[stat] = d;

      int lx = stat.sec.fir.fir;
      int ly = stat.sec.fir.sec;
      int rx = stat.sec.sec.fir;
      int ry = stat.sec.sec.sec;

      if (cmap[lx][ly] == 'T' || cmap[rx][ry] == 'T') {
        res = min(d, res);
        goto RES;
      }

      if (stat.fir) { // right foot moved last
        for (int dx = -5; dx <= 5; dx++)
          for (int dy = -5; dy <= 5; dy++) {
            if (!chk(lx + dx, ly + dy))
              continue;
            if (!chk2(lx + dx, ly + dy, rx, ry))
              continue;
            if (lx >= rx)
              continue;

            int c = c2c(cmap[lx + dx][ly + dy]);
            if (c == 100000)
              continue;
            q.push(
                pair<int, S>(d + c, S(0, PP(P(lx + dx, ly + dy), P(rx, ry)))));
          }
      } else {
        for (int dx = -5; dx <= 5; dx++)
          for (int dy = -5; dy <= 5; dy++) {
            if (!chk(rx + dx, ry + dy))
              continue;
            if (!chk2(lx, ly, rx + dx, ry + dy))
              continue;
            if (lx >= rx)
              continue;

            int c = c2c(cmap[rx + dx][ry + dy]);
            if (c == 100000)
              continue;
            q.push(
                pair<int, S>(d + c, S(1, PP(P(lx, ly), P(rx + dx, ry + dy)))));
          }
      }
    }
    printf("-1\\n");
    continue;
  RES:
    printf("%d\\n", res);
  }
  return 0;
}