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

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

int H = 19, W = 15;

enum DIR {
  Left_Up,
  Up,
  Right_Up,
  Left,
  Right,
  Left_Down,
  Down,
  Right_Down,
};

DIR dir[8] = {Left_Up, Up, Right_Up, Left, Right, Left_Down, Down, Right_Down};

int diff_row[8] = {-1, -1, -1, 0, 0, 1, 1, 1},
    diff_col[8] = {-1, 0, 1, -1, 1, -1, 0, 1};

struct BlackStone {
  BlackStone() { row = col = 0; }

  BlackStone(short arg_row, short arg_col) {
    row = arg_row;
    col = arg_col;
  }
  short row, col;
};

struct Info {
  vector<BlackStone> BLACK_STONE;
  short row, col, count;
};

bool rangeCheck(short row, short col) {
  if (row <= 17) {
    if (col < 0 || col > 14) {
      return false;
    } else {
      return true;
    }
  } else { // row >= 18
    if (row == 18 && (col < 0 || col > 14)) {
      return false;
    } else {
      return true;
    }
  }
}

Info move(Info info, DIR dir) {
  Info ret;

  char map[19][15];
  for (int i = 0; i < H; i++) {
    for (int k = 0; k < W; k++)
      map[i][k] = '.';
  }

  for (int i = 0; i < info.BLACK_STONE.size(); i++) {
    map[info.BLACK_STONE[i].row][info.BLACK_STONE[i].col] = 'X';
  }
  ret.count = info.count + 1;

  int next_row, next_col, index;

  switch (dir) {
  case Left_Up:
    index = 0;
    break;
  case Up:
    index = 1;
    break;
  case Right_Up:
    index = 2;
    break;
  case Left:
    index = 3;
    break;
  case Right:
    index = 4;
    break;
  case Left_Down:
    index = 5;
    break;
  case Down:
    index = 6;
    break;
  case Right_Down:
    index = 7;
    break;
  }

  next_row = info.row + diff_row[index];
  next_col = info.col + diff_col[index];

  while (rangeCheck(next_row, next_col) == true &&
         map[next_row][next_col] == 'X') {
    next_row += diff_row[index];
    next_col += diff_col[index];
  }

  if (next_row == info.row + diff_row[index] &&
      next_col == info.col + diff_col[index]) {
    ret.row = 1;
    ret.col = -1;
  } else {

    if (rangeCheck(next_row, next_col) == true &&
        next_row <= 18) { //???????????§??????????????¢??????????????´???

      for (int i = 0; i < info.BLACK_STONE.size(); i++) {
        ret.BLACK_STONE.push_back(info.BLACK_STONE[i]);
      }

      int tmp_row, tmp_col;

      tmp_row = info.row + diff_row[index];
      tmp_col = info.col + diff_col[index];

      while (tmp_row != next_row || tmp_col != next_col) {
        for (int i = 0; i < ret.BLACK_STONE.size(); i++) {
          if (ret.BLACK_STONE[i].row == tmp_row &&
              ret.BLACK_STONE[i].col == tmp_col) {
            ret.BLACK_STONE.erase(ret.BLACK_STONE.begin() + i);
            break;
          }
        }
        tmp_row += diff_row[index];
        tmp_col += diff_col[index];
      }
    }

    ret.row = next_row;
    ret.col = next_col;
  }

  return ret;
}

int main() {

  Info first;

  char buf[15];
  int minimum = BIG_NUM, start_row, start_col, num;
  bool FLG = true;

  for (short i = 0; i < H; i++) {
    scanf("%s", buf);
    if (i == 17) {
      num = 0;
    }
    for (short k = 0; k < W; k++) {
      if (buf[k] == 'O') {
        start_row = i;
        start_col = k;
      } else if (buf[k] == 'X') {
        first.BLACK_STONE.push_back(BlackStone(i, k));
      }
      if ((i == 17 || i == 18) && buf[k] == 'X')
        num++;
    }
    if (i == 18 && num == 0) {
      FLG = false;
    }
  }

  if (!FLG) {
    printf("-1\\n");
    return 0;
  }

  first.row = start_row;
  first.col = start_col;
  first.count = 0;

  queue<Info> Q;
  Q.push(first);

  while (!Q.empty()) {

    if (Q.front().row >= 18) {
      minimum = Q.front().count;
      break;
    } else {

      for (int i = 0; i < 8; i++) {
        Info next = move(Q.front(), dir[i]);

        if (rangeCheck(next.row, next.col)) {
          Q.push(next);
        }
      }

      Q.pop();
    }
  }

  if (minimum == BIG_NUM) {
    printf("-1\\n");
  } else {
    printf("%d\\n", minimum);
  }

  return 0;
}

