Problem p00898 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <queue>
// #define _DEBUG
using namespace std;

const int kNext[20][3] = {
    {5, 1, 4},    // 0
    {6, 2, 0},    // 1
    {7, 3, 1},    // 2
    {8, 4, 2},    // 3
    {9, 0, 3},    // 4
    {0, 10, 11},  // 5
    {1, 11, 12},  // 6
    {2, 12, 13},  // 7
    {3, 13, 14},  // 8
    {4, 14, 10},  // 9
    {15, 5, 9},   // 10
    {16, 6, 5},   // 11
    {17, 7, 6},   // 12
    {18, 8, 7},   // 13
    {19, 9, 8},   // 14
    {10, 19, 16}, // 15
    {11, 15, 17}, // 16
    {12, 16, 18}, // 17
    {13, 17, 19}, // 18
    {14, 18, 15}  // 19
};

struct QNode {
  int x, y, s, stp;
  int c[3];

  QNode(int _x, int _y, int _s, const int _c[], int _stp) {
    x = _x, y = _y, s = _s, stp = _stp;
    for (int i = 0; i < 3; ++i)
      c[i] = _c[i];
  }
};

int X, Y, N;
int f[210][210][20][3], vst_cnt;

int bfs(void);

inline void shift(int c[]) {
  int tmp[3];
  copy(&c[0], &c[3], &tmp[0]);
  for (int i = 0; i < 3; ++i)
    c[(i + 1) % 3] = tmp[i];
}

int main() {
  while (cin >> X >> Y >> N) {
    if (X == 0 && Y == 0 && N == 0)
      break;
    X += 110, Y += 110;
    cout << bfs() << "\n";
  }

  return 0;
}

