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

#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;

int tostate(int a, int b, int c, int k) {
  int mul;
  int ret = 0;

  for (int i = 0, mul = 1; i < k; ++i, mul *= 3)
    ret += ((a >> i) & 1) * 1 * mul;
  for (int i = 0, mul = 1; i < k; ++i, mul *= 3)
    ret += ((b >> i) & 1) * 2 * mul;

  return ret;
}

inline int mhb(int x) {
  for (int i = 31; i >= 0; --i) {
    if (x & (1 << i))
      return 1 << i;
  }

  return 0;
}

const int inf = 1000000000;
const int pow3x5 = 3 * 3 * 3 * 3 * 3;
const int pow3x15 = pow3x5 * pow3x5 * pow3x5;
bool visit[pow3x15];

struct node {
  int a, b, c, remain;
  node(int a, int b, int c, int remain) : a(a), b(b), c(c), remain(remain) {}
};

int calc(int a, int b, int c, int remain, int k) {
  int f = inf;

  queue<node> q;

  q.push(node(a, b, c, remain));

  while (!q.empty()) {

    node cur = q.front();
    q.pop();

    if (cur.remain < 0)
      continue;

    if (cur.b == 0 && (cur.a == 0 || cur.c == 0)) {
      f = cur.remain;
      break;
    }

    int state = tostate(cur.a, cur.b, cur.c, k);

    if (visit[state])
      continue;
    visit[state] = true;

    if (cur.a > cur.b) {
      int move = mhb(cur.a);
      int ta = cur.a - move;
      int tb = cur.b + move;
      int tc = cur.c;
      q.push(node(ta, tb, tc, cur.remain - 1));
    } else {
      int move = mhb(cur.b);
      int ta = cur.a + move;
      int tb = cur.b - move;
      int tc = cur.c;
      q.push(node(ta, tb, tc, cur.remain - 1));
    }

    if (cur.b > cur.c) {
      int move = mhb(cur.b);
      int ta = cur.a;
      int tb = cur.b - move;
      int tc = cur.c + move;
      q.push(node(ta, tb, tc, cur.remain - 1));
    } else {
      int move = mhb(cur.c);
      int ta = cur.a;
      int tb = cur.b + move;
      int tc = cur.c - move;
      q.push(node(ta, tb, tc, cur.remain - 1));
    }
  }

  int ret = (f != inf ? remain - f : -1);

  return ret;
}

int main() {
  while (true) {

    int n, m;

    scanf("%d%d", &n, &m);
    if (n == 0)
      break;

    fill(visit + 0, visit + pow3x15, false);

    int a[3];
    int bita[3] = {0};
    int k = 0;

    for (int i = 0; i < 3; ++i) {
      scanf("%d", a + i);
      for (int j = 0; j < a[i]; ++j) {
        int t;
        scanf("%d", &t);
        bita[i] += 1 << (t - 1);
        k = max(k, t);
      }
    }

    int ans = calc(bita[0], bita[1], bita[2], m, k);

    printf("%d\\n", ans);
  }

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cstdio>
using namespace std;

int tostate(int a, int b, int c, int k) {
  int mul;
  int ret = 0;

  for (int i = 0, mul = 1; i < k; ++i, mul *= 3)
    ret += ((a >> i) & 1) * 1 * mul;
  for (int i = 0, mul = 1; i < k; ++i, mul *= 3)
    ret += ((b >> i) & 1) * 2 * mul;

  return ret;
}

inline int mhb(int x) {
  for (int i = 31; i >= 0; --i) {
    if (x & (1 << i))
      return 1 << i;
  }

  return 0;
}

const int inf = 1000000000;
const int pow3x5 = 3 * 3 * 3 * 3 * 3;
const int pow3x15 = pow3x5 * pow3x5 * pow3x5;
bool visit[pow3x15];

int check(int a, int b, int c, int remain, int k) {
  if (remain < 0)
    return inf;

  if (b == 0 && (a == 0 || c == 0))
    return remain;

  int state = tostate(a, b, c, k);

  if (visit[state])
    return inf;
  visit[state] = true;

  int ret = inf;

  if (a > b) {
    int move = mhb(a);
    int ta = a - move;
    int tb = b + move;
    ret = min(ret, check(ta, tb, c, remain - 1, k));
  } else {
    int move = mhb(b);
    int ta = a + move;
    int tb = b - move;
    ret = min(ret, check(ta, tb, c, remain - 1, k));
  }

  if (b > c) {
    int move = mhb(b);
    int tb = b - move;
    int tc = c + move;
    ret = min(ret, check(a, tb, tc, remain - 1, k));
  } else {
    int move = mhb(c);
    int tb = b + move;
    int tc = c - move;
    ret = min(ret, check(a, tb, tc, remain - 1, k));
  }

  return ret;
}

int main() {
  while (true) {

    int n, m;

    scanf("%d%d", &n, &m);
    if (n == 0)
      break;

    fill(visit + 0, visit + pow3x15, false);

    int a[3];
    int bita[3] = {0};
    int k = 0;

    for (int i = 0; i < 3; ++i) {
      scanf("%d", a + i);
      for (int j = 0; j < a[i]; ++j) {
        int t;
        scanf("%d", &t);
        bita[i] += 1 << (t - 1);
        k = max(k, t);
      }
    }

    int ans = m - check(bita[0], bita[1], bita[2], m, k);

    printf("%d\\n", ans >= 0 ? ans : -1);
  }

  return 0;
}