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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
// #define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define BIG_NUM 32767

struct Info {
  void set(int arg_row, int arg_col) {
    row = arg_row;
    col = arg_col;
  }
  int row, col;
};

struct Data {
  bool operator<(const struct Data &arg) const {
    return total_cost > arg.total_cost;
  }
  void set(short arg_total_cost, bool arg_cleard_1, bool arg_cleard_2,
           bool arg_cleard_3) {
    total_cost = arg_total_cost;
    cleard_1 = arg_cleard_1;
    cleard_2 = arg_cleard_2;
    cleard_3 = arg_cleard_3;
  }
  short total_cost;
  Info loc_1, loc_2, loc_3;
  bool cleard_1, cleard_2, cleard_3;
};

Info start_info[3], goal_info[3];

string line;
int W, H, N;
short min_cost1[16][16];
short min_cost2[16][16][16][16];
short min_cost3[16][16][16][16][16][16];
int diff_row[5] = {-1, 0, 0, 0, 1}, diff_col[5] = {0, -1, 0, 1, 0};
char table[16][17];

bool is_Same(Info a, Info b) {

  if (a.row == b.row && a.col == b.col) {
    return true;
  } else {
    return false;
  }
}

void calc3() {

  for (int a = 0; a < H; a++) {
    for (int b = 0; b < W; b++) {
      for (int c = 0; c < H; c++) {
        for (int d = 0; d < W; d++) {
          for (int e = 0; e < H; e++) {
            for (int f = 0; f < W; f++)
              min_cost3[a][b][c][d][e][f] = BIG_NUM;
          }
        }
      }
    }
  }

  priority_queue<Data> Q;
  min_cost3[start_info[0].row][start_info[0].col][start_info[1].row]
           [start_info[1].col][start_info[2].row][start_info[2].col] = 0;
  Data first;
  first.total_cost = 0;
  first.loc_1 = start_info[0];
  first.loc_2 = start_info[1];
  first.loc_3 = start_info[2];
  first.cleard_1 = is_Same(start_info[0], goal_info[0]);
  first.cleard_2 = is_Same(start_info[1], goal_info[1]);
  first.cleard_3 = is_Same(start_info[2], goal_info[2]);
  Q.push(first);

  Info next_loc1, next_loc2, next_loc3;

  while (!Q.empty()) {

    if (Q.top().cleard_1 == true && Q.top().cleard_2 == true &&
        Q.top().cleard_3 == true) {
      Q.pop();
    } else if (Q.top().total_cost >
               min_cost3[Q.top().loc_1.row][Q.top().loc_1.col]
                        [Q.top().loc_2.row][Q.top().loc_2.col]
                        [Q.top().loc_3.row][Q.top().loc_3.col]) {
      Q.pop();
    } else {

      for (int i = 0; i < 5; i++) {
        next_loc1.set(Q.top().loc_1.row + diff_row[i],
                      Q.top().loc_1.col + diff_col[i]);
        if (table[next_loc1.row][next_loc1.col] == '#')
          continue;

        for (int k = 0; k < 5; k++) {
          next_loc2.set(Q.top().loc_2.row + diff_row[k],
                        Q.top().loc_2.col + diff_col[k]);
          if ((table[next_loc2.row][next_loc2.col] == '#') ||
              (is_Same(next_loc1, next_loc2) == true) ||
              (is_Same(next_loc1, Q.top().loc_2) == true &&
               is_Same(next_loc2, Q.top().loc_1)))
            continue;
          for (int p = 0; p < 5; p++) {

            next_loc3.set(Q.top().loc_3.row + diff_row[p],
                          Q.top().loc_3.col + diff_col[p]);
            if ((table[next_loc3.row][next_loc3.col] == '#') ||
                (is_Same(next_loc1, next_loc3) == true) ||
                (is_Same(next_loc2, next_loc3) == true) ||
                (is_Same(next_loc1, Q.top().loc_3) == true &&
                 is_Same(next_loc3, Q.top().loc_1)) ||
                (is_Same(next_loc2, Q.top().loc_3) == true &&
                 is_Same(next_loc3, Q.top().loc_2)))
              continue;

            if (min_cost3[next_loc1.row][next_loc1.col][next_loc2.row]
                         [next_loc2.col][next_loc3.row][next_loc3.col] >
                Q.top().total_cost + 1) {
              min_cost3[next_loc1.row][next_loc1.col][next_loc2.row]
                       [next_loc2.col][next_loc3.row][next_loc3.col] =
                           Q.top().total_cost + 1;
              Data new_data;
              new_data.loc_1 = next_loc1;
              new_data.loc_2 = next_loc2;
              new_data.loc_3 = next_loc3;
              new_data.total_cost = Q.top().total_cost + 1;
              new_data.cleard_1 = is_Same(next_loc1, goal_info[0]);
              new_data.cleard_2 = is_Same(next_loc2, goal_info[1]);
              new_data.cleard_3 = is_Same(next_loc3, goal_info[2]);
              Q.push(new_data);
            }
          }
        }
      }
      Q.pop();
    }
  }

  printf("%d\\n",
         min_cost3[goal_info[0].row][goal_info[0].col][goal_info[1].row]
                  [goal_info[1].col][goal_info[2].row][goal_info[2].col]);
}