Error: MLE

Fixed submission:

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

int H = 19, W = 15;

enum DIR {
  Left_Up,
  Up,
  Right_Up,
  Left,
  Right,
  Left_Down,
  Down,
  Right_Down,
};

DIR dir[8] = {Left_Up, Up, Right_Up, Left, Right, Left_Down, Down, Right_Down};

int diff_row[8] = {-1, -1, -1, 0, 0, 1, 1, 1},
    diff_col[8] = {-1, 0, 1, -1, 1, -1, 0, 1};

struct BlackStone {
  short row, col;
  bool erased;
};

struct Info {
  BlackStone black_stone[20];
  short row, col, black_num, count;
};

bool rangeCheck(int row, int col) {
  if (row <= 17) {
    if (col < 0 || col > 14) {
      return false;
    } else {
      return true;
    }
  } else { // row >= 18
    if (row == 18 && (col < 0 || col > 14)) {
      return false;
    } else {
      return true;
    }
  }
}

Info move(Info info, DIR dir) {
  Info ret;

  char map[19][15];
  for (int i = 0; i < H; i++) {
    for (int k = 0; k < W; k++)
      map[i][k] = '.';
  }

  for (int i = 0; i < info.black_num; i++) {
    if (info.black_stone[i].erased == false) {
      map[info.black_stone[i].row][info.black_stone[i].col] = 'X';
    }
    ret.black_stone[i].row = info.black_stone[i].row;
    ret.black_stone[i].col = info.black_stone[i].col;
    ret.black_stone[i].erased = info.black_stone[i].erased;
  }
  ret.black_num = info.black_num;
  ret.count = info.count + 1;

  int next_row, next_col, index;

  switch (dir) {
  case Left_Up:
    index = 0;
    break;
  case Up:
    index = 1;
    break;
  case Right_Up:
    index = 2;
    break;
  case Left:
    index = 3;
    break;
  case Right:
    index = 4;
    break;
  case Left_Down:
    index = 5;
    break;
  case Down:
    index = 6;
    break;
  case Right_Down:
    index = 7;
    break;
  }

  next_row = info.row + diff_row[index];
  next_col = info.col + diff_col[index];

  while (rangeCheck(next_row, next_col) == true &&
         map[next_row][next_col] == 'X') {
    next_row += diff_row[index];
    next_col += diff_col[index];
  }

  if (next_row == info.row + diff_row[index] &&
      next_col == info.col + diff_col[index]) {
    ret.row = 1;
    ret.col = -1;
  } else {
    int tmp_row, tmp_col;

    tmp_row = info.row + diff_row[index];
    tmp_col = info.col + diff_col[index];

    while (tmp_row != next_row || tmp_col != next_col) {
      for (int i = 0; i < ret.black_num; i++) {
        if (ret.black_stone[i].erased == false &&
            ret.black_stone[i].row == tmp_row &&
            ret.black_stone[i].col == tmp_col) {
          ret.black_stone[i].erased = true;
          break;
        }
      }
      tmp_row += diff_row[index];
      tmp_col += diff_col[index];
    }

    ret.row = next_row;
    ret.col = next_col;
  }

  return ret;
}

int main() {

  Info first;

  for (int i = 0; i < 20; i++)
    first.black_stone[i].erased = true;
  first.black_num = 0;
  char buf[15];
  int minimum = BIG_NUM, start_row, start_col;

  for (int i = 0; i < H; i++) {
    scanf("%s", buf);
    for (int k = 0; k < W; k++) {
      if (buf[k] == 'O') {
        start_row = i;
        start_col = k;
      } else if (buf[k] == 'X') {
        first.black_stone[first.black_num].erased = false;
        first.black_stone[first.black_num].row = i;
        first.black_stone[first.black_num++].col = k;
      }
    }
  }

  first.row = start_row;
  first.col = start_col;
  first.count = 0;

  queue<Info> Q;
  Q.push(first);

  while (!Q.empty()) {

    if (Q.front().row >= 18) {
      minimum = Q.front().count;
      break;
    } else {

      for (int i = 0; i < 8; i++) {
        Info next = move(Q.front(), dir[i]);

        if (rangeCheck(next.row, next.col)) {
          Q.push(next);
        }
      }

      Q.pop();
    }
  }

  if (minimum == BIG_NUM) {
    printf("-1\\n");
  } else {
    printf("%d\\n", minimum);
  }

  return 0;
}