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

#include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr, __VA_ARGS__)
// #define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

int main() {
  int n;
  while (cin >> n, n) {
    set<char> charset;
    bool top[26] = {};
    int vars[26] = {};
    REP(i, n) {
      string line;
      cin >> line;
      REP(j, line.length()) { charset.insert(line[j]); }
      if (line.length() > 1)
        top[line[0] - 'A'] = true;
      int k = 1;
      int sign = i == n - 1 ? -1 : 1;
      for (int j = line.length() - 1; j >= 0; j--) {
        vars[line[j] - 'A'] += k * sign;
        k *= 10;
      }
    }

    //        for (auto x : vars) {
    //            LOG("%c %d\\n", x.first, x.second);
    //        }

    int N = charset.size();
    vector<char> chars;
    for (char c : charset)
      chars.push_back(c);

    int res = 0;
    REP(i, 1 << 10) {
      if (__builtin_popcount(i) == N) {
        int nums[10];
        int idx = 0;
        REP(j, 10) {
          if (i & (1 << j)) {
            nums[idx++] = j;
          }
        }

        //                LOG("---------> ");
        //                REP(j, N) {
        //                    LOG("%d ", nums[j]);
        //                }
        //                LOG("\\n");

        do {
          int ans = 0;

          REP(j, N) {
            if (nums[j] == 0 && top[chars[j] - 'A'])
              goto NEXT;
          }

          REP(j, N) { ans += vars[chars[j] - 'A'] * nums[j]; }
          if (ans == 0)
            res++;

          //                    REP(j, N) {
          //                        LOG("%d ", nums[j]);
          //                    }
          //                    LOG("\\n");

        NEXT : {}
        } while (next_permutation(nums, nums + N));
      }
    }

    cout << res << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr, __VA_ARGS__)
// #define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

template <class BidirectionalIterator>
bool next_combination(BidirectionalIterator first1, BidirectionalIterator last1,
                      BidirectionalIterator first2,
                      BidirectionalIterator last2) {
  if ((first1 == last1) || (first2 == last2)) {
    return false;
  }
  BidirectionalIterator m1 = last1;
  BidirectionalIterator m2 = last2;
  --m2;
  while (--m1 != first1 && !(*m1 < *m2)) {
  }
  bool result = (m1 == first1) && !(*first1 < *m2);
  if (!result) {
    while (first2 != m2 && !(*m1 < *first2)) {
      ++first2;
    }
    first1 = m1;
    std::iter_swap(first1, first2);
    ++first1;
    ++first2;
  }
  if ((first1 != last1) && (first2 != last2)) {
    m1 = last1;
    m2 = first2;
    while ((m1 != first1) && (m2 != last2)) {
      std::iter_swap(--m1, m2);
      ++m2;
    }
    std::reverse(first1, m1);
    std::reverse(first1, last1);
    std::reverse(m2, last2);
    std::reverse(first2, last2);
  }
  return !result;
}

template <class BidirectionalIterator>
bool next_combination(BidirectionalIterator first, BidirectionalIterator middle,
                      BidirectionalIterator last) {
  return next_combination(first, middle, middle, last);
}

int main() {
  int n;
  while (cin >> n, n) {
    vector<string> e(n);
    set<char> charset;
    REP(i, n) {
      cin >> e[i];
      REP(j, e[i].length()) { charset.insert(e[i][j]); }
    }
    vector<char> cs(ALL(charset));

    // index????±???????
    vvi expr(n);
    REP(i, n) {
      REP(j, e[i].length()) {
        auto it = find(ALL(cs), e[i][j]);
        expr[i].push_back(it - cs.begin());
      }
    }

    vi n1;
    REP(i, 10) n1.push_back(i);
    int r = charset.size();

    int cnt = 0;
    do {
      vi n2(n1.begin(), n1.begin() + r);
      do {
        int sum = 0;
        REP(i, n) {
          int num = 0;
          REP(j, expr[i].size()) {
            int c = n2[expr[i][j]];
            if (j == 0 && expr[i].size() > 1 && c == 0) {
              goto next;
            }
            num *= 10;
            num += c;
          }
          if (i == n - 1) {
            sum -= num;
          } else {
            sum += num;
          }
        }
        if (sum == 0) {
          cnt++;
        }
      next : {}
      } while (next_permutation(ALL(n2)));
    } while (next_combination(n1.begin(), n1.begin() + r, n1.end()));

    cout << cnt << endl;
  }
}