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

// include
//------------------------------------------
#include <algorithm>
#include <bitset>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

// typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

// container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i, c)                                                             \\
  for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

// repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

// constant
//--------------------------------------------
const double EPS = 1e-10;
const double PI = acos(-1.0);

int N, kind, len;
int pw[9];
VI ng;
VI add;
int dfs(int idx, queue<int> &q, int diff) {
  if (idx == kind) {
    if (diff == 0)
      return 1;
    return 0;
  }
  if (idx >= len && diff > 0) {
    return 0;
  }

  int ret = 0;
  vector<bool> used(10, false);
  while (!used[q.front()]) {
    int i = q.front();
    q.pop();
    used[i] = true;
    if (i == 0 && ng[idx]) {
      q.push(i);
      continue;
    }

    ret += dfs(idx + 1, q, diff + i * add[idx]);
    q.push(i);
  }
  return ret;
}

vector<bool> used;
int f(int idx, int rest) {
  if (rest == 0) {
    VI vi;
    int res = 0;
    REP(i, 10) if (used[i]) vi.PB(i);

    do {
      int diff = 0;
      REP(i, kind) {
        if (vi[i] == 0 && ng[i]) {
          diff = -1;
          break;
        }
        diff += vi[i] * add[i];
      }
      if (diff == 0)
        ++res;
    } while (next_permutation(ALL(vi)));

    return res;
  }
  if (idx == 10)
    return 0;
  used[idx] = true;
  int res = f(idx + 1, rest - 1);
  used[idx] = false;
  res += f(idx + 1, rest);

  return res;
}

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

  pw[0] = 1;
  FOR(i, 1, 9)
  pw[i] = pw[i - 1] * 10;

  while (cin >> N, N) {
    vector<string> vs(N);
    VI sz(N);
    set<char> left, right;
    REP(i, N - 1) {
      cin >> vs[i];
      sz[i] = SZ(vs[i]);
    }
    cin >> vs[N - 1];
    sz[N - 1] = SZ(vs[N - 1]);

    REP(i, SZ(vs[N - 1])) right.insert(vs[N - 1][i]);
    REP(i, N - 1)
    REP(j, SZ(vs[i])) if (right.find(vs[i][j]) == right.end())
        left.insert(vs[i][j]);

    string uniq = "";
    for (char ch : right)
      uniq += string(1, ch);
    for (char ch : left)
      uniq += string(1, ch);
    kind = SZ(uniq);
    len = SZ(right);

    ng.assign(kind, 0);
    REP(i, N)
    if (SZ(vs[i]) > 1) {
      REP(j, SZ(uniq))
      if (vs[i][0] == uniq[j])
        ng[j] = 1;
    }

    add.assign(kind, 0);
    REP(i, kind) REP(j, N) REP(k, SZ(vs[j])) if (vs[j][k] == uniq[i]) {
      if (j < N - 1)
        add[i] += pw[sz[j] - k - 1];
      else
        add[i] -= pw[sz[j] - k - 1];
    }

    queue<int> q;
    REP(i, 10) q.push(i);
    int ans = dfs(0, q, 0);
    cout << ans << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

// include
//------------------------------------------
#include <algorithm>
#include <bitset>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

// typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

// container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i, c)                                                             \\
  for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

// repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

// constant
//--------------------------------------------
const double EPS = 1e-10;
const double PI = acos(-1.0);

int N, kind;
VI ng;
VVI tab;
int dfs(int idx, queue<int> &q, int l, int r) {
  if (idx == kind) {
    if (l == r)
      return 1;
    return 0;
  }

  int ret = 0;
  vector<bool> used(10, false);
  while (!used[q.front()]) {
    int i = q.front();
    q.pop();
    used[i] = true;
    if (i == 0 && ng[idx]) {
      q.push(i);
      continue;
    }

    int acc = 0;
    REP(j, N - 1)
    acc += i * tab[j][idx];
    l += acc;
    r += i * tab[N - 1][idx];

    ret += dfs(idx + 1, q, l, r);

    l -= acc;
    r -= i * tab[N - 1][idx];
    q.push(i);
  }
  return ret;
}

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

  int pw[9];
  pw[0] = 1;
  FOR(i, 1, 9)
  pw[i] = pw[i - 1] * 10;

  while (cin >> N, N) {
    vector<string> vs(N);
    VI sz(N);
    set<char> mem;
    REP(i, N) {
      cin >> vs[i];
      sz[i] = SZ(vs[i]);
      REP(j, SZ(vs[i]))
      mem.insert(vs[i][j]);
    }
    string uniq = "";
    for (char ch : mem)
      uniq += string(1, ch);
    kind = SZ(mem);

    ng.assign(kind, 0);
    REP(i, N)
    if (SZ(vs[i]) > 1) {
      REP(j, SZ(uniq))
      if (vs[i][0] == uniq[j])
        ng[j] = 1;
    }

    tab.assign(N, VI(kind, 0));
    REP(j, N)
    REP(i, kind) REP(k, SZ(vs[j])) if (vs[j][k] == uniq[i]) tab[j][i] +=
        pw[sz[j] - k - 1];

    queue<int> q;
    REP(i, 10) q.push(i);
    int ans = dfs(0, q, 0, 0);
    cout << ans << endl;
  }

  return 0;
}