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

#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> PII;
typedef vector<PII> VPII;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<VVI> VVVI;
typedef vector<char> VC;
typedef vector<VC> VVC;

#define Y first
#define X second
#define RANGE(x, y, mX, mY) (0 <= (x) && 0 <= (y) && (x) < (mX) && (y) < (mY))
#define MP make_pair

const int INF = 0x3f3f3f3f;

int N, M;
vector<string> ss;

set<char> not_zero;

VC as;

map<char, int> ks;

// alphabet?????????
VC find_alphas() {
  set<char> as_set;
  for (auto s : ss) {
    for (auto c : s) {
      as_set.insert(c);
    }
  }

  VC res;
  for (auto c : as_set) {
    res.push_back(c);
  }

  return res;
}

void find_not_zero() {
  not_zero.clear();

  for (auto &s : ss) {
    if (s.size() == 1)
      continue;
    not_zero.insert(s[0]);
  }
}

// ?????°?¨????
void calc_ks() {
  ks.clear();

  for (auto c : as) {
    ks[c] = 0;
  }

  for (int i = 0; i < N; i++) {
    int v = 1;
    string &s = ss[i];

    for (int j = (int)s.size() - 1; j >= 0; --j) {
      ks[s[j]] += v * (i == N - 1 ? -1 : 1);
      v *= 10;
    }
  }
}

bool calc_siki(VI &idxes) {
  int sum = 0;

  for (int i = 0; i < M; i++) {
    char c = as[i];
    int n = idxes[i];
    sum += ks[c] * n;
  }

  return sum == 0;
}

int dfs(int used, int n, int sum) {
  if (n == M) {
    return sum == 0;
  }

  int cnt = 0;
  for (int i = 0; i < 10; i++) {
    if (1 << i & used)
      continue;
    if (!i && not_zero.count(as[n]))
      continue;

    cnt += dfs(used | 1 << i, n + 1, sum + ks[as[n]] * i);
  }

  return cnt;
}

int solve() {
  as = find_alphas();
  M = as.size();
  find_not_zero();
  calc_ks();

  return dfs(0, 0, 0);
}

int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);

  while (cin >> N, N) {
    ss.clear();
    ss.resize(N);

    for (auto &s : ss)
      cin >> s;

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

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> PII;
typedef vector<PII> VPII;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<VVI> VVVI;
typedef vector<char> VC;
typedef vector<VC> VVC;

#define Y first
#define X second
#define RANGE(x, y, mX, mY) (0 <= (x) && 0 <= (y) && (x) < (mX) && (y) < (mY))
#define MP make_pair

const int INF = 0x3f3f3f3f;

int N, M;
vector<string> ss;

set<char> not_zero;

VC as;

map<char, int> ks;

// alphabet?????????
VC find_alphas() {
  set<char> as_set;
  for (auto s : ss) {
    for (auto c : s) {
      as_set.insert(c);
    }
  }

  VC res;
  for (auto c : as_set) {
    res.push_back(c);
  }

  return res;
}

void find_not_zero() {
  not_zero.clear();

  for (auto &s : ss) {
    if (s.size() == 1)
      continue;
    not_zero.insert(s[0]);
  }
}

// ?????°?¨????
void calc_ks() {
  ks.clear();

  for (auto c : as) {
    ks[c] = 0;
  }

  for (int i = 0; i < N; i++) {
    int v = 1;
    string &s = ss[i];

    for (int j = (int)s.size() - 1; j >= 0; --j) {
      ks[s[j]] += v * (i == N - 1 ? -1 : 1);
      v *= 10;
    }
  }
}

bool calc_siki(VI &idxes) {
  int sum = 0;

  for (int i = 0; i < M; i++) {
    char c = as[i];
    int n = idxes[i];
    sum += ks[c] * n;
  }

  return sum == 0;
}

int dfs(int used, int n, VI &idxes) {
  if (n == M) {
    return calc_siki(idxes);
  }

  int cnt = 0;
  for (int i = 0; i < 10; i++) {
    if (1 << i & used)
      continue;
    if (!i && not_zero.count(as[n]))
      continue;

    idxes[n] = i;

    cnt += dfs(used | 1 << i, n + 1, idxes);
  }

  return cnt;
}

int solve() {
  as = find_alphas();
  M = as.size();
  find_not_zero();
  calc_ks();

  VI idxes(M);

  return dfs(0, 0, idxes);
  /*
      int cnt = 0;

      for (int p = (1 << M) - 1; p < 1 << 10; p++) {
          if (__builtin_popcount(p) != M) continue;

          // ?????????????????°???
          VI idxes;
          bool have_zero = 1 & p;
          for (int i = 0; i < 10; i++) {
              if (1 << i & p) {
                  idxes.push_back(i);
              }
          }

          do {
              // ??????0?????????
              if (have_zero) {
                  auto it = find(idxes.begin(), idxes.end(), 0);
                  if (it != idxes.end()) {
                      char zero_c = as[it - idxes.begin()];
                      if (not_zero.count(zero_c)) continue;
                  }
              }

              cnt += calc_siki(idxes);
          } while (next_permutation(idxes.begin(), idxes.end()));
      }

      return cnt;*/
}

int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);

  while (cin >> N, N) {
    ss.clear();
    ss.resize(N);

    for (auto &s : ss)
      cin >> s;

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