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

#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

#define REP(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) REP(i, 0, n)
#define DEB 0

int board[7][7]; // 1base
int sx[2], sy[2];
static const int dx[] = {0, 0, 1, -1};
static const int dy[] = {1, -1, 0, 0};

int calc(int y, int x) {
  switch (board[y][x]) {
  case 1:
    return abs(2 - y) + abs(2 - x);
  case 2:
    return abs(2 - y) + abs(3 - x);
  case 3:
    return abs(2 - y) + abs(4 - x);
  case 4:
    return abs(3 - y) + abs(1 - x);
  case 5:
    return abs(3 - y) + abs(2 - x);
  case 6:
    return abs(3 - y) + abs(3 - x);
  case 7:
    return abs(3 - y) + abs(4 - x);
  case 8:
    return abs(3 - y) + abs(5 - x);
  case 9:
    return abs(4 - y) + abs(2 - x);
  case 10:
    return abs(4 - y) + abs(3 - x);
  case 11:
    return abs(4 - y) + abs(4 - x);
  }
  return -1;
}
int dist(void) {
  int ret = 0;
  if (board[1][3])
    ret += calc(1, 3);
  rep(i, 3) if (board[2][2 + i]) ret += calc(2, 2 + i);
  rep(i, 5) if (board[3][1 + i]) ret += calc(3, 1 + i);
  rep(i, 3) if (board[4][2 + i]) ret += calc(4, 2 + i);
  if (board[5][3])
    ret += calc(5, 3);
  return ret;
}
bool isgoal(void) {
  if (board[1][3] != 0)
    return false;
  rep(i, 3) if (board[2][2 + i] != i + 1) return false;
  rep(i, 5) if (board[3][1 + i] != i + 4) return false;
  rep(i, 3) if (board[4][2 + i] != i + 9) return false;
  if (board[5][3] != 0)
    return false;
  return true;
}

bool dfs(int cnt, int LIM, int py, int px, const vector<pair<int, int>> sp) {
  if (isgoal())
    return true;
  if (cnt + dist() > LIM)
    return false;

  rep(i, 2) {
    if (board[sp[i].second][sp[i].first] != 0)
      exit(-1);
    rep(k, 4) {
      int tx = sp[i].first + dx[k];
      int ty = sp[i].second + dy[k];
      if (board[ty][tx] <= 0)
        continue;

      swap(board[sp[i].second][sp[i].first], board[ty][tx]);

      vector<pair<int, int>> v = sp;
      pair<int, int> tmp(tx, ty);
      swap(v[i], tmp);
      if (dfs(cnt + 1, LIM, ty, tx, v))
        return true;

      swap(board[sp[i].second][sp[i].first], board[ty][tx]);
    }
  }
  return false;
}
int solve(void) {
  int ttx[2], tty[2];
  int tb[7][7];
  vector<pair<int, int>> sp;
  rep(i, 2) sp.push_back(make_pair(sx[i], sy[i]));
  rep(i, 7) rep(j, 7) tb[i][j] = board[i][j];

  for (int lim = 0; lim < 21; lim++) {
    if (dfs(0, lim, -1, -1, sp))
      return lim;
    // rep(i,7)rep(j,7)if( board[i][j]!=tb[i][j] ) puts("ugeeeee");
  }
  return -1;
}
int main() {
  for (;;) {
    memset(board, -1, sizeof(board));
    int sz = 0;

    scanf("%d", &board[1][3]);
    if (board[1][3] == -1)
      break;
    rep(i, 3) scanf("%d", &board[2][2 + i]);
    rep(i, 5) scanf("%d", &board[3][1 + i]);
    rep(i, 3) scanf("%d", &board[4][2 + i]);
    scanf("%d", &board[5][3]);

    // find space
    if (board[1][3] == 0) {
      sx[sz] = 3;
      sy[sz] = 1;
      sz++;
    }
    rep(i, 3) if (board[2][2 + i] == 0) {
      sx[sz] = 2 + i;
      sy[sz] = 2;
      sz++;
    }
    rep(i, 5) if (board[3][1 + i] == 0) {
      sx[sz] = 1 + i;
      sy[sz] = 3;
      sz++;
    }
    rep(i, 3) if (board[4][2 + i] == 0) {
      sx[sz] = 2 + i;
      sy[sz] = 4;
      sz++;
    }
    if (board[5][3] == 0) {
      sx[sz] = 3;
      sy[sz] = 5;
      sz++;
    }

    // printf("hoge:%d\\n",dist());
    int ans = solve();
    if (ans != -1)
      printf("%d\\n", ans);
    else
      puts("NA");
  }
  return 0;
}

