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

#include <bits/stdc++.h>

using namespace std;

#define rep(i, n) REP(i, 0, n)
#define REP(i, s, e) for (int i = (s); i < (int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for (int i = (int)(s - 1); i >= (int)(e); i--)
#define pb push_back
#define all(r) r.begin(), r.end()
#define rall(r) r.rbegin(), r.rend()
#define fi first
#define se second

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

#define DEBUG_MODE
#ifdef DEBUG_MODE
#define dump(x) cout << #x << " : " << x << endl
#define LINE cout << "line : " << __LINE__ << endl
#define dumpV(v)                                                               \\
  cout << #v << " : [";                                                        \\
  for (auto &t : v)                                                            \\
    cout << t << ", ";                                                         \\
  cout << "]" << endl
#define STOP assert(false)
#else
#define dump(x) ;
#define LINE ;
#define dumpV(v) ;
#define STOP ;
#endif

namespace std {
template <class S, class T>
ostream &operator<<(ostream &out, const pair<S, T> &a) {
  out << '(' << a.fi << ", " << a.se << ')';
  return out;
}
} // namespace std

typedef string::const_iterator State;

bool atom(State &it, int mask);
bool term(State &it, int mask);
bool formula(State &it, int mask);

bool atom(State &it, int mask) {
  auto c = *it;
  it++;
  if (c == '0')
    return false;
  if (c == '1')
    return true;
  assert(c >= 'a' && c <= 'd');
  return mask & (1 << (c - 'a'));
}

bool term(State &it, int mask) {
  bool ret = formula(it, mask);
  auto c = *it;
  it++;
  if (c == '*')
    return ret & formula(it, mask);
  if (c == '^')
    return ret ^ formula(it, mask);
  assert(false);
}
bool formula(State &it, int mask) {
  if (((*it) >= 'a' && (*it) <= 'd') || *it == '0' || *it == '1') {
    return atom(it, mask);
  }
  auto c = *it;
  it++;
  if (c == '-')
    return !formula(it, mask);
  if (c == '(') {
    bool tmp = term(it, mask);
    it++;
    return tmp;
  }
  assert(false);
}

