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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <queue>
#include <stack>
#include <stdio.h>
#include <vector>
typedef long long int ll;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000001
using namespace std;

class Dice {
public:
  Dice() {
    number = new int[6];
    work = new int[6];
  };

  void roll(char dst) {
    for (int i = 0; i < 6; i++)
      work[i] = number[i];
    switch (dst) {
    case 'E':
      setNumber(work[3], work[1], work[0], work[5], work[4], work[2]);
      break;
    case 'S':
      setNumber(work[1], work[5], work[2], work[3], work[0], work[4]);
      break;
    case 'N':
      setNumber(work[4], work[0], work[2], work[3], work[5], work[1]);
      break;
    case 'W':
      setNumber(work[2], work[1], work[5], work[0], work[4], work[3]);
      break;
    }
  };

  int getBottom() { return number[5]; }

  int getEast() { return number[2]; }

  void setNumber(int n0, int n1, int n2, int n3, int n4, int n5) {
    number[0] = n0;
    number[1] = n1;
    number[2] = n2;
    number[3] = n3;
    number[4] = n4;
    number[5] = n5;
  }

  void init() { setNumber(1, 5, 3, 4, 2, 6); }

  void set(Dice arg) {
    for (int i = 0; i < 6; i++) {
      number[i] = arg.number[i];
    }
  }

  int *number;
  int *work;
};

int H, W, diff_row[4] = {-1, 0, 0, 1}, diff_col[4] = {0, -1, 1, 0};

struct Info {
  Info() {
    row = col = penalty = 0;
    dice.init();
  }

  void set(int arg_row, int arg_col, int arg_penalty) {
    row = arg_row;
    col = arg_col;
    penalty = arg_penalty;
  }
  int row, col, penalty;
  Dice dice;
};

bool rangeCheck(int row, int col) {
  if (row >= 0 && row <= H - 1 && col >= 0 && col <= W - 1)
    return true;
  else {
    return false;
  }
}

