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

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

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef pair<int, int> pii;

const int INF = 1 << 29;
const double EPS = 1e-9;

const int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};

const int boardw = 4;

struct BOARD {
  int map[boardw][boardw];
};

bool check(BOARD &b) {
  for (int i = 0; i < boardw; ++i) {
    for (int j = 0; j < boardw; ++j) {
      if (b.map[i][j] == 0)
        continue;
      int tgt = i * boardw + j + 1;
      if (b.map[i][j] != tgt) {
        return false;
      }
    }
  }
  return true;
}

int dfs(BOARD &b, int depth, int dir) {
  if (depth == 0) {
    if (check(b)) {
      return 1;
    } else {
      return -1;
    }
  }

  int px, py;
  for (int i = 0; i < boardw; ++i) {
    for (int j = 0; j < boardw; ++j) {
      if (b.map[i][j] == 0) {
        px = j;
        py = i;
      }
    }
  }
  int est = 0;
  for (int i = 0; i < boardw; ++i) {
    for (int j = 0; j < boardw; ++j) {
      if (i * j == boardw * boardw)
        continue;
      for (int k = 0; k < boardw; ++k) {
        for (int l = 0; l < boardw; ++l) {
          if (i * boardw + j + 1 == b.map[k][l]) {
            est += std::abs(k - i) + std::abs(l - j);
          }
        }
      }
    }
  }
  if (est > depth) {
    return -1;
  }
  int dx[] = {0, 1, 0, -1};
  int dy[] = {1, 0, -1, 0};
  for (int k = 0; k < 4; k++) {
    if (dir != -1 && k == (dir + 2) % 4) {
      continue;
    }
    int tx = px + dx[k];
    int ty = py + dy[k];
    if (tx < 0 || tx >= boardw || ty < 0 || ty >= boardw)
      continue;
    int temp = b.map[py][px];
    b.map[py][px] = b.map[ty][tx];
    b.map[ty][tx] = temp;

    int ret = dfs(b, depth - 1, k);

    temp = b.map[py][px];
    b.map[py][px] = b.map[ty][tx];
    b.map[ty][tx] = temp;
    if (ret != -1)
      return ret;
  }
  return -1;
}

int main(int argc, char const *argv[]) {
  BOARD b;
  for (int i = 0; i < boardw; ++i) {
    for (int j = 0; j < boardw; ++j) {
      cin >> b.map[i][j];
    }
  }
  if (check(b)) {
    cout << 0 << endl;
    return 0;
  }
  int i = 0;
  while (++i) {
    int ret = dfs(b, i, -1);
    if (ret == 1) {
      cout << i << endl;
      return 0;
    }
  }

  return 0;
}

Error: 0

Fixed submission:

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

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef pair<int, int> pii;

const int INF = 1 << 29;
const double EPS = 1e-9;

const int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};

struct BOARD {
  int turn;
  int map[4][4];
  bool operator<(const BOARD &rhs) const {
    for (int i = 0; i < 4; i++) {
      for (int j = 0; j < 4; ++j) {
        if (this->map[i][j] < rhs.map[i][j]) {
          return true;
        }
      }
    }
    return false;
  }
};

std::queue<BOARD> q;
std::map<BOARD, int> m;

bool check(BOARD b) {
  for (int i = 0; i < 4; ++i) {
    for (int j = 0; j < 4; ++j) {
      if (b.map[i][j] == 0)
        continue;
      int tgt = i * 4 + j + 1;
      if (b.map[i][j] != tgt) {
        return false;
      }
    }
  }
  return true;
}

int main(int argc, char const *argv[]) {
  BOARD b;
  for (int i = 0; i < 4; ++i) {
    for (int j = 0; j < 4; ++j) {
      cin >> b.map[i][j];
    }
  }
  b.turn = 0;
  q.push(b);
  while (!q.empty()) {
    BOARD nowB;
    nowB = q.front();
    q.pop();

    if (check(nowB)) {
      cout << nowB.turn << endl;
      return 0;
    }

    int px, py;

    for (int i = 0; i < 4; ++i) {
      for (int j = 0; j < 4; ++j) {
        if (nowB.map[i][j] == 0) {
          px = j;
          py = i;
        }
      }
    }
    int dx[] = {0, 1, 0, -1};
    int dy[] = {1, 0, -1, 0};
    for (int k = 0; k < 4; ++k) {
      int tx = px + dx[k];
      int ty = py + dy[k];
      if (tx < 0 || tx >= 4 || ty < 0 || ty >= 4)
        continue;

      BOARD newB;
      for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
          newB.map[i][j] = nowB.map[i][j];
        }
      }
      newB.turn = nowB.turn + 1;

      int temp = newB.map[py][px];
      newB.map[py][px] = newB.map[ty][tx];
      newB.map[ty][tx] = temp;
      if (m.find(newB) == m.end()) {
        m[newB] = 1;

        int est = 0;
        for (int i = 0; i < 4; ++i) {
          for (int j = 0; j < 4; ++j) {
            int tgt = i * 4 + j + 1;
            for (int k = 0; k < 4; k++) {
              for (int l = 0; l < 4; l++) {
                if (newB.map[k][l] == tgt) {
                  est += std::abs(k - i) + std::abs(l - j);
                }
              }
            }
          }
        }
        if (newB.turn + est / 2 - 1 <= 45) {
          q.push(newB);
        }
      }
    }
  }

  return 0;
}