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

#include <cstdlib>
#include <iostream>
#include <stack>
#include <vector>
#define N 4
#define N2 16
#define MAX_DEPTH 45
using namespace std;

class game {
public:
  int board[N2];
  int w;
  int last_move;
  int depth;
  int mnh;
};
game start;

vector<int> move_list[N2];
int dist[N2][N2];

void print(game &g) {
  for (int i = 0; i < N2; i++) {
    printf(" %d", g.board[i]);
  }
  cout << " mnh: " << g.mnh << endl;
}

bool dfs(int depth) {
  stack<game> s;
  s.push(start);

  game g;
  while (!s.empty()) {
    g = s.top();
    s.pop();
    if (g.mnh == 0)
      return true;
    if (g.depth == depth)
      continue;
    if (g.depth + g.mnh > depth)
      continue;

    for (int move : move_list[g.w]) {
      if (g.last_move == -move)
        continue;
      game h = g;
      int to = h.w + move;
      h.mnh -= dist[to][h.board[to] - 1];
      h.mnh += dist[h.w][h.board[to] - 1];
      swap(h.board[h.w], h.board[to]);
      h.w = to;
      h.depth++;
      h.last_move = move;
      s.push(h);
    }
  }
  return false;
}

void initialize() {
  for (int i = 0; i < N2; i++) {
    if (i % N < N - 1)
      move_list[i].push_back(1);
    if (i % N > 0)
      move_list[i].push_back(-1);
    if (i / N < N - 1)
      move_list[i].push_back(N);
    if (i / N > 0)
      move_list[i].push_back(-N);
  }

  // i=board,j=piece-1
  for (int i = 0; i < N2; i++) {
    for (int j = 0; j < N2; j++) {
      dist[i][j] = abs(j % N - i % N) + abs(j / N - i / N);
    }
  }

  start.mnh = 0;
  for (int i = 0; i < N2; i++) {
    if (i == start.w)
      continue;
    start.mnh += dist[i][start.board[i] - 1];
  }
}

int solve() {
  initialize();
  for (int i = start.mnh; i <= MAX_DEPTH; i++) {
    if (dfs(i)) {
      return i;
    }
  }
  return -1;
}

int main() {
  for (int i = 0; i < N2; i++) {
    int tmp;
    cin >> tmp;
    if (tmp == 0) {
      start.board[i] = N2;
      start.w = i;
    } else {
      start.board[i] = tmp;
    }
  }
  start.depth = 0;
  start.last_move = 0;

  cout << solve() << endl;
}

Error: TLE

Fixed submission:

#include <cstdlib>
#include <iostream>
#include <stack>
#include <vector>
#define N 4
#define N2 16
#define MAX_DEPTH 45
using namespace std;

class game {
public:
  int board[N2];
  int w;
  int last_move;
  int depth;
  int mnh;
};
game start;

vector<int> move_list[N2];
int dist[N2][N2];

void print(game &g) {
  for (int i = 0; i < N2; i++) {
    printf(" %d", g.board[i]);
  }
  cout << " mnh: " << g.mnh << endl;
}

bool dfs(int depth) {
  stack<game> s;
  s.push(start);

  game g;
  while (!s.empty()) {
    g = s.top();
    s.pop();
    if (g.mnh == 0)
      return true;
    if (g.depth == depth)
      continue;
    if (g.depth + g.mnh > MAX_DEPTH)
      continue;

    for (int move : move_list[g.w]) {
      if (g.last_move == -move)
        continue;
      game h = g;
      int to = h.w + move;
      h.mnh -= dist[to][h.board[to] - 1];
      h.mnh += dist[h.w][h.board[to] - 1];
      swap(h.board[h.w], h.board[to]);
      h.w = to;
      h.depth++;
      h.last_move = move;
      s.push(h);
    }
  }
  return false;
}

void initialize() {
  for (int i = 0; i < N2; i++) {
    if (i % N < N - 1)
      move_list[i].push_back(1);
    if (i % N > 0)
      move_list[i].push_back(-1);
    if (i / N < N - 1)
      move_list[i].push_back(N);
    if (i / N > 0)
      move_list[i].push_back(-N);
  }

  // i=board,j=piece-1
  for (int i = 0; i < N2; i++) {
    for (int j = 0; j < N2; j++) {
      dist[i][j] = abs(j % N - i % N) + abs(j / N - i / N);
    }
  }

  start.mnh = 0;
  for (int i = 0; i < N2; i++) {
    if (i == start.w)
      continue;
    start.mnh += dist[i][start.board[i] - 1];
  }
}

int solve() {
  initialize();
  for (int i = start.mnh; i < MAX_DEPTH; i++) {
    if (dfs(i)) {
      return i;
    }
  }
  return -1;
}

int main() {
  for (int i = 0; i < N2; i++) {
    int tmp;
    cin >> tmp;
    if (tmp == 0) {
      start.board[i] = N2;
      start.w = i;
    } else {
      start.board[i] = tmp;
    }
  }
  start.depth = 0;
  start.last_move = 0;

  cout << solve() << endl;
}