int main() {

  int dp[10][10][7][7];
  int map[10][10], start_row, start_col, goal_row, goal_col, minimum, next_row,
      next_col;
  queue<Info> Q;

  while (true) {
    scanf("%d %d", &H, &W);
    if (H == 0 && W == 0)
      break;

    for (int i = 0; i < H; i++) {
      for (int k = 0; k < W; k++)
        scanf("%d", &map[i][k]);
    }

    scanf("%d %d", &start_row, &start_col);
    scanf("%d %d", &goal_row, &goal_col);

    for (int i = 0; i < H; i++) {
      for (int k = 0; k < W; k++) {
        for (int p = 1; p <= 6; p++) {
          for (int q = 1; q <= 6; q++)
            dp[i][k][p][q] = BIG_NUM;
        }
      }
    }

    Info first;
    first.set(start_row, start_col, 0);
    dp[start_row][start_col][first.dice.getBottom()][first.dice.getEast()] = 0;

    while (!Q.empty())
      Q.pop();
    Q.push(first);

    minimum = BIG_NUM;

    while (!Q.empty()) {

      if (Q.front().row == goal_row && Q.front().col == goal_col) {
        minimum = min(minimum, Q.front().penalty);
        Q.pop();
      } else if (Q.front().penalty >= minimum ||
                 Q.front().penalty >
                     dp[Q.front().row][Q.front().col]
                       [Q.front().dice.getBottom()][Q.front().dice.getEast()]) {
        Q.pop();
      } else {

        for (int i = 0; i < 4; i++) {
          next_row = Q.front().row + diff_row[i];
          next_col = Q.front().col + diff_col[i];

          if (rangeCheck(next_row, next_col)) {
            Info next;
            next.set(next_row, next_col, Q.front().penalty);
            next.dice.set(Q.front().dice);
            switch (i) {
            case 0:
              next.dice.roll('N');
              break;
            case 1:
              next.dice.roll('W');
              break;
            case 2:
              next.dice.roll('E');
              break;
            case 3:
              next.dice.roll('S');
              break;
            }

            if (dp[next_row][next_col][next.dice.getBottom()]
                  [next.dice.getEast()] >
                dp[Q.front().row][Q.front().col][Q.front().dice.getBottom()]
                  [Q.front().dice.getEast()] +
                    map[next_row][next_col] * next.dice.getBottom()) {
              dp[next_row][next_col][next.dice.getBottom()]
                [next.dice.getEast()] =
                    dp[Q.front().row][Q.front().col][Q.front().dice.getBottom()]
                      [Q.front().dice.getEast()] +
                    map[next_row][next_col] * next.dice.getBottom();
              next.penalty += map[next_row][next_col] * next.dice.getBottom();
              Q.push(next);
            }
          }
        }
        Q.pop();
      }
    }

    printf("%d\\n", minimum);
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <queue>
#include <stack>
#include <stdio.h>
#include <vector>
typedef long long int ll;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000001
using namespace std;

class Dice {
public:
  Dice() {
    number = new int[6];
    work = new int[6];
  };

  void roll(char dst) {
    for (int i = 0; i < 6; i++)
      work[i] = number[i];
    switch (dst) {
    case 'E':
      setNumber(work[3], work[1], work[0], work[5], work[4], work[2]);
      break;
    case 'S':
      setNumber(work[1], work[5], work[2], work[3], work[0], work[4]);
      break;
    case 'N':
      setNumber(work[4], work[0], work[2], work[3], work[5], work[1]);
      break;
    case 'W':
      setNumber(work[2], work[1], work[5], work[0], work[4], work[3]);
      break;
    }
  };

  int getBottom() { return number[5]; }

  int getEast() { return number[2]; }

  void setNumber(int n0, int n1, int n2, int n3, int n4, int n5) {
    number[0] = n0;
    number[1] = n1;
    number[2] = n2;
    number[3] = n3;
    number[4] = n4;
    number[5] = n5;
  }

  void init() { setNumber(1, 5, 3, 4, 2, 6); }

  void set(Dice arg) {
    for (int i = 0; i < 6; i++) {
      number[i] = arg.number[i];
    }
  }

  int *number;
  int *work;
};

int H, W, diff_row[4] = {-1, 0, 0, 1}, diff_col[4] = {0, -1, 1, 0};

struct Info {
  Info() {
    row = col = penalty = 0;
    dice.init();
  }

  void set(int arg_row, int arg_col, int arg_penalty) {
    row = arg_row;
    col = arg_col;
    penalty = arg_penalty;
  }
  int row, col, penalty;
  Dice dice;
};

bool rangeCheck(int row, int col) {
  if (row >= 0 && row <= H - 1 && col >= 0 && col <= W - 1)
    return true;
  else {
    return false;
  }
}

int main() {

  int dp[10][10][7][7];
  int map[10][10], start_row, start_col, goal_row, goal_col, minimum, next_row,
      next_col;

  while (true) {
    scanf("%d %d", &H, &W);
    if (H == 0 && W == 0)
      break;

    for (int i = 0; i < H; i++) {
      for (int k = 0; k < W; k++)
        scanf("%d", &map[i][k]);
    }

    scanf("%d %d", &start_row, &start_col);
    scanf("%d %d", &goal_row, &goal_col);

    for (int i = 0; i < H; i++) {
      for (int k = 0; k < W; k++) {
        for (int p = 1; p <= 6; p++) {
          for (int q = 1; q <= 6; q++)
            dp[i][k][p][q] = BIG_NUM;
        }
      }
    }

    Info first;
    first.set(start_row, start_col, 0);
    dp[start_row][start_col][first.dice.getBottom()][first.dice.getEast()] = 0;
    queue<Info> Q;

    Q.push(first);

    minimum = BIG_NUM;

    while (!Q.empty()) {

      if (Q.front().row == goal_row && Q.front().col == goal_col) {
        minimum = min(minimum, Q.front().penalty);
        Q.pop();
      } else {

        for (int i = 0; i < 4; i++) {
          next_row = Q.front().row + diff_row[i];
          next_col = Q.front().col + diff_col[i];

          if (rangeCheck(next_row, next_col)) {
            Info next;
            next.set(next_row, next_col, Q.front().penalty);
            next.dice.set(Q.front().dice);
            switch (i) {
            case 0:
              next.dice.roll('N');
              break;
            case 1:
              next.dice.roll('W');
              break;
            case 2:
              next.dice.roll('E');
              break;
            case 3:
              next.dice.roll('S');
              break;
            }

            if (dp[next_row][next_col][next.dice.getBottom()]
                  [next.dice.getEast()] >
                dp[Q.front().row][Q.front().col][Q.front().dice.getBottom()]
                  [Q.front().dice.getEast()] +
                    map[next_row][next_col] * next.dice.getBottom()) {
              dp[next_row][next_col][next.dice.getBottom()]
                [next.dice.getEast()] =
                    dp[Q.front().row][Q.front().col][Q.front().dice.getBottom()]
                      [Q.front().dice.getEast()] +
                    map[next_row][next_col] * next.dice.getBottom();
              next.penalty += map[next_row][next_col] * next.dice.getBottom();
              Q.push(next);
            }
          }
        }
        Q.pop();
      }
    }

    printf("%d\\n", minimum);
  }

  return 0;
}