Problem p00190 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

struct S {
  vector<int> p;
  int t;
  S(vector<int> p, int t) : p(p), t(t) {}
};

bool operator<(const S &s, const S &t) { return s.t > t.t; }

int x[13] = {2, 1, 2, 3, 0, 1, 2, 3, 4, 1, 2, 3, 2};
int y[13] = {4, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 0};
vector<int> goal(13);
set<vector<int>> memo;
int distance(S s) {
  int count = 0;
  REP(i, 13) {
    if (s.p[i]) {
      count += abs(x[i] - x[s.p[i]]) + abs(y[i] - y[s.p[i]]);
    }
  }
  return count + s.t;
}
void print_s(S s) {
  vector<int> v = s.p;
  printf("time:%d\\n", s.t);
  printf("    %2d    \\n", v[0]);
  printf("  %2d%2d%2d  \\n", v[1], v[2], v[3]);
  printf("%2d%2d%2d%2d%2d\\n", v[4], v[5], v[6], v[7], v[8]);
  printf("  %2d%2d%2d  \\n", v[9], v[10], v[11]);
  printf("    %2d    \\n", v[12]);
}
int bfs(S start) {
  priority_queue<S> que;
  que.push(start);
  while (!que.empty()) {
    S s = que.top();
    que.pop();
    // print_s(s);
    if (s.t > 20)
      return -1;
    if (s.p == goal)
      return s.t;
    if (memo.find(s.p) != memo.end())
      continue;
    memo.insert(s.p);
    if (distance(s) > 20)
      continue;
    REP(i, 13) {
      vector<int> tmp = s.p;
      if (s.p[i] == 0) {
        switch (i) {
        case 0:
        case 2:
          swap(tmp[0], tmp[2]);
          que.push(S(tmp, s.t + 1));
          break;
        case 12:
        case 10:
          swap(tmp[12], tmp[10]);
          que.push(S(tmp, s.t + 1));
          break;
        case 4:
        case 5:
          swap(tmp[4], tmp[5]);
          que.push(S(tmp, s.t + 1));
          break;
        case 8:
        case 7:
          swap(tmp[8], tmp[7]);
          que.push(S(tmp, s.t + 1));
          break;
        }
        if (i % 4 == 2 || i % 4 == 3) {
          tmp = s.p;
          swap(tmp[i], tmp[i - 1]);
          que.push(S(tmp, s.t + 1));
        }
        if (i % 4 == 1 || i % 4 == 2) {
          tmp = s.p;
          swap(tmp[i], tmp[i + 1]);
          que.push(S(tmp, s.t + 1));
        }
        if (i % 4 != 0 && i < 8) {
          tmp = s.p;
          swap(tmp[i], tmp[i + 4]);
          que.push(S(tmp, s.t + 1));
        }
        if (i % 4 != 0 && i > 4) {
          tmp = s.p;
          swap(tmp[i], tmp[i - 4]);
          que.push(S(tmp, s.t + 1));
        }
      }
    }
  }
  return -1;
}
int main() {
  int n;
  vector<int> p(13);

  REP(i, 11) goal[i + 1] = i + 1;

  while (cin >> p[0], p[0] != -1) {
    for (int i = 1; i < 13; i++) {
      cin >> p[i];
    }
    S start(p, 0);
    memo.clear();
    int ans = bfs(start);
    if (ans == -1)
      cout << "NA" << endl;
    else
      cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

struct S {
  vector<int> p;
  int t;
  S(vector<int> p, int t) : p(p), t(t) {}
};

bool operator<(const S &s, const S &t) { return s.t > t.t; }
int x[13] = {2, 1, 2, 3, 0, 1, 2, 3, 4, 1, 2, 3, 2};
int y[13] = {4, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 0};
int distance(S s) {
  int ret = 0;
  REP(i, 13) {
    if (s.p[i]) {
      ret = max(ret, abs(x[i] - x[s.p[i]]) + abs(y[i] - y[s.p[i]]));
    }
  }
  return ret + s.t;
}
void print_s(S s) {
  vector<int> v = s.p;
  printf("time:%d\\n", s.t);
  printf("    %2d    \\n", v[0]);
  printf("  %2d%2d%2d  \\n", v[1], v[2], v[3]);
  printf("%2d%2d%2d%2d%2d\\n", v[4], v[5], v[6], v[7], v[8]);
  printf("  %2d%2d%2d  \\n", v[9], v[10], v[11]);
  printf("    %2d    \\n", v[12]);
}

set<vector<int>> memo;
vector<int> goal(13);
int bfs(S start) {
  priority_queue<S> que;
  que.push(start);
  while (!que.empty()) {
    S s = que.top();
    que.pop();
    // print_s(s);
    if (s.t > 20)
      return -1;
    if (s.p == goal)
      return s.t;
    if (memo.find(s.p) != memo.end())
      continue;
    memo.insert(s.p);
    if (distance(s) > 20)
      continue;
    REP(i, 13) {
      vector<int> tmp = s.p;
      if (s.p[i] == 0) {
        switch (i) {
        case 0:
        case 2:
          swap(tmp[0], tmp[2]);
          que.push(S(tmp, s.t + 1));
          break;
        case 12:
        case 10:
          swap(tmp[12], tmp[10]);
          que.push(S(tmp, s.t + 1));
          break;
        case 4:
        case 5:
          swap(tmp[4], tmp[5]);
          que.push(S(tmp, s.t + 1));
          break;
        case 8:
        case 7:
          swap(tmp[8], tmp[7]);
          que.push(S(tmp, s.t + 1));
          break;
        }
        if (i % 4 == 2 || i % 4 == 3) {
          tmp = s.p;
          swap(tmp[i], tmp[i - 1]);
          que.push(S(tmp, s.t + 1));
        }
        if (i % 4 == 1 || i % 4 == 2) {
          tmp = s.p;
          swap(tmp[i], tmp[i + 1]);
          que.push(S(tmp, s.t + 1));
        }
        if (i % 4 != 0 && i < 8) {
          tmp = s.p;
          swap(tmp[i], tmp[i + 4]);
          que.push(S(tmp, s.t + 1));
        }
        if (i % 4 != 0 && i > 4) {
          tmp = s.p;
          swap(tmp[i], tmp[i - 4]);
          que.push(S(tmp, s.t + 1));
        }
      }
    }
  }
}
int main() {
  int n;
  vector<int> p(13);

  REP(i, 11) goal[i + 1] = i + 1;

  while (cin >> p[0], p[0] != -1) {
    for (int i = 1; i < 13; i++) {
      cin >> p[i];
    }
    S start(p, 0);
    memo.clear();
    int ans = bfs(start);
    if (ans == -1)
      cout << "NA" << endl;
    else
      cout << ans << endl;
  }
  return 0;
}