/*

//-------------------------------------------------------

#define N 5
#define REP(i, n) for ( int i = 0; i < (int)n; i++ )
#define LIMIT 20

static const int T[12][2] = {
    {-1, -1},
    {1, 1},
    {1, 2},
    {1, 3},
    {2, 0},
    {2, 1},
    {2, 2},
    {2, 3},
    {2, 4},
    {3, 1},
    {3, 2},
    {3, 3}
};
static const int g[N][N] = {
    {-1,-1, 0,-1,-1},
    {-1, 1, 2, 3,-1},
    { 4, 5, 6, 7, 8},
    {-1, 9,10,11,-1},
    {-1,-1, 0,-1,-1}
};

class Puzzle{
public:
    int C[N][N], mdist; //manhatta distance
    Puzzle(){}

    bool swapAdj( int si, int sj, int ti, int tj ){
        if ( ti < 0 || tj < 0 || ti >= N || tj >= N ) return false;
        if ( C[ti][tj] <= 0 ) return false;
        swap(C[ti][tj], C[si][sj]);
        int tti = T[C[si][sj]][0];
        int ttj = T[C[si][sj]][1];
        //mdist -= max(tti, ti)-min(tti, ti) + max(ttj, tj)-min(ttj, tj);
        //mdist += max(tti, si)-min(tti, si) + max(ttj, sj)-min(ttj, sj);
        //mdist -= abs(tti-ti)+abs(ttj-tj);
        //mdist += abs(tti-si)+abs(ttj-sj);
        return true;
    }

    bool isGoal(){
        REP(i, N) REP(j, N) if ( g[i][j] != C[i][j] ) return false;
        return true;
    }

    int getMD(){ // get initial manhattan distance
        int sum = 0;
        int ti, tj;
        REP(i, 5) REP(j, 5){
            if ( C[i][j] <= 0 ) continue;
            ti = T[C[i][j]][0];
            tj = T[C[i][j]][1];
            //sum += (max(ti, i)-min(ti, i) + max(tj, j) - min(tj, j));
            sum += abs(ti-i) + abs(tj-j);
        }
        return sum;
    }
};

int limit;

bool dfs( int depth, Puzzle P ){
    if ( P.isGoal() ) return true;
    if ( depth + P.getMD() > limit ) return false;

    static const int di[4] = {0, -1, 0, 1};
    static const int dj[4] = {1, 0, -1, 0};

    REP(i, N) REP(j, N){
        if ( P.C[i][j] != 0 ) continue;
        REP(r, 4){
            Puzzle v = P;
            if ( !v.swapAdj(i, j, i+di[r], j+dj[r]) ) continue;
            if ( dfs( depth + 1, v ) ) return true;
        }
    }

    return false;
}

int idp(Puzzle source){
    for ( limit = 0; limit <= LIMIT; limit++ ){
        //source.mdist = source.getMD();
        if ( dfs(0, source) ) return limit;
    }
    return INT_MAX;
}

int main(){
    Puzzle P;
    int top;

    while(1){
        cin >> top;
        if ( top == -1 ) break;
        REP(j, N) P.C[0][j] = -1;
        P.C[0][2] = top;
        for(int i = 1; i < N; i++) REP(j, N){
                if ( (i == 1 || i == 3) && (j == 0 || j == 4 ) ) P.C[i][j] = -1;
                else if ( i == 4 && j != 2 ) P.C[i][j] = -1;
                else cin >> P.C[i][j];
            }

        int cost = idp(P);
        if ( cost == INT_MAX ) cout << "NA" << endl;
        else cout << cost << endl;
    }

    return 0;
}

*/