void calc2() {

  for (int a = 0; a < H; a++) {
    for (int b = 0; b < W; b++) {
      for (int c = 0; c < H; c++) {
        for (int d = 0; d < W; d++)
          min_cost2[a][b][c][d] = BIG_NUM;
      }
    }
  }

  priority_queue<Data> Q;
  min_cost2[start_info[0].row][start_info[0].col][start_info[1].row]
           [start_info[1].col] = 0;
  Data first;
  first.total_cost = 0;
  first.loc_1 = start_info[0];
  first.loc_2 = start_info[1];
  first.cleard_1 = is_Same(start_info[0], goal_info[0]);
  first.cleard_2 = is_Same(start_info[1], goal_info[1]);
  Q.push(first);

  Info next_loc1, next_loc2;

  while (!Q.empty()) {

    if (Q.top().cleard_1 == true && Q.top().cleard_2 == true) {
      Q.pop();
    } else if (Q.top().total_cost >
               min_cost2[Q.top().loc_1.row][Q.top().loc_1.col]
                        [Q.top().loc_2.row][Q.top().loc_2.col]) {
      Q.pop();
    } else {

      for (int i = 0; i < 5; i++) {
        next_loc1.set(Q.top().loc_1.row + diff_row[i],
                      Q.top().loc_1.col + diff_col[i]);
        if (table[next_loc1.row][next_loc1.col] == '#')
          continue;
        for (int k = 0; k < 5; k++) {

          next_loc2.set(Q.top().loc_2.row + diff_row[k],
                        Q.top().loc_2.col + diff_col[k]);
          if ((table[next_loc2.row][next_loc2.col] == '#') ||
              (is_Same(next_loc1, next_loc2) == true) ||
              (is_Same(next_loc1, Q.top().loc_2) == true &&
               is_Same(next_loc2, Q.top().loc_1)))
            continue;

          if (min_cost2[next_loc1.row][next_loc1.col][next_loc2.row]
                       [next_loc2.col] > Q.top().total_cost + 1) {
            min_cost2[next_loc1.row][next_loc1.col][next_loc2.row]
                     [next_loc2.col] = Q.top().total_cost + 1;
            Data new_data;
            new_data.loc_1 = next_loc1;
            new_data.loc_2 = next_loc2;
            new_data.total_cost = Q.top().total_cost + 1;
            new_data.cleard_1 = is_Same(next_loc1, goal_info[0]);
            new_data.cleard_2 = is_Same(next_loc2, goal_info[1]);
            Q.push(new_data);
          }
        }
      }

      Q.pop();
    }
  }

  printf("%d\\n", min_cost2[goal_info[0].row][goal_info[0].col][goal_info[1].row]
                          [goal_info[1].col]);
}

