Problem p02246 (C++) — buggy submission, verdict: Runtime Error

#include <array>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stdio.h>
#include <utility>

struct Status {
  std::array<int, 16> board;
  int distance{}, h{}, empty{};
  bool operator>(const Status &) const;
};

bool Status::operator>(const Status &tmp) const {
  return this->distance + this->h > tmp.distance + tmp.h;
}

void shift_empty(Status &, int);

int main() {
  Status start;
  for (int i{}; i < 16; i++) {
    scanf("%d", &start.board[i]);
    start.board[i]--;
    if (start.board[i] >= 0)
      start.h += std::abs(start.board[i] % 4 - i % 4) +
                 std::abs(start.board[i] / 4 - i / 4);
    else
      start.empty = i;
  }
  std::priority_queue<Status, std::vector<Status>, std::greater<Status>> pq;
  std::set<std::array<int, 16>> done;
  pq.push(start);

  while (!pq.empty()) {
    Status min{pq.top()};
    pq.pop();
    if (done.find(min.board) != done.end())
      continue;
    done.insert(min.board);
    if (min.h == 0) {
      printf("%d\\n", min.distance);
      break;
    }
    min.distance++;
    if (min.empty % 4) {
      shift_empty(min, 0);
      auto next{done.find(min.board)};
      if (min.distance + min.h <= 45 && done.find(min.board) == done.end())
        pq.push(min);
      shift_empty(min, 2);
    }
    if (min.empty % 4 < 3) {
      shift_empty(min, 2);
      auto next{done.find(min.board)};
      if (min.distance + min.h <= 45 && done.find(min.board) == done.end())
        pq.push(min);
      shift_empty(min, 0);
    }
    if (min.empty >= 4) {
      shift_empty(min, 1);
      auto next{done.find(min.board)};
      if (min.distance + min.h <= 45 && done.find(min.board) == done.end())
        pq.push(min);
      shift_empty(min, 3);
    }
    if (min.empty < 12) {
      shift_empty(min, 3);
      auto next{done.find(min.board)};
      if (min.distance + min.h <= 45 && done.find(min.board) == done.end())
        pq.push(min);
      shift_empty(min, 1);
    }
  }
  return 0;
}

void shift_empty(Status &tmp, int com) {
  const int dir[4]{-1, -4, 1, 4};
  std::swap(tmp.board[tmp.empty], tmp.board[tmp.empty + dir[com]]);
  tmp.empty += dir[com];
  tmp.h = 0;
  for (int i{}; i < 16; i++)
    if (i != tmp.empty)
      tmp.h += std::abs(tmp.board[i] % 4 - i % 4) +
               std::abs(tmp.board[i] / 4 - i / 4);
  return;
}


Error: 0

Fixed submission:

#include <array>
#include <iostream>
#include <vector>

struct Board {
  std::array<int, 16> arrange{};
  int zero_pos;
  int distance;
  int pre_dir;
};

int search(Board);
bool equal_goal(std::array<int, 16>);

int main() {
  Board board;
  for (int i = 0; i < 16; ++i) {
    std::cin >> board.arrange[i];
    if (!board.arrange[i])
      board.zero_pos = i;
  }
  board.distance = 0;
  board.pre_dir = -1;
  std::cout << search(board) << std::endl;

  return 0;
}

int search(Board start) {
  if (equal_goal(start.arrange))
    return 0;

  std::vector<Board> queue;
  queue.push_back(start);

  int move_dir[4] = {-4, -1, 4, 1};
  for (int queue_i = 0;; ++queue_i) {
    int zero_pos = queue[queue_i].zero_pos;
    bool can_move[4] = {zero_pos / 4 != 0, zero_pos % 4 != 0, zero_pos / 4 != 3,
                        zero_pos % 4 != 3};
    for (int dir_i = 0; dir_i < 4; ++dir_i) {
      if ((dir_i + 2) % 4 == queue[queue_i].pre_dir || !can_move[dir_i])
        continue;

      Board board = queue[queue_i];
      int next_zero_pos = zero_pos + move_dir[dir_i];
      board.arrange[zero_pos] = board.arrange[next_zero_pos];
      board.arrange[next_zero_pos] = 0;
      board.zero_pos = next_zero_pos;
      board.distance++;
      board.pre_dir = dir_i;

      if (equal_goal(board.arrange))
        return board.distance;
      queue.push_back(board);
    }
  }
  return -1;
}

bool equal_goal(std::array<int, 16> arrange) {
  for (int i = 0; i < 15; ++i)
    if (arrange[i] != i + 1)
      return false;
  if (arrange[15] != 0)
    return false;

  return true;
}