Error: 0

Fixed submission:

#include <algorithm>
#include <climits>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

#define REP(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) REP(i, 0, n)
#define DEB 0

int board[7][7]; // 1base
int sx[2], sy[2];
static const int dx[] = {0, 0, 1, -1};
static const int dy[] = {1, -1, 0, 0};

int calc(int y, int x) {
  switch (board[y][x]) {
  case 1:
    return abs(2 - y) + abs(2 - x);
  case 2:
    return abs(2 - y) + abs(3 - x);
  case 3:
    return abs(2 - y) + abs(4 - x);
  case 4:
    return abs(3 - y) + abs(1 - x);
  case 5:
    return abs(3 - y) + abs(2 - x);
  case 6:
    return abs(3 - y) + abs(3 - x);
  case 7:
    return abs(3 - y) + abs(4 - x);
  case 8:
    return abs(3 - y) + abs(5 - x);
  case 9:
    return abs(4 - y) + abs(2 - x);
  case 10:
    return abs(4 - y) + abs(3 - x);
  case 11:
    return abs(4 - y) + abs(4 - x);
  }
  return -1;
}
int dist(void) {
  int ret = 0;
  if (board[1][3])
    ret += calc(1, 3);
  rep(i, 3) if (board[2][2 + i]) ret += calc(2, 2 + i);
  rep(i, 5) if (board[3][1 + i]) ret += calc(3, 1 + i);
  rep(i, 3) if (board[4][2 + i]) ret += calc(4, 2 + i);
  if (board[5][3])
    ret += calc(5, 3);
  return ret;
}
bool isgoal(void) {
  if (board[1][3] != 0)
    return false;
  rep(i, 3) if (board[2][2 + i] != i + 1) return false;
  rep(i, 5) if (board[3][1 + i] != i + 4) return false;
  rep(i, 3) if (board[4][2 + i] != i + 9) return false;
  if (board[5][3] != 0)
    return false;
  return true;
}

bool dfs(int cnt, int LIM, int py, int px, vector<pair<int, int>> sp) {
  if (isgoal())
    return true;
  if (cnt + dist() > LIM)
    return false;

  rep(i, 2) {
    if (board[sp[i].second][sp[i].first] != 0)
      exit(-1);
    rep(k, 4) {
      int tx = sp[i].first + dx[k];
      int ty = sp[i].second + dy[k];
      if (board[ty][tx] == -1 || tx == px && ty == py)
        continue;

      swap(board[sp[i].second][sp[i].first], board[ty][tx]);

      vector<pair<int, int>> v = sp;
      pair<int, int> tmp(tx, ty);
      swap(v[i], tmp);
      if (dfs(cnt + 1, LIM, ty, tx, v))
        return true;

      swap(board[sp[i].second][sp[i].first], board[ty][tx]);
    }
  }
  return false;
}
int solve(void) {
  int ttx[2], tty[2];
  // int tb[7][7];
  vector<pair<int, int>> sp;
  rep(i, 2) sp.push_back(make_pair(sx[i], sy[i]));
  // rep(i,7)rep(j,7) tb[i][j] = board[i][j];

  for (int lim = 0; lim < 21; lim++) {
    if (dfs(0, lim, -1, -1, sp))
      return lim;
  }
  return -1;
}
int main() {
  for (;;) {
    memset(board, -1, sizeof(board));
    int sz = 0;

    scanf("%d", &board[1][3]);
    if (board[1][3] == -1)
      break;
    rep(i, 3) scanf("%d", &board[2][2 + i]);
    rep(i, 5) scanf("%d", &board[3][1 + i]);
    rep(i, 3) scanf("%d", &board[4][2 + i]);
    scanf("%d", &board[5][3]);

    // find space
    if (board[1][3] == 0) {
      sx[sz] = 3;
      sy[sz] = 1;
      sz++;
    }
    rep(i, 3) if (board[2][2 + i] == 0) {
      sx[sz] = 2 + i;
      sy[sz] = 2;
      sz++;
    }
    rep(i, 5) if (board[3][1 + i] == 0) {
      sx[sz] = 1 + i;
      sy[sz] = 3;
      sz++;
    }
    rep(i, 3) if (board[4][2 + i] == 0) {
      sx[sz] = 2 + i;
      sy[sz] = 4;
      sz++;
    }
    if (board[5][3] == 0) {
      sx[sz] = 3;
      sy[sz] = 5;
      sz++;
    }

    // printf("hoge:%d\\n",dist());
    int ans = solve();
    if (ans != -1)
      printf("%d\\n", ans);
    else
      puts("NA");
  }
  return 0;
}

