Problem p00190 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <map>
#include <queue>

using namespace std;

const int SIZE = 13;

struct Puzzle {
  short c[SIZE];

  void move(int d, int n) {
    if (d == 0)
      moveUp(n);
    if (d == 1)
      moveDown(n);
    if (d == 2)
      moveLeft(n);
    if (d == 3)
      moveRight(n);
  }
  // n = choosed blank number 0(first one) or 1(second one)
  void moveUp(int n) {
    int pos = findBlankPosition(n);
    int tmp[] = {-1, -1, 0, -1, -1, 1, 2, 3, -1, 5, 6, 7, 10};

    int npos = tmp[pos];
    if (npos != -1)
      swap(c[pos], c[npos]);
  }

  void moveDown(int n) {
    int pos = findBlankPosition(n);
    int tmp[] = {2, 5, 6, 7, -1, 9, 10, 11, -1, -1, 12, -1, -1};

    int npos = tmp[pos];
    if (npos != -1)
      swap(c[pos], c[npos]);
  }

  void moveLeft(int n) {
    int pos = findBlankPosition(n);
    int tmp[] = {-1, -1, 1, 2, -1, 4, 5, 6, 7, -1, 9, 10, -1};

    int npos = tmp[pos];
    if (npos != -1)
      swap(c[pos], c[npos]);
  }

  void moveRight(int n) {
    int pos = findBlankPosition(n);
    int tmp[] = {-1, 2, 3, -1, 5, 6, 7, 8, -1, 10, 11, -1, -1};

    int npos = tmp[pos];
    if (npos != -1)
      swap(c[pos], c[npos]);
  }

  int findBlankPosition(int n) {
    for (int i = 0; i < SIZE; i++) {
      if (c[i] == 0)
        n--;
      if (n < 0)
        return i;
    }
    return -1;
  }

  bool operator<(const Puzzle &p) const {
    for (int i = 0; i < SIZE; i++)
      if (c[i] != p.c[i])
        return c[i] < p.c[i];
    return false;
  }
};

Puzzle puz;

bool input() {
  cin >> puz.c[0];
  if (puz.c[0] == -1)
    return false;
  for (int i = 1; i < SIZE; i++)
    cin >> puz.c[i];
  return true;
}

void solve() {
  map<Puzzle, int> M;
  M[puz] = 1;

  queue<Puzzle> Q;
  Q.push(puz);

  while (!Q.empty()) {
    Puzzle now = Q.front();
    Q.pop();

    for (int i = 0; i < 4; i++)
      for (int j = 0; j < 2; j++) {
        Puzzle nex = now;
        nex.move(i, j);
        if (M[nex] > M[now] + 1 || M[nex] == 0) {
          M[nex] = M[now] + 1;
          if (M[nex] <= 11)
            Q.push(nex);
        }
      }
  }

  Puzzle tmp;
  for (int i = 0; i < SIZE; i++)
    tmp.c[i] = i % (SIZE - 1);

  int ans = 25;
  Q.push(tmp);
  map<Puzzle, int> MG;
  MG[tmp] = 1;

  while (!Q.empty()) {
    Puzzle now = Q.front();
    Q.pop();
    if (M[now] != 0)
      ans = min(ans, M[now] + MG[now] - 2);
    for (int i = 0; i < 4; i++)
      for (int j = 0; j < 2; j++) {
        Puzzle nex = now;
        nex.move(i, j);

        if (MG[nex] > MG[now] + 1 || MG[nex] == 0) {
          MG[nex] = MG[now] + 1;
          if (MG[nex] <= 11)
            Q.push(nex);
        }
      }
  }
  if (ans <= 20)
    cout << ans << endl;
  else
    cout << "NA" << endl;
}

int main() {
  while (input())
    solve();
  return 0;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <map>
#include <queue>

using namespace std;

const int SIZE = 13;

struct Puzzle {
  short c[SIZE];

  void move(int d, int n) {
    if (d == 0)
      moveUp(n);
    if (d == 1)
      moveDown(n);
    if (d == 2)
      moveLeft(n);
    if (d == 3)
      moveRight(n);
  }
  // n = choosed blank number 0(first one) or 1(second one)
  void moveUp(int n) {
    int pos = findBlankPosition(n);
    int tmp[] = {-1, -1, 0, -1, -1, 1, 2, 3, -1, 5, 6, 7, 10};

    int npos = tmp[pos];
    if (npos != -1)
      swap(c[pos], c[npos]);
  }

  void moveDown(int n) {
    int pos = findBlankPosition(n);
    int tmp[] = {2, 5, 6, 7, -1, 9, 10, 11, -1, -1, 12, -1, -1};

    int npos = tmp[pos];
    if (npos != -1)
      swap(c[pos], c[npos]);
  }

  void moveLeft(int n) {
    int pos = findBlankPosition(n);
    int tmp[] = {-1, -1, 1, 2, -1, 4, 5, 6, 7, -1, 9, 10, -1};

    int npos = tmp[pos];
    if (npos != -1)
      swap(c[pos], c[npos]);
  }

  void moveRight(int n) {
    int pos = findBlankPosition(n);
    int tmp[] = {-1, 2, 3, -1, 5, 6, 7, 8, -1, 10, 11, -1, -1};

    int npos = tmp[pos];
    if (npos != -1)
      swap(c[pos], c[npos]);
  }

  int findBlankPosition(int n) {
    for (int i = 0; i < SIZE; i++) {
      if (c[i] == 0)
        n--;
      if (n < 0)
        return i;
    }
    return -1;
  }

  bool operator<(const Puzzle &p) const {
    for (int i = 0; i < SIZE; i++)
      if (c[i] != p.c[i])
        return c[i] < p.c[i];
    return false;
  }
};

Puzzle puz;

bool input() {
  cin >> puz.c[0];
  if (puz.c[0] == -1)
    return false;
  for (int i = 1; i < SIZE; i++)
    cin >> puz.c[i];
  return true;
}

void solve() {
  map<Puzzle, int> M;
  M[puz] = 1;

  queue<Puzzle> Q;
  Q.push(puz);

  while (!Q.empty()) {
    Puzzle now = Q.front();
    Q.pop();

    for (int i = 0; i < 4; i++)
      for (int j = 0; j < 2; j++) {
        Puzzle nex = now;
        nex.move(i, j);
        if (M[nex] > M[now] + 1 || M[nex] == 0) {
          M[nex] = M[now] + 1;
          if (M[nex] < 11)
            Q.push(nex);
        }
      }
  }

  Puzzle tmp;
  for (int i = 0; i < SIZE; i++)
    tmp.c[i] = i % (SIZE - 1);

  int ans = 25;
  Q.push(tmp);
  map<Puzzle, int> MG;
  MG[tmp] = 1;

  while (!Q.empty()) {
    Puzzle now = Q.front();
    Q.pop();
    if (M[now] != 0)
      ans = min(ans, M[now] + MG[now] - 2);
    for (int i = 0; i < 4; i++)
      for (int j = 0; j < 2; j++) {
        Puzzle nex = now;
        nex.move(i, j);

        if (MG[nex] > MG[now] + 1 || MG[nex] == 0) {
          MG[nex] = MG[now] + 1;
          if (MG[nex] <= 11)
            Q.push(nex);
        }
      }
  }
  if (ans <= 20)
    cout << ans << endl;
  else
    cout << "NA" << endl;
}

int main() {
  while (input())
    solve();
  return 0;
}