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

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

int W, H, div_row[4] = {-1, 0, 0, 1}, div_col[5] = {0, -1, 1, 0};

struct Info {
  Info() { eat_after = row = col = hp = time = 0; }

  void set(int arg_row, int arg_col, int arg_hp, int arg_time,
           int arg_eat_after) {
    row = arg_row;
    col = arg_col;
    hp = arg_hp;
    time = arg_time;
    eat_after = arg_eat_after;
  }

  int row, col, hp, time, eat_after;
  short check[8][8];
};

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

void func() {

  int map[H][W];
  int start_row, start_col, goal_row, goal_col;

  for (int i = 0; i < H; i++) {
    for (int k = 0; k < W; k++) {
      scanf("%d", &map[i][k]);
      if (map[i][k] == 2) {
        start_row = i;
        start_col = k;
        map[i][k] = 1;
      } else if (map[i][k] == 3) {
        goal_row = i;
        goal_col = k;
      }
    }
  }

  int ans = -1, limit = 2 * H * W;
  queue<Info> Q;
  Info current;

  Info first;

  for (int i = 0; i < H; i++) {
    for (int k = 0; k < W; k++)
      first.check[i][k] = 0;
  }

  first.check[start_row][start_col] = 1;
  first.set(start_row, start_col, 6, 0, 3);

  Q.push(first);

  int debug = 0;
  while (!Q.empty()) {
    current = Q.front();
    Q.pop();

    debug++;
    if (debug > 250000) {
      break;
    }

    if (current.hp == 0)
      continue;

    if (map[current.row][current.col] == 3) {
      ans = current.time;
      break;
    } else if (map[current.row][current.col] == 4) {
      current.hp = 6;
      current.eat_after = 0;
    }

    if (current.time + abs(current.row - goal_row) +
            abs(current.col - goal_col) >
        limit)
      continue;

    for (int i = 0; i < 4; i++) {
      if (rangeCheck(current.row + div_row[i], current.col + div_col[i]) ==
              true &&
          map[current.row + div_row[i]][current.col + div_col[i]] != 0 &&
          ((current.check[current.row + div_row[i]][current.col + div_col[i]] ==
            0) ||
           (current.check[current.row + div_row[i]][current.col + div_col[i]] ==
                1 &&
            current.eat_after <= 1))) {
        Info new_info;
        for (int a = 0; a < H; a++) {
          for (int b = 0; b < W; b++) {
            new_info.check[a][b] = current.check[a][b];
          }
        }
        new_info.check[current.row + div_row[i]][current.col + div_col[i]]++;
        new_info.set(current.row + div_row[i], current.col + div_col[i],
                     current.hp - 1, current.time + 1, current.eat_after + 1);
        Q.push(new_info);
      }
    }
  }
  printf("%d\\n", ans);
}

int main() {

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

    func();
  }

  return 0;
}

Error: MLE

Fixed submission:

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

int W, H, div_row[4] = {-1, 0, 0, 1}, div_col[5] = {0, -1, 1, 0};

struct Info {
  Info() { eat_after = row = col = hp = time = 0; }

  void set(int arg_row, int arg_col, int arg_hp, int arg_time,
           int arg_eat_after) {
    row = arg_row;
    col = arg_col;
    hp = arg_hp;
    time = arg_time;
    eat_after = arg_eat_after;
  }

  int row, col, hp, time, eat_after;
  short check[8][8];
};

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

void func() {

  int map[H][W];
  int start_row, start_col, goal_row, goal_col;

  for (int i = 0; i < H; i++) {
    for (int k = 0; k < W; k++) {
      scanf("%d", &map[i][k]);
      if (map[i][k] == 2) {
        start_row = i;
        start_col = k;
        map[i][k] = 1;
      } else if (map[i][k] == 3) {
        goal_row = i;
        goal_col = k;
      }
    }
  }

  int ans = -1, limit = 2 * H * W;
  queue<Info> Q;
  Info current;

  Info first;

  for (int i = 0; i < H; i++) {
    for (int k = 0; k < W; k++)
      first.check[i][k] = 0;
  }

  first.check[start_row][start_col] = 1;
  first.set(start_row, start_col, 6, 0, 3);

  Q.push(first);

  int debug = 0;
  while (!Q.empty()) {
    current = Q.front();
    Q.pop();

    debug++;
    if (debug > 300000) {
      break;
    }

    if (current.hp == 0)
      continue;

    if (map[current.row][current.col] == 3) {
      ans = current.time;
      break;
    } else if (map[current.row][current.col] == 4) {
      current.hp = 6;
      current.eat_after = 0;
    }

    if (current.time + abs(current.row - goal_row) +
            abs(current.col - goal_col) >
        limit)
      continue;

    for (int i = 0; i < 4; i++) {
      if (rangeCheck(current.row + div_row[i], current.col + div_col[i]) ==
              true &&
          map[current.row + div_row[i]][current.col + div_col[i]] != 0 &&
          ((current.check[current.row + div_row[i]][current.col + div_col[i]] ==
            0) ||
           (current.check[current.row + div_row[i]][current.col + div_col[i]] ==
                1 &&
            current.eat_after <= 1))) {
        Info new_info;
        for (int a = 0; a < H; a++) {
          for (int b = 0; b < W; b++) {
            new_info.check[a][b] = current.check[a][b];
          }
        }
        new_info.check[current.row + div_row[i]][current.col + div_col[i]]++;
        new_info.set(current.row + div_row[i], current.col + div_col[i],
                     current.hp - 1, current.time + 1, current.eat_after + 1);
        Q.push(new_info);
      }
    }
  }
  printf("%d\\n", ans);
}

int main() {

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

    func();
  }

  return 0;
}