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

#include <cstring>
#include <iostream>
#include <queue>
using namespace std;

int board[10][10];
int memo[7][7][7][10][10];
int h, w;

struct State {
  int x, y, top, south, east, cost;
  State(int x, int y, int top, int south, int east, int cost)
      : x(x), y(y), top(top), south(south), east(east), cost(cost) {
    ;
  }
};

const bool operator<(const State &s, const State &t) { return s.cost > t.cost; }

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

State roll(State s, int k) {
  int nx = s.x + dx[k], ny = s.y + dy[k];
  if (nx < 0 || nx > w - 1 || ny < 0 || ny > h - 1)
    return State(-1, 0, 0, 0, 0, 0);

  int ntop, nsouth, neast;
  if (k == 0) {
    nsouth = s.south;
    neast = s.top;
    ntop = 7 - s.east;
  } else if (k == 1) {
    neast = s.east;
    nsouth = s.top;
    ntop = 7 - s.south;
  } else if (k == 2) {
    nsouth = s.south;
    neast = 7 - s.top;
    ntop = s.east;
  } else if (k == 3) {
    neast = s.east;
    nsouth = 7 - s.top;
    ntop = s.south;
  }
  return State(nx, ny, ntop, nsouth, neast, 0);
}

inline int dist(State s) { return memo[s.top][s.south][s.east][s.y][s.x]; }

int main() {
  while (cin >> h >> w, h | w) {
    for (int i = 0; i < h; ++i)
      for (int j = 0; j < w; ++j)
        cin >> board[i][j];

    int sx, sy, gx, gy;
    cin >> sy >> sx >> gy >> gx;

    priority_queue<State> q;
    memset(memo, -1, sizeof(memo));
    memo[1][2][3][sy][sx] = 0;
    q.push(State(sx, sy, 1, 2, 3, 0));
    while (!q.empty()) {
      State s = q.top();
      q.pop();
      for (int k = 0; k < 4; ++k) {
        State ns = roll(s, k);
        if (ns.x == -1)
          continue;
        int nc = dist(s) + (7 - ns.top) * board[ns.y][ns.x];
        if (dist(ns) != -1 /* && nc > dist(ns)*/)
          continue;
        memo[ns.top][ns.south][ns.east][ns.y][ns.x] = nc;
        ns.cost = nc;
        q.push(ns);
      }
    }

    int ans = 1 << 29;
    for (int i = 1; i <= 6; ++i)
      for (int j = 1; j <= 6; ++j)
        for (int k = 1; k <= 6; ++k) {
          if (memo[i][j][k][gy][gx] == -1)
            continue;
          ans = min(ans, memo[i][j][k][gy][gx]);
        }

    cout << ans << endl;
  }
}

Error: MLE

Fixed submission:

#include <cstring>
#include <iostream>
#include <queue>
using namespace std;

int board[10][10];
int memo[7][7][7][10][10];
int h, w;

struct State {
  int x, y, top, south, east, cost;
  State(int x, int y, int top, int south, int east, int cost)
      : x(x), y(y), top(top), south(south), east(east), cost(cost) {
    ;
  }
};

const bool operator<(const State &s, const State &t) { return s.cost > t.cost; }

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

State roll(State s, int k) {
  int nx = s.x + dx[k], ny = s.y + dy[k];
  if (nx < 0 || nx > w - 1 || ny < 0 || ny > h - 1)
    return State(-1, 0, 0, 0, 0, 0);

  int ntop, nsouth, neast;
  if (k == 0) {
    nsouth = s.south;
    neast = s.top;
    ntop = 7 - s.east;
  } else if (k == 1) {
    neast = s.east;
    nsouth = s.top;
    ntop = 7 - s.south;
  } else if (k == 2) {
    nsouth = s.south;
    neast = 7 - s.top;
    ntop = s.east;
  } else if (k == 3) {
    neast = s.east;
    nsouth = 7 - s.top;
    ntop = s.south;
  }
  return State(nx, ny, ntop, nsouth, neast, 0);
}

inline int dist(State s) { return memo[s.top][s.south][s.east][s.y][s.x]; }

int main() {
  while (cin >> h >> w, h | w) {
    for (int i = 0; i < h; ++i)
      for (int j = 0; j < w; ++j)
        cin >> board[i][j];

    int sx, sy, gx, gy;
    cin >> sy >> sx >> gy >> gx;

    priority_queue<State> q;
    memset(memo, -1, sizeof(memo));
    memo[1][2][3][sy][sx] = 0;
    q.push(State(sx, sy, 1, 2, 3, 0));
    while (!q.empty()) {
      State s = q.top();
      q.pop();
      for (int k = 0; k < 4; ++k) {
        State ns = roll(s, k);
        if (ns.x == -1)
          continue;
        int nc = dist(s) + (7 - ns.top) * board[ns.y][ns.x];
        if (dist(ns) != -1 && nc > dist(ns))
          continue;
        memo[ns.top][ns.south][ns.east][ns.y][ns.x] = nc;
        ns.cost = nc;
        // cout<<ns.x<<" "<<ns.y<<" "<<ns.top<<" "<<ns.south<<" "<<ns.east<<"
        // "<<ns.cost<<endl;
        q.push(ns);
      }
    }

    int ans = 1 << 29;
    for (int i = 1; i <= 6; ++i)
      for (int j = 1; j <= 6; ++j)
        for (int k = 1; k <= 6; ++k) {
          if (memo[i][j][k][gy][gx] == -1)
            continue;
          ans = min(ans, memo[i][j][k][gy][gx]);
        }

    cout << ans << endl;
  }
}