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

#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>
using namespace std;

int n;
string str[12];

int digit[26];
bool used[26];
bool lead[26];
int maxlen;

int dfs(int i, int j, int s) {
  if (i == maxlen) {
    return !s;
  }
  if (j == n - 1) {
    if (digit[str[j][i] - 'A'] != -1) {
      if (s % 10 == digit[str[j][i] - 'A'])
        return dfs(i + 1, 0, s / 10);
      return 0;
    }
    if (!used[s % 10] && !(s % 10 == 0 && lead[str[j][i] - 'A'])) {
      used[s % 10] = true;
      digit[str[j][i] - 'A'] = s % 10;
      int res = dfs(i + 1, 0, s / 10);
      used[s % 10] = false;
      digit[str[j][i] - 'A'] = -1;
      return res;
    }
    return 0;
  }
  if (str[j].size() <= i)
    return dfs(i, j + 1, s);
  if (digit[str[j][i] - 'A'] != -1)
    return dfs(i, j + 1, s + digit[str[j][i] - 'A']);
  int res = 0;
  for (int k = lead[str[j][i] - 'A']; k < 10; k++) {
    if (used[k])
      continue;
    used[k] = true;
    digit[str[j][i] - 'A'] = k;
    res += dfs(i, j + 1, s + k);
    used[k] = false;
    digit[str[j][i] - 'A'] = -1;
  }
  return res;
}
int main() {
  while (cin >> n && n) {
    maxlen = 0;
    memset(lead, false, sizeof(lead));
    memset(used, false, sizeof(used));
    memset(digit, -1, sizeof(digit));
    for (int i = 0; i < n; i++) {
      cin >> str[i];
      if (str[i].size() != 1)
        lead[str[i][0] - 'A'] = true;
      reverse(str[i].begin(), str[i].end());
      maxlen = max(maxlen, (int)str[i].size());
    }
    if (str[n - 1].size() < maxlen)
      cout << 0 << endl;
    else
      cout << dfs(0, 0, 0) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#define INF (1 << 29)

int n;
string str[12];
bool head[10];

bool used[10];
int wariate[10];

bool eq() {
  int a = 0, b = 0;
  for (int i = 0; i < n - 1; i++) {
    int c = 1;
    for (int j = str[i].size() - 1; j >= 0; j--) {
      a += c * wariate[str[i][j] - 'A'];
      c *= 10;
    }
  }
  int c = 1;
  for (int j = str[n - 1].size() - 1; j >= 0; j--) {
    b += c * wariate[str[n - 1][j] - 'A'];
    c *= 10;
  }
  return a == b;
}
int dfs(int d) {
  int res = 0;
  if (d == -1) {
    if (eq())
      res++;
    return res;
  }
  for (int i = 0; i < 10; i++) {
    if (i == 0 && head[d])
      continue;
    if (used[i])
      continue;
    used[i] = true;
    wariate[d] = i;
    res += dfs(d - 1);
    used[i] = false;
  }
  return res;
}
int main() {
  while (cin >> n && n) {
    int num = 0;
    char f[26];
    memset(f, -1, sizeof(f));
    memset(head, false, sizeof(head));
    for (int i = 0; i < n; i++) {
      cin >> str[i];
      for (int j = 0; j < str[i].size(); j++) {
        if (f[str[i][j] - 'A'] == -1) {
          f[str[i][j] - 'A'] = num + 'A';
          str[i][j] = 'A' + num++;
        } else {
          str[i][j] = f[str[i][j] - 'A'];
        }
        if (j == 0 && str[i].size() != 1) {
          head[str[i][0] - 'A'] = true;
        }
      }
    }
    memset(used, false, sizeof(used));
    cout << dfs(num - 1) << endl;
  }
  return 0;
}