void calc1() {

  for (int a = 0; a < H; a++) {
    for (int b = 0; b < W; b++) {
      min_cost1[a][b] = BIG_NUM;
    }
  }

  priority_queue<Data> Q;
  min_cost1[start_info[0].row][start_info[0].col] = 0;
  Data first;
  first.total_cost = 0;
  first.loc_1 = start_info[0];
  first.cleard_1 = is_Same(start_info[0], goal_info[0]);
  Q.push(first);

  Info next_loc1;

  while (!Q.empty()) {

    if (Q.top().cleard_1 == true) {
      Q.pop();
    } else if (Q.top().total_cost >
               min_cost1[Q.top().loc_1.row][Q.top().loc_1.col]) {
      Q.pop();
    } else {

      for (int i = 0; i < 5; i++) {
        next_loc1.set(Q.top().loc_1.row + diff_row[i],
                      Q.top().loc_1.col + diff_col[i]);
        if (table[next_loc1.row][next_loc1.col] == '#')
          continue;

        if (min_cost1[next_loc1.row][next_loc1.col] > Q.top().total_cost + 1) {
          min_cost1[next_loc1.row][next_loc1.col] = Q.top().total_cost + 1;
          Data new_data;
          new_data.loc_1 = next_loc1;
          new_data.total_cost = Q.top().total_cost + 1;
          new_data.cleard_1 = is_Same(next_loc1, goal_info[0]);
          Q.push(new_data);
        }
      }
      Q.pop();
    }
  }
  printf("%d\\n", min_cost1[goal_info[0].row][goal_info[0].col]);
}

void func() {

  for (int row = 0; row < H; row++) {

    getline(cin, line);
    for (int col = 0; col < W; col++)
      table[row][col] = line[col];

    for (int col = 0; col < W; col++) {
      switch (table[row][col]) {
      case 'a':
        start_info[0].set(row, col);
        break;
      case 'b':
        start_info[1].set(row, col);
        break;
      case 'c':
        start_info[2].set(row, col);
        break;
      case 'A':
        goal_info[0].set(row, col);
        break;
      case 'B':
        goal_info[1].set(row, col);
        break;
      case 'C':
        goal_info[2].set(row, col);
        break;
      }
    }
  }

  switch (N) {
  case 1:
    calc1();
    break;
  case 2:
    calc2();
    break;
  case 3:
    calc3();
    break;
  }
}

int main() {

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

    getchar();
    func();
  }

  return 0;
}

Error: MLE

Fixed submission:

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

struct Info {
  void set(int arg_row, int arg_col) {
    row = arg_row;
    col = arg_col;
  }
  int row, col;
};

struct Data {
  bool operator<(const struct Data &arg) const {
    return total_cost > arg.total_cost;
  }
  void set(int arg_total_cost, bool arg_cleard_1, bool arg_cleard_2,
           bool arg_cleard_3) {
    total_cost = arg_total_cost;
    cleard_1 = arg_cleard_1;
    cleard_2 = arg_cleard_2;
    cleard_3 = arg_cleard_3;
  }
  int total_cost;
  Info loc_1, loc_2, loc_3;
  bool cleard_1, cleard_2, cleard_3;
};

Info start_info[3], goal_info[3];

string line;
int W, H, N;
int min_cost1[16][16];
int min_cost2[16][16][16][16];
int min_cost3[16][16][16][16][16][16];
int diff_row[5] = {-1, 0, 0, 0, 1}, diff_col[5] = {0, -1, 0, 1, 0};
char table[16][17];

bool is_Same(Info a, Info b) {

  if (a.row == b.row && a.col == b.col) {
    return true;
  } else {
    return false;
  }
}