int bfs(void) {
  deque<QNode> que;

  f[110][110][0][0] = ++vst_cnt;
  que.push_back(QNode(110, 110, 0, kNext[0], 0));
  while (!que.empty()) {
    QNode frn(que.front());
    que.pop_front();

#ifdef _DEBUG
    if (frn.stp <= 1)
      cout << "x = " << frn.x - 110 << ", y = " << frn.y - 110
           << ", s = " << frn.s << endl;
#endif

    for (int di = 0; di < 3; ++di) {
      bool is_upside = (frn.x + frn.y) % 2 == 0;
      int nx, ny, ns, nc[3], nstp, r = 0;

      if (di == 0) {
        nx = frn.x - 1, ny = frn.y, nstp = frn.stp + 1;
        ns = is_upside ? frn.c[2] : frn.c[1];
        copy(&kNext[ns][0], &kNext[ns][3], &nc[0]);
        if (is_upside) {
          while (nc[2] != frn.s)
            ++r, shift(nc);
        } else {
          while (nc[1] != frn.s)
            ++r, shift(nc);
        }
      } else if (di == 1) {
        nx = frn.x + 1, ny = frn.y, nstp = frn.stp + 1;
        ns = is_upside ? frn.c[1] : frn.c[2];
        copy(&kNext[ns][0], &kNext[ns][3], &nc[0]);
        if (is_upside) {
          while (nc[1] != frn.s)
            ++r, shift(nc);
        } else {
          while (nc[2] != frn.s)
            ++r, shift(nc);
        }
      } else {
        nx = frn.x, ny = is_upside ? frn.y + 1 : frn.y - 1, nstp = frn.stp + 1;
        ns = frn.c[0];
        copy(&kNext[ns][0], &kNext[ns][3], &nc[0]);
        while (nc[0] != frn.s)
          ++r, shift(nc);
      }

#ifdef _DEBUG
      if (frn.stp <= 1) {
        cout << "nx = " << nx - 110 << ", ny = " << ny - 110 << ", ns = " << ns
             << ",";
        for (int o = 0; o < 3; ++o)
          cout << " " << nc[o];
        cout << ", r = " << r << endl;
      }
#endif

      if (nx == X && ny == Y && ns == N)
        return nstp;

      if (f[nx][ny][ns][r] != vst_cnt) {
        f[nx][ny][ns][r] = vst_cnt;
        que.push_back(QNode(nx, ny, ns, nc, nstp));
      }
    }
  }

  return -1;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <queue>
// #define _DEBUG
using namespace std;

const int kNext[20][3] = {
    {5, 1, 4},    // 0
    {6, 2, 0},    // 1
    {7, 3, 1},    // 2
    {8, 4, 2},    // 3
    {9, 0, 3},    // 4
    {0, 10, 11},  // 5
    {1, 11, 12},  // 6
    {2, 12, 13},  // 7
    {3, 13, 14},  // 8
    {4, 14, 10},  // 9
    {15, 5, 9},   // 10
    {16, 6, 5},   // 11
    {17, 7, 6},   // 12
    {18, 8, 7},   // 13
    {19, 9, 8},   // 14
    {10, 19, 16}, // 15
    {11, 15, 17}, // 16
    {12, 16, 18}, // 17
    {13, 17, 19}, // 18
    {14, 18, 15}  // 19
};

struct QNode {
  int x, y, s, stp;
  int c[3];

  QNode(int _x, int _y, int _s, const int _c[], int _stp) {
    x = _x, y = _y, s = _s, stp = _stp;
    for (int i = 0; i < 3; ++i)
      c[i] = _c[i];
  }
};

int X, Y, N;
int f[220][220][20][3], vst_cnt;

int bfs(void);

inline void shift(int c[]) {
  int tmp[3];
  copy(&c[0], &c[3], &tmp[0]);
  for (int i = 0; i < 3; ++i)
    c[(i + 1) % 3] = tmp[i];
}

int main() {
  while (cin >> X >> Y >> N) {
    if (X == 0 && Y == 0 && N == 0)
      break;
    X += 110, Y += 110;
    cout << bfs() << "\n";
  }

  return 0;
}

int bfs(void) {
  deque<QNode> que;

  f[110][110][0][0] = ++vst_cnt;
  que.push_back(QNode(110, 110, 0, kNext[0], 0));
  while (!que.empty()) {
    QNode frn(que.front());
    que.pop_front();

#ifdef _DEBUG
    if (frn.stp <= 1)
      cout << "x = " << frn.x - 110 << ", y = " << frn.y - 110
           << ", s = " << frn.s << endl;
#endif

    for (int di = 0; di < 3; ++di) {
      bool is_upside = (frn.x + frn.y) % 2 == 0;
      int nx, ny, ns, nc[3], nstp, r = 0;

      if (di == 0) {
        nx = frn.x - 1, ny = frn.y, nstp = frn.stp + 1;
        ns = is_upside ? frn.c[2] : frn.c[1];
        copy(&kNext[ns][0], &kNext[ns][3], &nc[0]);
        if (is_upside) {
          while (nc[2] != frn.s)
            ++r, shift(nc);
        } else {
          while (nc[1] != frn.s)
            ++r, shift(nc);
        }
      } else if (di == 1) {
        nx = frn.x + 1, ny = frn.y, nstp = frn.stp + 1;
        ns = is_upside ? frn.c[1] : frn.c[2];
        copy(&kNext[ns][0], &kNext[ns][3], &nc[0]);
        if (is_upside) {
          while (nc[1] != frn.s)
            ++r, shift(nc);
        } else {
          while (nc[2] != frn.s)
            ++r, shift(nc);
        }
      } else {
        nx = frn.x, ny = is_upside ? frn.y + 1 : frn.y - 1, nstp = frn.stp + 1;
        ns = frn.c[0];
        copy(&kNext[ns][0], &kNext[ns][3], &nc[0]);
        while (nc[0] != frn.s)
          ++r, shift(nc);
      }

#ifdef _DEBUG
      if (frn.stp <= 1) {
        cout << "nx = " << nx - 110 << ", ny = " << ny - 110 << ", ns = " << ns
             << ",";
        for (int o = 0; o < 3; ++o)
          cout << " " << nc[o];
        cout << ", r = " << r << endl;
      }
#endif

      if (nx == X && ny == Y && ns == N)
        return nstp;

      if (f[nx][ny][ns][r] != vst_cnt) {
        f[nx][ny][ns][r] = vst_cnt;
        que.push_back(QNode(nx, ny, ns, nc, nstp));
      }
    }
  }

  return -1;
}