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

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  bool isfirst[26];
  bool isused[26];
  int N;
  while (cin >> N, N) {
    fill(isfirst, isfirst + 26, false);
    fill(isused, isused + 26, false);
    vector<string> S;
    int K[26] = {};
    for (int i = 0; i < N; i++) {
      string str;
      cin >> str;
      S.push_back(str);
      if (str.size() > 1)
        isfirst[str[0] - 'A'] = true;
      for (auto c : str)
        isused[c - 'A'] = true;
    }
    for (int n = 0; n < N - 1; n++) {
      for (int i = 0, k = 1; i < 8; i++, k *= 10) {
        K[S[n][S[n].size() - 1 - i] - 'A'] += k;
      }
    }
    for (int i = 0, k = 1; i < 8; i++, k *= 10) {
      K[S[N - 1][S[N - 1].size() - 1 - i] - 'A'] -= k;
    }
    int used = 0;
    for (int i = 0; i < 26; i++)
      if (isused[i])
        used++;
    int ans = 0;
    int comb = (1 << used) - 1;
    while (comb < (1 << 10)) {
      int perm[10];
      for (int i = 0, p = 0; i < 10; i++) {
        if (comb & (1 << i)) {
          perm[p++] = i;
        }
      }
      int x = comb & -comb, y = comb + x;
      comb = ((comb & ~y) / x >> 1) | y;
      do {
        int num[26];
        int d, sum = 0;
        for (int i = 0, p = 0; i < 26; i++) {
          if (isused[i]) {
            num[i] = perm[p++];
            if (isfirst[i] && num[i] == 0) {
              sum = -1;
              break;
            }
            sum += K[i] * num[i];
          }
        }
        ans += !sum;
      } while (next_permutation(perm, perm + used));
    }
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  bool isfirst[26];
  bool isused[26];
  int N;
  while (cin >> N, N) {
    fill(isfirst, isfirst + 26, false);
    fill(isused, isused + 26, false);
    vector<string> S;
    int K[26] = {};
    for (int i = 0; i < N; i++) {
      string str;
      cin >> str;
      S.push_back(str);
      if (str.size() > 1)
        isfirst[str[0] - 'A'] = true;
      for (auto c : str)
        isused[c - 'A'] = true;
    }
    for (int n = 0; n < N - 1; n++) {
      for (int i = 0, k = 1; i < 8; i++, k *= 10) {
        K[S[n][S[n].size() - 1 - i] - 'A'] += k;
      }
    }
    for (int i = 0, k = 1; i < 8; i++, k *= 10) {
      K[S[N - 1][S[N - 1].size() - 1 - i] - 'A'] -= k;
    }
    int used = 0;
    for (int i = 0; i < 26; i++)
      if (isused[i])
        used++;
    int ans = 0;
    int comb = (1 << used) - 1;
    while (comb < (1 << 10)) {
      int perm[10];
      for (int i = 0, p = 0; i < 10; i++) {
        if (comb & (1 << i)) {
          perm[p++] = i;
        }
      }
      int x = comb & -comb, y = comb + x;
      comb = ((comb & ~y) / x >> 1) | y;
      do {
        int num[26];
        int d, sum = 0;
        for (int i = 0, p = 0; i < 26; i++) {
          if (isused[i]) {
            num[i] = perm[p++];
            sum += K[i] * num[i];
          }
        }
        for (int i = 0; i < 26; i++) {
          if (isfirst[i] && num[i] == 0) {
            sum = -1;
            break;
          }
        }
        if (!sum)
          ans++;
      } while (next_permutation(perm, perm + used));
    }
    cout << ans << endl;
  }
  return 0;
}