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

#include <algorithm>
#include <math.h>
#include <stdio.h>

using namespace std;

int minimum = -1;

int calcDiffSum(int table[2][4]) {
  int sum = 0;
  for (int row = 0; row < 2; row++) {
    for (int col = 0; col < 4; col++) {
      if (table[row][col] != 0) {
        sum +=
            abs((table[row][col]) / 4 - row) + abs((table[row][col]) % 4 - col);
      }
    }
  }
  return sum;
}

int zeroLoc(int table[2][4]) {
  int zero_loc;
  for (int i = 0; i < 2; i++) {
    for (int k = 0; k < 4; k++) {
      if (table[i][k] == 0) {
        zero_loc = 10 * i + k;
      }
    }
  }
  return zero_loc;
}

void recursive(int table[2][4], int max_depth, int count, int pre_loc,
               int zero_loc) {
  int diffSum = calcDiffSum(table);
  if (count == max_depth && diffSum == 0) {
    minimum = max_depth;
    return;
  }

  if (minimum != -1)
    return;

  int next_table[3][2][4];
  int dif1, dif2, dif3, dif4;

  switch (zero_loc) {
  case 0:
    for (int a = 0; a < 2; a++) {
      for (int b = 0; b < 2; b++) {
        for (int c = 0; c < 4; c++) {
          next_table[a][b][c] = table[b][c];
        }
      }
    }

    if (pre_loc != 1) {
      if ((table[0][1]) % 4 == 0) {
        dif1 = diffSum - 1;
      } else {
        dif1 = diffSum + 1;
      }
      swap(next_table[0][0][0], next_table[0][0][1]);
      if (count < max_depth && dif1 <= max_depth - count) {
        recursive(next_table[0], max_depth, count + 1, zero_loc, 1);
      }
    }
    if (pre_loc != 10) {
      if ((table[1][0]) / 4 == 0) {
        dif2 = diffSum - 1;
      } else {
        dif2 = diffSum + 1;
      }
      swap(next_table[1][0][0], next_table[1][1][0]);
      if (count < max_depth && dif2 <= max_depth - count) {
        recursive(next_table[1], max_depth, count + 1, zero_loc, 10);
      }
    }
    break;
  case 1:

    for (int a = 0; a < 3; a++) {
      for (int b = 0; b < 2; b++) {
        for (int c = 0; c < 4; c++) {
          next_table[a][b][c] = table[b][c];
        }
      }
    }

    if (pre_loc != 0) {
      if ((table[0][0]) % 4 >= 1) {
        dif1 = diffSum - 1;
      } else {
        dif1 = diffSum + 1;
      }
      swap(next_table[0][0][1], next_table[0][0][0]);
      if (count < max_depth && dif1 <= max_depth - count) {
        recursive(next_table[0], max_depth, count + 1, zero_loc, 0);
      }
    }
    if (pre_loc != 11) {
      if ((table[1][1]) / 4 == 0) {
        dif2 = diffSum - 1;
      } else {
        dif2 = diffSum + 1;
      }
      swap(next_table[1][0][1], next_table[1][1][1]);
      if (count < max_depth && dif2 <= max_depth - count) {
        recursive(next_table[1], max_depth, count + 1, zero_loc, 11);
      }
    }
    if (pre_loc != 2) {
      if ((table[0][2]) % 4 <= 1) {
        dif3 = diffSum - 1;
      } else {
        dif3 = diffSum + 1;
      }
      swap(next_table[2][0][1], next_table[2][0][2]);
      if (count < max_depth && dif3 <= max_depth - count) {
        recursive(next_table[2], max_depth, count + 1, zero_loc, 2);
      }
    }
    break;
  case 2:
    for (int a = 0; a < 3; a++) {
      for (int b = 0; b < 2; b++) {
        for (int c = 0; c < 4; c++) {
          next_table[a][b][c] = table[b][c];
        }
      }
    }

    if (pre_loc != 1) {
      if ((table[0][1]) % 4 >= 2) {
        dif1 = diffSum - 1;
      } else {
        dif1 = diffSum + 1;
      }
      swap(next_table[0][0][2], next_table[0][0][1]);
      if (count < max_depth && dif1 <= max_depth - count) {
        recursive(next_table[0], max_depth, count + 1, zero_loc, 1);
      }
    }
    if (pre_loc != 12) {
      if ((table[1][2]) / 4 == 0) {
        dif2 = diffSum - 1;
      } else {
        dif2 = diffSum + 1;
      }
      swap(next_table[1][0][2], next_table[1][1][2]);
      if (count < max_depth && dif2 <= max_depth - count) {
        recursive(next_table[1], max_depth, count + 1, zero_loc, 12);
      }
    }
    if (pre_loc != 3) {
      if ((table[0][3]) % 4 <= 2) {
        dif3 = diffSum - 1;
      } else {
        dif3 = diffSum + 1;
      }
      swap(next_table[2][0][2], next_table[2][0][3]);
      if (count < max_depth && dif3 <= max_depth - count) {
        recursive(next_table[2], max_depth, count + 1, zero_loc, 3);
      }
    }
    break;
  case 3:
    for (int a = 0; a < 2; a++) {
      for (int b = 0; b < 2; b++) {
        for (int c = 0; c < 4; c++) {
          next_table[a][b][c] = table[b][c];
        }
      }
    }

    if (pre_loc != 2) {
      if ((table[0][2]) % 4 == 3) {
        dif1 = diffSum - 1;
      } else {
        dif1 = diffSum + 1;
      }
      swap(next_table[0][0][3], next_table[0][0][2]);
      if (count < max_depth && dif1 <= max_depth - count) {
        recursive(next_table[0], max_depth, count + 1, zero_loc, 2);
      }
    }
    if (pre_loc != 13) {
      if ((table[1][3]) / 4 == 0) {
        dif2 = diffSum - 1;
      } else {
        dif2 = diffSum + 1;
      }
      swap(next_table[1][0][3], next_table[1][1][3]);
      if (count < max_depth && dif2 <= max_depth - count) {
        recursive(next_table[1], max_depth, count + 1, zero_loc, 13);
      }
    }
    break;
  case 10:
    for (int a = 0; a < 2; a++) {
      for (int b = 0; b < 2; b++) {
        for (int c = 0; c < 4; c++) {
          next_table[a][b][c] = table[b][c];
        }
      }
    }

    if (pre_loc != 0) {
      if ((table[0][0]) / 4 == 1) {
        dif1 = diffSum - 1;
      } else {
        dif1 = diffSum + 1;
      }
      swap(next_table[0][1][0], next_table[0][0][0]);
      if (count < max_depth && dif1 <= max_depth - count) {
        recursive(next_table[0], max_depth, count + 1, zero_loc, 0);
      }
    }
    if (pre_loc != 11) {
      if ((table[1][1]) % 4 == 0) {
        dif2 = diffSum - 1;
      } else {
        dif2 = diffSum + 1;
      }
      swap(next_table[1][1][0], next_table[1][1][1]);
      if (count < max_depth && dif2 <= max_depth - count) {
        recursive(next_table[1], max_depth, count + 1, zero_loc, 11);
      }
    }
    break;
  case 11:
    for (int a = 0; a < 3; a++) {
      for (int b = 0; b < 2; b++) {
        for (int c = 0; c < 4; c++) {
          next_table[a][b][c] = table[b][c];
        }
      }
    }

    if (pre_loc != 1) {
      if ((table[0][1]) / 4 == 1) {
        dif1 = diffSum - 1;
      } else {
        dif1 = diffSum + 1;
      }
      swap(next_table[0][1][1], next_table[0][0][1]);
      if (count < max_depth && dif1 <= max_depth - count) {
        recursive(next_table[0], max_depth, count + 1, zero_loc, 1);
      }
    }
    if (pre_loc != 10) {
      if ((table[1][0]) % 4 >= 1) {
        dif2 = diffSum - 1;
      } else {
        dif2 = diffSum + 1;
      }
      swap(next_table[1][1][1], next_table[1][1][0]);
      if (count < max_depth && dif2 <= max_depth - count) {
        recursive(next_table[1], max_depth, count + 1, zero_loc, 10);
      }
    }
    if (pre_loc != 12) {
      if ((table[1][2]) % 4 <= 1) {
        dif3 = diffSum - 1;
      } else {
        dif3 = diffSum + 1;
      }
      swap(next_table[2][1][1], next_table[2][1][2]);
      if (count < max_depth && dif3 <= max_depth - count) {
        recursive(next_table[2], max_depth, count + 1, zero_loc, 12);
      }
    }
    break;
  case 12:
    for (int a = 0; a < 3; a++) {
      for (int b = 0; b < 2; b++) {
        for (int c = 0; c < 4; c++) {
          next_table[a][b][c] = table[b][c];
        }
      }
    }

    if (pre_loc != 2) {
      if ((table[0][2]) / 4 == 1) {
        dif1 = diffSum - 1;
      } else {
        dif1 = diffSum + 1;
      }
      swap(next_table[0][1][2], next_table[0][0][2]);
      if (count < max_depth && dif1 <= max_depth - count) {
        recursive(next_table[0], max_depth, count + 1, zero_loc, 2);
      }
    }
    if (pre_loc != 11) {
      if ((table[1][1]) % 4 >= 2) {
        dif2 = diffSum - 1;
      } else {
        dif2 = diffSum + 1;
      }
      swap(next_table[1][1][2], next_table[1][1][1]);
      if (count < max_depth && dif2 <= max_depth - count) {
        recursive(next_table[1], max_depth, count + 1, zero_loc, 11);
      }
    }
    if (pre_loc != 13) {
      if ((table[1][3]) % 4 <= 2) {
        dif3 = diffSum - 1;
      } else {
        dif3 = diffSum + 1;
      }
      swap(next_table[2][1][2], next_table[2][1][3]);
      if (count < max_depth && dif3 <= max_depth - count) {
        recursive(next_table[2], max_depth, count + 1, zero_loc, 13);
      }
    }
    break;
  case 13:

    for (int a = 0; a < 2; a++) {
      for (int b = 0; b < 2; b++) {
        for (int c = 0; c < 4; c++) {
          next_table[a][b][c] = table[b][c];
        }
      }
    }

    if (pre_loc != 3) {
      if ((table[0][3]) / 4 == 1) {
        dif1 = diffSum - 1;
      } else {
        dif1 = diffSum + 1;
      }
      swap(next_table[0][1][3], next_table[0][0][3]);
      if (count < max_depth && dif1 <= max_depth - count) {
        recursive(next_table[0], max_depth, count + 1, zero_loc, 3);
      }
    }
    if (pre_loc != 12) {
      if ((table[1][2]) % 4 == 3) {
        dif2 = diffSum - 1;
      } else {
        dif2 = diffSum + 1;
      }
      swap(next_table[1][1][3], next_table[1][1][2]);
      if (count < max_depth && dif2 <= max_depth - count) {
        recursive(next_table[1], max_depth, count + 1, zero_loc, 12);
      }
    }
    break;
  }
}

