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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef int INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair<INT, INT> II;
typedef vector<II> VII;

template <class T> ostream &operator<<(ostream &os, vector<T> v) {
  for (typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i) {
    os << *it_i << ", ";
  }
  return os;
}

int T[20];
int A[20], B[20];
int n, m;

int solve() {
  int P[17];
  P[n] = 2;
  for (int i = n; i > 0; --i)
    P[i - 1] = 3 * P[i] + 2;

  A[n] = T[n];
  B[n] = 2 - T[n];
  for (int i = n; i > 1; --i) {
    if (T[i - 1] == 0) {
      A[i - 1] = A[i];
      B[i - 1] = B[i] + 2 * P[i] + 2;
    } else if (T[i - 1] == 1) {
      A[i - 1] = B[i] + P[i] + 1;
      B[i - 1] = A[i] + P[i] + 1;
    } else if (T[i - 1] == 2) {
      A[i - 1] = A[i] + 2 * P[i] + 2;
      B[i - 1] = B[i];
    }
  }
  int res = min(A[1], B[1]);
  if (res > m)
    return -1;
  return res;
}

int main() {
  while (cin >> n >> m && n) {
    for (int i = 0; i < 3; ++i) {
      int k;
      cin >> k;
      for (int j = 0; j < k; ++j) {
        int t;
        cin >> t;
        T[t] = i;
      }
    }

    cout << solve() << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <climits>
#include <iostream>
#include <map>
#include <tuple>
using namespace std;

const int NONE = INT_MAX;
typedef tuple<int, int, int> Tuple;
map<Tuple, int> S;
Tuple goal;
int n, m;

int get_last(int m) {
  for (int i = n - 1; i >= 0; --i) {
    if ((m & (1 << i)) == (1 << i))
      return 1 << i;
  }
  return 0;
}

int remove_last(int m) {
  for (int i = n - 1; i >= 0; --i) {
    if ((m & (1 << i)) == (1 << i))
      return m ^ (1 << i);
  }
  return m;
}

int solve(int A, int B, int C, int turns) {
  Tuple tuple = make_tuple(A, B, C);
  if (S.count(tuple) > 0 && turns >= S[tuple])
    return NONE;
  S[tuple] = turns;
  if (turns > m)
    return NONE;
  if (tuple == goal)
    return turns;
  if (A != 0) {
    int u = get_last(A);
    int v = get_last(B);
    if (u > v) {
      int ret = solve(remove_last(A), B | u, C, turns + 1);
      if (ret != NONE)
        return ret;
    }
  }
  if (B != 0) {
    int u = get_last(B);
    int v = get_last(A);
    if (u > v) {
      int ret = solve(A | u, remove_last(B), C, turns + 1);
      if (ret != NONE)
        return ret;
    }
  }
  if (B != 0) {
    int u = get_last(B);
    int v = get_last(C);
    if (u > v) {
      int ret = solve(A, remove_last(B), C | u, turns + 1);
      if (ret != NONE)
        return ret;
    }
  }
  if (C != 0) {
    int u = get_last(C);
    int v = get_last(B);
    if (u > v) {
      int ret = solve(A, B | u, remove_last(C), turns + 1);
      if (ret != NONE)
        return ret;
    }
  }
  return NONE;
}

int main() {
  while (cin >> n >> m) {
    if (n == 0 && m == 0)
      break;
    S.clear();
    int T[3] = {0, 0, 0};
    for (int i = 0; i < 3; ++i) {
      int k;
      cin >> k;
      for (int j = 0; j < k; ++j) {
        int t;
        cin >> t;
        t--;
        T[i] |= 1 << t;
      }
    }
    goal = make_tuple(T[0], T[1], T[2]);
    int ret1 = solve((1 << n) - 1, 0, 0, 0);
    int ret2 = solve(0, 0, (1 << n) - 1, 0);
    int res = min(ret1, ret2);
    if (res == NONE)
      res = -1;
    cout << res << endl;
  }
  return 0;
}