void calc3() {

  for (int a = 0; a < H; a++) {
    for (int b = 0; b < W; b++) {
      for (int c = 0; c < H; c++) {
        for (int d = 0; d < W; d++) {
          for (int e = 0; e < H; e++) {
            for (int f = 0; f < W; f++)
              min_cost3[a][b][c][d][e][f] = BIG_NUM;
          }
        }
      }
    }
  }

  priority_queue<Data> Q;
  min_cost3[start_info[0].row][start_info[0].col][start_info[1].row]
           [start_info[1].col][start_info[2].row][start_info[2].col] = 0;
  Data first;
  first.total_cost = 0;
  first.loc_1 = start_info[0];
  first.loc_2 = start_info[1];
  first.loc_3 = start_info[2];
  first.cleard_1 = is_Same(start_info[0], goal_info[0]);
  first.cleard_2 = is_Same(start_info[1], goal_info[1]);
  first.cleard_3 = is_Same(start_info[2], goal_info[2]);
  Q.push(first);

  Info next_loc1, next_loc2, next_loc3;

  while (!Q.empty()) {

    if (Q.top().cleard_1 == true && Q.top().cleard_2 == true &&
        Q.top().cleard_3 == true) {
      Q.pop();
    } else if (Q.top().total_cost >
               min_cost3[Q.top().loc_1.row][Q.top().loc_1.col]
                        [Q.top().loc_2.row][Q.top().loc_2.col]
                        [Q.top().loc_3.row][Q.top().loc_3.col]) {
      Q.pop();
    } else {

      for (int i = 0; i < 5; i++) {
        next_loc1.set(Q.top().loc_1.row + diff_row[i],
                      Q.top().loc_1.col + diff_col[i]);
        if (table[next_loc1.row][next_loc1.col] == '#')
          continue;

        for (int k = 0; k < 5; k++) {
          next_loc2.set(Q.top().loc_2.row + diff_row[k],
                        Q.top().loc_2.col + diff_col[k]);
          if ((table[next_loc2.row][next_loc2.col] == '#') ||
              (is_Same(next_loc1, next_loc2) == true) ||
              (is_Same(next_loc1, Q.top().loc_2) == true &&
               is_Same(next_loc2, Q.top().loc_1)))
            continue;
          for (int p = 0; p < 5; p++) {

            next_loc3.set(Q.top().loc_3.row + diff_row[p],
                          Q.top().loc_3.col + diff_col[p]);
            if ((table[next_loc3.row][next_loc3.col] == '#') ||
                (is_Same(next_loc1, next_loc3) == true) ||
                (is_Same(next_loc2, next_loc3) == true) ||
                (is_Same(next_loc1, Q.top().loc_3) == true &&
                 is_Same(next_loc3, Q.top().loc_1)) ||
                (is_Same(next_loc2, Q.top().loc_3) == true &&
                 is_Same(next_loc3, Q.top().loc_2)))
              continue;

            if (min_cost3[next_loc1.row][next_loc1.col][next_loc2.row]
                         [next_loc2.col][next_loc3.row][next_loc3.col] >
                Q.top().total_cost + 1) {
              min_cost3[next_loc1.row][next_loc1.col][next_loc2.row]
                       [next_loc2.col][next_loc3.row][next_loc3.col] =
                           Q.top().total_cost + 1;
              Data new_data;
              new_data.loc_1 = next_loc1;
              new_data.loc_2 = next_loc2;
              new_data.loc_3 = next_loc3;
              new_data.total_cost = Q.top().total_cost + 1;
              new_data.cleard_1 = is_Same(next_loc1, goal_info[0]);
              new_data.cleard_2 = is_Same(next_loc2, goal_info[1]);
              new_data.cleard_3 = is_Same(next_loc3, goal_info[2]);
              Q.push(new_data);
            }
          }
        }
      }
      Q.pop();
    }
  }

  printf("%d\\n",
         min_cost3[goal_info[0].row][goal_info[0].col][goal_info[1].row]
                  [goal_info[1].col][goal_info[2].row][goal_info[2].col]);
}

