Problem p01105 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <unordered_set>
#include <vector>

#define REP(i, s, n) for (int i = s; i < n; ++i)
#define rep(i, n) REP(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define FOR_SUBSET(b, a) for (int b = a; b != 0; b = (b - 1) & a)

using namespace std;

string normalize(string s) {
  map<char, char> mp;
  char c = 'a';
  rep(i, (int)s.size()) {
    if (isalpha(s[i])) {
      if (!mp.count(s[i]))
        mp[s[i]] = c++;
    }
  }
  rep(i, (int)s.size()) {
    if (isalpha(s[i])) {
      s[i] = mp[s[i]];
    }
  }
  return s;
}

class Parser {
private:
  string parse;
  int pos;

public:
  Parser(string s) {
    parse = s;
    pos = 0;
  }

  int fact() {
    if (parse[pos] == '-') {
      ++pos;
      int p = fact();
      return (p + 1) & 1;
    } else if (parse[pos] == '(') {
      pos++;
      int p = expression();
      pos++;
      return p;
    } else {
      int p = 0;
      while ('0' <= parse[pos] && parse[pos] <= '1') {
        p *= 10;
        p += parse[pos] - '0';
        pos++;
      }
      return p;
    }
  }

  int expression() {
    int p = fact();
    while (parse[pos] == '^' || parse[pos] == '*') {
      if (parse[pos] == '^') {
        ++pos;
        p = p ^ fact();
      } else {
        ++pos;
        p = p & fact();
      }
    }
    return p;
  }
};

bool variable_check(int b_s, string t) {
  rep(i, (int)t.size()) if ('a' <= t[i] && t[i] <= 'd') {
    if (!((b_s >> (t[i] - 'a')) & 1))
      return false;
  }
  return true;
}

void compute(string s, vector<string> &E) {
  int b_s = 0;
  rep(i, (int)s.size()) if ('a' <= s[i] && s[i] <= 'd') {
    b_s |= (1 << (s[i] - 'a'));
  }
  vector<char> perm;
  rep(i, 4) if ((b_s >> i) & 1) perm.push_back((char)('a' + i));

  rep(i, (int)E.size()) {

    if (E[i].size() >= s.size())
      break;
    if (!variable_check(b_s, E[i]))
      continue;

    bool ok = true;
    do {
      ok = true;

      string tmp = s;
      rep(i, (int)s.size()) if (isalpha(s[i])) { s[i] = perm[s[i] - 'a']; }
      FOR_SUBSET(j, b_s) {
        string s1 = s, s2 = E[i];
        rep(k, (int)s1.size()) if (isalpha(s1[k])) {
          s1[k] = (char)('0' + ((j >> (s1[k] - 'a')) & 1));
        }
        rep(k, (int)s2.size()) if (isalpha(s2[k])) {
          s2[k] = (char)('0' + ((j >> (s2[k] - 'a')) & 1));
        }
        Parser p1 = Parser(s1);
        Parser p2 = Parser(s2);
        int v1, v2;
        if ((v1 = p1.expression()) != (v2 = p2.expression())) {
          // cout << s1 << " != " << s2 << " ( " << v1 << " != " << v2 << " )"
          // << endl;
          ok = false;
          break;
        }
      }
      { // all 0
        string s1 = s, s2 = E[i];
        rep(k, (int)s1.size()) if (isalpha(s1[k])) { s1[k] = '0'; }
        rep(k, (int)s2.size()) if (isalpha(s2[k])) { s2[k] = '0'; }
        Parser p1 = Parser(s1);
        Parser p2 = Parser(s2);
        int v1, v2;
        if ((v1 = p1.expression()) != (v2 = p2.expression())) {
          // cout << s1 << " != " << s2 << " ( " << v1 << " != " << v2 << " )"
          // << endl;
          ok = false;
        }
      }
      if (ok)
        break;
      s = tmp;
    } while (next_permutation(ALL(perm)));

    if (ok) {
      // cout << s << " == " << E[i] << endl;
      cout << E[i].size() << endl;
      return;
    }
  }
  cout << s.size() << endl;
}

bool cmp(string &s, string &t) { return s.size() < t.size(); }