int main() {
  string s;
  vi ans((1 << 16) + 10, 1e9);
  auto calc = [](const string &t) {
    int ret = 0;
    rep(mask, (1 << 4)) {
      auto it = t.begin();
      if (formula(it, mask))
        ret |= (1 << mask);
    }
    return ret;
  };
  {
    set<string> used[20];
    queue<string> q;
    vector<char> atoms = {'a', 'b', 'c', 'd', '0', '1'};
    vector<char> opes = {'*', '^'};
    for (auto &c : atoms) {
      q.push(string(1, c));
      used[1].insert(string(1, c));
    }
    while (!q.empty()) {
      string s = q.front();
      q.pop();
      int bits = calc(s);
      ans[bits] = min(ans[bits], (int)s.size());
      if (s[0] != '-' && s.size() < 16) {
        q.push("-" + s);
        used[s.size() + 1].insert("-" + s);
      }
      for (auto ope : opes) {
        for (int i = 1; i + s.size() < 16; i++) {
          for (auto a : used[i]) {
            string nxt;
            nxt = ("(" + s + ope) + a + ")";
            if (nxt.size() <= 16 && used[nxt.size()].count(nxt) == 0) {
              q.push(nxt);
              used[nxt.size()].insert(nxt);
            }
            nxt = ("(" + s + ope) + "-" + a + ")";
            if (nxt.size() <= 16 && used[nxt.size()].count(nxt) == 0) {
              q.push(nxt);
              used[nxt.size()].insert(nxt);
            }
          }
        }
      }
    }
  }
  while (cin >> s) {
    if (s == ".")
      break;
    assert(s.size() >= ans[calc(s)]);
    cout << ans[calc(s)] << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define rep(i, n) REP(i, 0, n)
#define REP(i, s, e) for (int i = (s); i < (int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for (int i = (int)(s - 1); i >= (int)(e); i--)
#define pb push_back
#define all(r) r.begin(), r.end()
#define rall(r) r.rbegin(), r.rend()
#define fi first
#define se second

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

#define DEBUG_MODE
#ifdef DEBUG_MODE
#define dump(x) cout << #x << " : " << x << endl
#define LINE cout << "line : " << __LINE__ << endl
#define dumpV(v)                                                               \\
  cout << #v << " : [";                                                        \\
  for (auto &t : v)                                                            \\
    cout << t << ", ";                                                         \\
  cout << "]" << endl
#define STOP assert(false)
#else
#define dump(x) ;
#define LINE ;
#define dumpV(v) ;
#define STOP ;
#endif

namespace std {
template <class S, class T>
ostream &operator<<(ostream &out, const pair<S, T> &a) {
  out << '(' << a.fi << ", " << a.se << ')';
  return out;
}
} // namespace std

typedef string::const_iterator State;

bool atom(State &it, int mask);
bool term(State &it, int mask);
bool formula(State &it, int mask);

bool atom(State &it, int mask) {
  auto c = *it;
  it++;
  if (c == '0')
    return false;
  if (c == '1')
    return true;
  assert(c >= 'a' && c <= 'd');
  return mask & (1 << (c - 'a'));
}

bool term(State &it, int mask) {
  bool ret = formula(it, mask);
  auto c = *it;
  it++;
  if (c == '*')
    return ret & formula(it, mask);
  if (c == '^')
    return ret ^ formula(it, mask);
  assert(false);
}
bool formula(State &it, int mask) {
  if (((*it) >= 'a' && (*it) <= 'd') || *it == '0' || *it == '1') {
    return atom(it, mask);
  }
  auto c = *it;
  it++;
  if (c == '-')
    return !formula(it, mask);
  if (c == '(') {
    bool tmp = term(it, mask);
    it++;
    return tmp;
  }
  assert(false);
}

int main() {
  string s;
  vi ans((1 << 16) + 10, 1e9);
  auto calc = [](const string &t) {
    int ret = 0;
    rep(mask, (1 << 4)) {
      auto it = t.begin();
      if (formula(it, mask))
        ret |= (1 << mask);
    }
    return ret;
  };
  {
    set<string> used;
    queue<string> q;
    vector<char> atoms = {'a', 'b', 'c', 'd', '0', '1'};
    vector<char> opes = {'*', '^'};
    for (auto &c : atoms) {
      q.push(string(1, c));
      used.insert(string(1, c));
    }
    while (!q.empty()) {
      string s = q.front();
      q.pop();
      int bits = calc(s);
      ans[bits] = min(ans[bits], (int)s.size());
      if (s[0] != '-' && s.size() < 16)
        q.push("-" + s);
      for (auto ope : opes) {
        for (auto a : atoms) {
          string nxt;
          nxt = ("(" + s + ope) + a + ")";
          if (nxt.size() <= 16 && used.count(nxt) == 0) {
            q.push(nxt);
            used.insert(nxt);
          }
          // nxt = ("(-" + s + ope) + a + ")";
          // if (nxt.size() <= 16 && used.count(nxt) == 0) {
          // 	q.push(nxt);
          // 	used.insert(nxt);
          // }
          nxt = ("(" + s + ope) + "-" + a + ")";
          if (nxt.size() <= 16 && used.count(nxt) == 0) {
            q.push(nxt);
            used.insert(nxt);
          }
          // nxt = ("(-" + s + ope) + "-" + a + ")";
          // if (nxt.size() <= 16 && used.count(nxt) == 0) {
          // 	q.push(nxt);
          // 	used.insert(nxt);
          // }
        }
      }
    }
  }
  while (cin >> s) {
    if (s == ".")
      break;
    assert(s.size() >= ans[calc(s)]);
    cout << ans[calc(s)] << endl;
  }
  return 0;
}