void calc2() {

  for (int a = 0; a < H; a++) {
    for (int b = 0; b < W; b++) {
      for (int c = 0; c < H; c++) {
        for (int d = 0; d < W; d++)
          min_cost2[a][b][c][d] = BIG_NUM;
      }
    }
  }

  priority_queue<Data> Q;
  min_cost2[start_info[0].row][start_info[0].col][start_info[1].row]
           [start_info[1].col] = 0;
  Data first;
  first.total_cost = 0;
  first.loc_1 = start_info[0];
  first.loc_2 = start_info[1];
  first.cleard_1 = is_Same(start_info[0], goal_info[0]);
  first.cleard_2 = is_Same(start_info[1], goal_info[1]);
  Q.push(first);

  Info next_loc1, next_loc2;

  while (!Q.empty()) {

    if (Q.top().cleard_1 == true && Q.top().cleard_2 == true) {
      Q.pop();
    } else if (Q.top().total_cost >
               min_cost2[Q.top().loc_1.row][Q.top().loc_1.col]
                        [Q.top().loc_2.row][Q.top().loc_2.col]) {
      Q.pop();
    } else {

      for (int i = 0; i < 5; i++) {
        next_loc1.set(Q.top().loc_1.row + diff_row[i],
                      Q.top().loc_1.col + diff_col[i]);
        if (table[next_loc1.row][next_loc1.col] == '#')
          continue;
        for (int k = 0; k < 5; k++) {

          next_loc2.set(Q.top().loc_2.row + diff_row[k],
                        Q.top().loc_2.col + diff_col[k]);
          if ((table[next_loc2.row][next_loc2.col] == '#') ||
              (is_Same(next_loc1, next_loc2) == true) ||
              (is_Same(next_loc1, Q.top().loc_2) == true &&
               is_Same(next_loc2, Q.top().loc_1)))
            continue;

          if (min_cost2[next_loc1.row][next_loc1.col][next_loc2.row]
                       [next_loc2.col] > Q.top().total_cost + 1) {
            min_cost2[next_loc1.row][next_loc1.col][next_loc2.row]
                     [next_loc2.col] = Q.top().total_cost + 1;
            Data new_data;
            new_data.loc_1 = next_loc1;
            new_data.loc_2 = next_loc2;
            new_data.total_cost = Q.top().total_cost + 1;
            new_data.cleard_1 = is_Same(next_loc1, goal_info[0]);
            new_data.cleard_2 = is_Same(next_loc2, goal_info[1]);
            Q.push(new_data);
          }
        }
      }

      Q.pop();
    }
  }

  printf("%d\\n", min_cost2[goal_info[0].row][goal_info[0].col][goal_info[1].row]
                          [goal_info[1].col]);
}

void calc1() {

  for (int a = 0; a < H; a++) {
    for (int b = 0; b < W; b++) {
      min_cost1[a][b] = BIG_NUM;
    }
  }

  priority_queue<Data> Q;
  min_cost1[start_info[0].row][start_info[0].col] = 0;
  Data first;
  first.total_cost = 0;
  first.loc_1 = start_info[0];
  first.cleard_1 = is_Same(start_info[0], goal_info[0]);
  Q.push(first);

  Info next_loc1;

  while (!Q.empty()) {

    if (Q.top().cleard_1 == true) {
      Q.pop();
    } else if (Q.top().total_cost >
               min_cost1[Q.top().loc_1.row][Q.top().loc_1.col]) {
      Q.pop();
    } else {

      for (int i = 0; i < 5; i++) {
        next_loc1.set(Q.top().loc_1.row + diff_row[i],
                      Q.top().loc_1.col + diff_col[i]);
        if (table[next_loc1.row][next_loc1.col] == '#')
          continue;

        if (min_cost1[next_loc1.row][next_loc1.col] > Q.top().total_cost + 1) {
          min_cost1[next_loc1.row][next_loc1.col] = Q.top().total_cost + 1;
          Data new_data;
          new_data.loc_1 = next_loc1;
          new_data.total_cost = Q.top().total_cost + 1;
          new_data.cleard_1 = is_Same(next_loc1, goal_info[0]);
          Q.push(new_data);
        }
      }
      Q.pop();
    }
  }
  printf("%d\\n", min_cost1[goal_info[0].row][goal_info[0].col]);
}

void func() {

  for (int row = 0; row < H; row++) {

    getline(cin, line);
    for (int col = 0; col < W; col++)
      table[row][col] = line[col];

    for (int col = 0; col < W; col++) {
      switch (table[row][col]) {
      case 'a':
        start_info[0].set(row, col);
        break;
      case 'b':
        start_info[1].set(row, col);
        break;
      case 'c':
        start_info[2].set(row, col);
        break;
      case 'A':
        goal_info[0].set(row, col);
        break;
      case 'B':
        goal_info[1].set(row, col);
        break;
      case 'C':
        goal_info[2].set(row, col);
        break;
      }
    }
  }

  switch (N) {
  case 1:
    calc1();
    break;
  case 2:
    calc2();
    break;
  case 3:
    calc3();
    break;
  }
}

int main() {

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

    getchar();
    func();
  }

  return 0;
}