int main() {
  /*
  string a;
  while( cin >> a ) {
    Parser aa = Parser(a);
    cout << aa.expression() << endl;
  }
  */

  srand((unsigned int)time(NULL));
  set<string> E;
  E.insert("0");
  E.insert("1");
  E.insert("a");
  E.insert("b");
  E.insert("c");
  E.insert("d");
  E.insert("-a");
  E.insert("-b");
  E.insert("-c");
  E.insert("-d");

  rep(_, 4) {
    set<string> nE = E;
    for (auto s : E) {
      if (1 + s.size() <= 15) {
        if (!(s[0] == '-' || s[0] == '0' || s[0] == '1')) {
          nE.insert("-" + s);
        }
      }
      for (auto t : E) {
        if (s.size() + t.size() + 3 <= 15) {
          if (!(((s == "0" || s == "1") && (t == "0" || t == "1")))) {
            // nE.insert(normalize("("+s+"^"+t+")"));
            nE.insert(normalize("(" + s + "^" + t + ")"));
          }
        }
        if (s.size() + t.size() + 3 <= 15) {
          if (!(s == "0" || s == "1" || t == "0" || t == "1")) {
            if (!(s == t)) {
              // nE.insert(normalize("("+s+"*"+t+")"));
              nE.insert(normalize("(" + s + "*" + t + ")"));
            }
          }
        }
      }
    }
    E = nE;
  }
  vector<string> vE;

  for (auto s : E)
    vE.push_back(s);
  sort(ALL(vE), cmp);

  /*
  cout << "vE.size() = " << vE.size() << endl;
  rep(i,vE.size()) {
    cout << vE[i] << endl;
  }
  */

  string s;
  while (cin >> s, s[0] != '.')
    compute(normalize(s), vE);
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <vector>

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

using namespace std;

bool cmp(string &s, string &t) { return s.size() < t.size(); }

class Parser {
private:
  string parse;
  int pos;

public:
  Parser(string s) {
    parse = s;
    pos = 0;
  }

  bool fact() {
    if (parse[pos] == '(') {
      pos++;
      bool p = expression();
      pos++;
      return p;
    } else if (parse[pos] == '-') {
      ++pos;
      bool p = fact();
      return !p;
    } else {
      bool p = 0;
      while ('0' <= parse[pos] && parse[pos] <= '1') {
        p = parse[pos++] - '0';
      }
      return p;
    }
  }

  bool expression() {
    bool p = fact();
    while (parse[pos] == '^' || parse[pos] == '*') {
      if (parse[pos] == '^') {
        pos++;
        p = p ^ fact();
      } else {
        pos++;
        p = p & fact();
      }
    }
    return p;
  }
};

int count(string s) {
  int cnt = 0;
  rep(i, (int)s.size()) cnt += isalpha(s[i]);
  return cnt;
}

bool dfs(string &s, string &t, deque<char> &cs, int cur, int depth) {
  if (cur >= depth) {
    string _s = s;
    string _t = t;
    rep(i, (int)_s.size()) if (isalpha(_s[i])) _s[i] = cs[_s[i] - 'a'];
    rep(i, (int)_t.size()) if (isalpha(_t[i])) _t[i] = cs[_t[i] - 'a'];
    Parser p1 = Parser(_s);
    Parser p2 = Parser(_t);
    bool res1 = p1.expression();
    bool res2 = p2.expression();
    return res1 == res2;
  }
  rep(v, 2) {
    cs.push_back((char)('0' + v));
    if (!dfs(s, t, cs, cur + 1, depth))
      return false;
    cs.pop_back();
  }
  return true;
}

bool check(string s, string t) {
  int maxi = max(count(s), count(t));
  deque<char> cs;
  bool res = dfs(s, t, cs, 0, maxi);
  return res;
}

void compute(string s, vector<string> &vec) {
  rep(i, (int)vec.size()) {
    if (vec[i].size() >= s.size())
      break;
    if (check(s, vec[i])) {
      cout << (int)vec[i].size() << endl;
      return;
    }
  }
  cout << s.size() << endl;
}

int main() {
  srand((unsigned int)time(NULL));
  set<string> S;
  S.insert("0");
  S.insert("1");
  S.insert("a");
  S.insert("-a");

  rep(i, 3) {
    set<string> T;
    for (auto s : S) {
      if (!((s == "0" || s == "1"))) {
        string tmp = "-" + s;
        if ((int)tmp.size() <= 16 && s != "0" && s != "1" && s[0] != '-') {
          T.insert(tmp);
        }
      }
      for (auto b : S) {
        if (!((s == "0" || s == "1") && (b == "0" || b == "1"))) {
          string tmp = "(" + s + "^" + b + ")";
          if (tmp.size() <= 16 && s != "0" && b != "0" && s != "1" &&
              b != "1") {
            char c = 'a';
            rep(i, (int)tmp.size()) if (isalpha(tmp[i])) tmp[i] = c++;
            T.insert(tmp);
          }
        }
        if (!((s == "0" || s == "1") && (b == "0" || b == "1"))) {
          string tmp = "(" + s + "*" + b + ")";
          if (tmp.size() <= 16 && s != "0" && b != "0" && s != "1" &&
              b != "1") {
            char c = 'a';
            rep(i, (int)tmp.size()) if (isalpha(tmp[i])) tmp[i] = c++;
            T.insert(tmp);
          }
        }
      }
    }
    for (auto t : T)
      S.insert(t);
  }

  vector<string> vec;
  for (auto s : S)
    vec.push_back(s);
  sort(vec.begin(), vec.end(), cmp);
  rep(i, (int)vec.size()) { cout << vec[i] << endl; }
  string s;
  while (getline(cin, s), s[0] != '.')
    compute(s, vec);

  return 0;
}