/*

//-------------------------------------------------------

#define N 5
#define REP(i, n) for ( int i = 0; i < (int)n; i++ )
#define LIMIT 20

static const int T[12][2] = {
    {-1, -1},
    {1, 1},
    {1, 2},
    {1, 3},
    {2, 0},
    {2, 1},
    {2, 2},
    {2, 3},
    {2, 4},
    {3, 1},
    {3, 2},
    {3, 3}
};
static const int g[N][N] = {
    {-1,-1, 0,-1,-1},
    {-1, 1, 2, 3,-1},
    { 4, 5, 6, 7, 8},
    {-1, 9,10,11,-1},
    {-1,-1, 0,-1,-1}
};

class Puzzle{
public:
    int C[N][N], mdist; //manhatta distance
    Puzzle(){}

    bool swapAdj( int si, int sj, int ti, int tj ){
        if ( ti < 0 || tj < 0 || ti >= N || tj >= N ) return false;
        if ( C[ti][tj] <= 0 ) return false;
        swap(C[ti][tj], C[si][sj]);
        int tti = T[C[si][sj]][0];
        int ttj = T[C[si][sj]][1];
        //mdist -= max(tti, ti)-min(tti, ti) + max(ttj, tj)-min(ttj, tj);
        //mdist += max(tti, si)-min(tti, si) + max(ttj, sj)-min(ttj, sj);
        //mdist -= abs(tti-ti)+abs(ttj-tj);
        //mdist += abs(tti-si)+abs(ttj-sj);
        return true;
    }

    bool isGoal(){
        REP(i, N) REP(j, N) if ( g[i][j] != C[i][j] ) return false;
        return true;
    }

    int getMD(){ // get initial manhattan distance
        int sum = 0;
        int ti, tj;
        REP(i, 5) REP(j, 5){
            if ( C[i][j] <= 0 ) continue;
            ti = T[C[i][j]][0];
            tj = T[C[i][j]][1];
            //sum += (max(ti, i)-min(ti, i) + max(tj, j) - min(tj, j));
            sum += abs(ti-i) + abs(tj-j);
        }
        return sum;
    }
};

int limit;

bool dfs( int depth, Puzzle P ){
    if ( P.isGoal() ) return true;
    if ( depth + P.getMD() > limit ) return false;

    static const int di[4] = {0, -1, 0, 1};
    static const int dj[4] = {1, 0, -1, 0};

    REP(i, N) REP(j, N){
        if ( P.C[i][j] != 0 ) continue;
        REP(r, 4){
            Puzzle v = P;
            if ( !v.swapAdj(i, j, i+di[r], j+dj[r]) ) continue;
            if ( dfs( depth + 1, v ) ) return true;
        }
    }

    return false;
}

int idp(Puzzle source){
    for ( limit = 0; limit <= LIMIT; limit++ ){
        //source.mdist = source.getMD();
        if ( dfs(0, source) ) return limit;
    }
    return INT_MAX;
}

int main(){
    Puzzle P;
    int top;

    while(1){
        cin >> top;
        if ( top == -1 ) break;
        REP(j, N) P.C[0][j] = -1;
        P.C[0][2] = top;
        for(int i = 1; i < N; i++) REP(j, N){
                if ( (i == 1 || i == 3) && (j == 0 || j == 4 ) ) P.C[i][j] = -1;
                else if ( i == 4 && j != 2 ) P.C[i][j] = -1;
                else cin >> P.C[i][j];
            }

        int cost = idp(P);
        if ( cost == INT_MAX ) cout << "NA" << endl;
        else cout << cost << endl;
    }

    return 0;
}

*/