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

// ALDS1_13_B.cpp
// Heuristic Search - 8 Puzzle
// ????????¨?????????24????????±??????????????????
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

const int N = 3;
const int N2 = 9;
const int INF = 40;
struct Puzzle {
  int f[N2];
  // int space;
  string path;

  bool operator<(const Puzzle &p) const {
    for (int i = 0; i < N2; i++) {
      if (f[i] == p.f[i])
        continue;
      return f[i] > p.f[i];
    }
    return false;
  }
};

static const int dx[4] = {-1, 0, 1, 0};
static const int dy[4] = {0, -1, 0, 1};
static const char dir[4] = {'u', 'l', 'd', 'r'};
map<Puzzle, bool> ms;
Puzzle in;
int ministep = INF;
int sx = 0;
int sy = 0;

void swap(int &a, int &b) {
  int t = a;
  a = b;
  b = t;
}

bool isTarget(Puzzle p) {
  for (int i = 0; i < N2; i++) {
    if (p.f[i] != i + 1)
      return false;
  }
  return true;
}

int getAllMD(Puzzle p) {
  int dist = 0;
  int x, y;
  int ux, uy;
  for (int i = 0; i < N2; i++) {
    if (p.f[i] == N2)
      continue; // ??????0??????
    x = (p.f[i] - 1) / N;
    y = (p.f[i] - 1) % N;
    ux = i / N;
    uy = i % N;
    dist += abs(x - ux) + abs(y - uy);
  }
  return dist;
}

void bfs(int i) {
  if (isTarget(in)) {
    ministep = min(ministep, i);
    //        cout << "ministep = " << ministep << endl;
    return;
  }
  if (ms[in] || ministep < i + getAllMD(in)) {
    return;
  }

  ms[in] = true;
  for (int u = 0; u < 4; u++) {
    int tx = sx + dx[u];
    int ty = sy + dy[u];
    if (tx < 0 || tx >= N || ty < 0 || ty >= N)
      continue;
    swap(in.f[sx * N + sy], in.f[tx * N + ty]);
    sx = tx;
    sy = ty;
    in.path += dir[u];
    /* test */
    //    cout << "(i = " << i << ") " << in.path << endl;
    //    for (int j = 0; j < N2; j++)
    //        cout << " " << in.f[j];
    //    cout << endl;
    //    cout << "MD: " << getAllMD(in) << endl;
    bfs(i + 1);
    sx = sx - dx[u];
    sy = sy - dy[u];
    swap(in.f[sx * N + sy], in.f[tx * N + ty]);
    in.path.pop_back();
  }
  ms[in] = false;
}

int main() {
  //    freopen("in.txt", "r", stdin);
  //    freopen("out.txt", "w", stdout);

  for (int i = 0; i < N2; i++) {
    cin >> in.f[i];
    if (in.f[i] == 0) {
      sx = i / N;
      sy = i % N;
      in.f[i] = 9; // ??????isTarget?????????
    }
  }
  bfs(0);
  cout << ministep << endl;
  return 0;
}

Error: TLE

Fixed submission:

// ALDS1_13_B.cpp
// Heuristic Search - 8 Puzzle
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

const int N = 3;
const int N2 = 9;
const int INF = 25;
struct Puzzle {
  int f[N2];
  // int space;
  string path;

  bool operator<(const Puzzle &p) const {
    for (int i = 0; i < N2; i++) {
      if (f[i] == p.f[i])
        continue;
      return f[i] > p.f[i];
    }
    return false;
  }
};
static const int dx[4] = {-1, 0, 1, 0};
static const int dy[4] = {0, -1, 0, 1};
static const char dir[4] = {'u', 'l', 'd', 'r'};
map<Puzzle, bool> ms;
Puzzle in;
int ministep = INF;
int sx = 0;
int sy = 0;

bool isTarget(Puzzle p) {
  for (int i = 0; i < N2; i++) {
    if (p.f[i] != i + 1)
      return false;
  }
  return true;
}

void swap(int &a, int &b) {
  int t = a;
  a = b;
  b = t;
}

void bfs(int i) {
  if (isTarget(in)) {
    ministep = min(ministep, i);
    //        cout << "ministep = " << ministep << endl;
    return;
  }
  if (ms[in] || ministep < i) {
    return;
  }

  if (in.path == "ldrd")
    int debug = 0;
  ms[in] = true;
  for (int u = 0; u < 4; u++) {
    int tx = sx + dx[u];
    int ty = sy + dy[u];
    if (tx < 0 || tx >= N || ty < 0 || ty >= N)
      continue;
    swap(in.f[sx * N + sy], in.f[tx * N + ty]);
    sx = tx;
    sy = ty;
    in.path += dir[u];
    /* test */
    //    cout << "(i = " << i << ") " << in.path << endl;
    //    for (int j = 0; j < N2; j++)
    //        cout << " " << in.f[j];
    //    cout << endl;
    bfs(i + 1);
    sx = sx - dx[u];
    sy = sy - dy[u];
    swap(in.f[sx * N + sy], in.f[tx * N + ty]);
    in.path.pop_back();
  }
  ms[in] = false;
}

int main() {
  //    freopen("in.txt", "r", stdin);
  //    freopen("out.txt", "w", stdout);

  for (int i = 0; i < N2; i++) {
    cin >> in.f[i];
    if (in.f[i] == 0) {
      sx = i / N;
      sy = i % N;
      in.f[i] = 9; // ??????isTarget?????????
    }
  }
  bfs(0);
  cout << ministep << endl;
  return 0;
}