void func(int table[2][4], int max_depth) {
  while (minimum == -1) {
    recursive(table, max_depth, 0, -1, zeroLoc(table));
    max_depth += 2;
  }
}

int main() {

  int table[2][4], start_count;

  while (scanf("%d %d %d %d %d %d %d %d", &table[0][0], &table[0][1],
               &table[0][2], &table[0][3], &table[1][0], &table[1][1],
               &table[1][2], &table[1][3]) != EOF) {
    start_count = calcDiffSum(table);

    func(table, start_count);

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

    minimum = -1;
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <math.h>
#include <stdio.h>

using namespace std;

int checkTable[40320];

void setNUM(int table[2][4], int x) {
  int S = 10000000;
  for (int i = 0; i < 2; i++) {
    for (int k = 0; k < 4; k++) {
      table[i][k] = x / S;
      x = x % S;
      S /= 10;
    }
  }
}

int getNUM(int x) {
  switch (x) {
  case 0:
    return 1;
  case 1:
    return 1;
  case 2:
    return 2;
  case 3:
    return 6;
  case 4:
    return 24;
  case 5:
    return 120;
  case 6:
    return 720;
  case 7:
    return 5040;
  }
  return -1;
}

int makeCode(int Table[2][4]) {
  return 10000000 * Table[0][0] + 1000000 * Table[0][1] + 100000 * Table[0][2] +
         10000 * Table[0][3] + 1000 * Table[1][0] + 100 * Table[1][1] +
         10 * Table[1][2] + Table[1][3];
}

int translateORDER(int Table[2][4]) {
  long long x = makeCode(Table);
  int checkTable[8] = {0};
  int S = 10000000;
  int ret = 0, small_num_appear_count;
  for (int i = 7; i >= 0; i--) {
    small_num_appear_count = 0;
    for (int k = 0; k < x / S; k++) {
      if (checkTable[k] == 1)
        small_num_appear_count++;
    }
    ret += ((x / S) - small_num_appear_count) * getNUM(i);
    checkTable[(x / S)] = 1;
    x %= S;
    S /= 10;
  }

  return ret;
}

int zeroLoc(int table[2][4]) {
  int zero_loc;
  for (int i = 0; i < 2; i++) {
    for (int k = 0; k < 4; k++) {
      if (table[i][k] == 0) {
        zero_loc = 10 * i + k;
      }
    }
  }
  return zero_loc;
}

struct Info {
  Info() { zero_loc = data = count = 0; }
  Info(int arg_data, int arg_count, short arg_loc) {
    data = arg_data;
    count = arg_count;
    zero_loc = arg_loc;
  }
  int data, count;
  short zero_loc;
};

class LongQ {
public:
  LongQ() {
    Q = new Info[40320];
    head = tail = num_of_data = 0;
  }

  void enqueue(int arg_data, int arg_count, short arg_loc) {
    Q[tail].count = arg_count;
    Q[tail].data = arg_data;
    Q[tail].zero_loc = arg_loc;
    num_of_data++;
    tail = (tail + 1) % 40320;
  }

  Info dequeue() {
    Info ret = Q[head];
    head = (head + 1) % 40320;
    num_of_data--;
    return ret;
  }

  bool isEmpty() { return num_of_data == 0; }

private:
  Info *Q;
  int head, tail, num_of_data;
};

LongQ func(LongQ queue, int table[2][4], Info tmpInfo, short zero_loc) {
  if (checkTable[translateORDER(table)] == -1) {
    checkTable[translateORDER(table)] = tmpInfo.count;
    queue.enqueue(makeCode(table), tmpInfo.count + 1, zero_loc);
  }
  return queue;
}

int main() {

  int table[2][4];

  while (scanf("%d %d %d %d %d %d %d %d", &table[0][0], &table[0][1],
               &table[0][2], &table[0][3], &table[1][0], &table[1][1],
               &table[1][2], &table[1][3]) != EOF) {

    for (int i = 0; i < 40320; i++)
      checkTable[i] = -1;

    checkTable[translateORDER(table)] = 0;
    LongQ queue;

    queue.enqueue(makeCode(table), 0, zeroLoc(table));

    Info tmpInfo;

    while (queue.isEmpty() == false) {
      tmpInfo = queue.dequeue();

      int tmpTable[2][4];
      setNUM(tmpTable, tmpInfo.data);
      if (tmpTable[0][0] == 0 && tmpTable[0][1] == 1 && tmpTable[0][2] == 2 &&
          tmpTable[0][3] == 3 && tmpTable[1][0] == 4 && tmpTable[1][1] == 5 &&
          tmpTable[1][2] == 6 && tmpTable[1][3] == 7) {
        printf("%d\\n", tmpInfo.count);
        break;
      }

      int next_table[4][2][4];

      for (int a = 0; a < 4; a++) {
        for (int b = 0; b < 2; b++) {
          for (int c = 0; c < 4; c++) {
            next_table[a][b][c] = tmpTable[b][c];
          }
        }
      }

      switch (tmpInfo.zero_loc) {
      case 0:
        swap(next_table[0][0][0], next_table[0][0][1]);
        queue = func(queue, next_table[0], tmpInfo, 1);

        swap(next_table[1][0][0], next_table[1][1][0]);
        queue = func(queue, next_table[1], tmpInfo, 10);
        break;
      case 1:
        swap(next_table[0][0][1], next_table[0][0][0]);
        queue = func(queue, next_table[0], tmpInfo, 0);

        swap(next_table[1][0][1], next_table[1][0][2]);
        queue = func(queue, next_table[1], tmpInfo, 2);

        swap(next_table[2][0][1], next_table[2][1][1]);
        queue = func(queue, next_table[2], tmpInfo, 11);
        break;
      case 2:
        swap(next_table[0][0][2], next_table[0][0][1]);
        queue = func(queue, next_table[0], tmpInfo, 1);

        swap(next_table[1][0][2], next_table[1][1][2]);
        queue = func(queue, next_table[1], tmpInfo, 12);

        swap(next_table[2][0][2], next_table[2][0][3]);
        queue = func(queue, next_table[2], tmpInfo, 3);

        break;
      case 3:
        swap(next_table[0][0][3], next_table[0][0][2]);
        queue = func(queue, next_table[0], tmpInfo, 2);

        swap(next_table[1][0][3], next_table[1][1][3]);
        queue = func(queue, next_table[1], tmpInfo, 13);

        break;
      case 10:
        swap(next_table[0][1][0], next_table[0][0][0]);
        queue = func(queue, next_table[0], tmpInfo, 0);

        swap(next_table[1][1][0], next_table[1][1][1]);
        queue = func(queue, next_table[1], tmpInfo, 11);

        break;
      case 11:
        swap(next_table[0][1][1], next_table[0][1][0]);
        queue = func(queue, next_table[0], tmpInfo, 10);

        swap(next_table[1][1][1], next_table[1][0][1]);
        queue = func(queue, next_table[1], tmpInfo, 1);

        swap(next_table[2][1][1], next_table[2][1][2]);
        queue = func(queue, next_table[2], tmpInfo, 12);
        break;
      case 12:
        swap(next_table[0][1][2], next_table[0][1][1]);
        queue = func(queue, next_table[0], tmpInfo, 11);

        swap(next_table[1][1][2], next_table[1][0][2]);
        queue = func(queue, next_table[1], tmpInfo, 2);

        swap(next_table[2][1][2], next_table[2][1][3]);
        queue = func(queue, next_table[2], tmpInfo, 13);
        break;
      case 13:
        swap(next_table[0][1][3], next_table[0][0][3]);
        queue = func(queue, next_table[0], tmpInfo, 3);

        swap(next_table[1][1][3], next_table[1][1][2]);
        queue = func(queue, next_table[1], tmpInfo, 12);

        break;
      }
    }
  }

  return 0;
}