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

#include <algorithm>
#include <bitset>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#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;

#define REP(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) REP(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define mp make_pair
#define pb push_back
#define EPS 1e-8
#define DEB 0
int alpha[256], check[256], least[256];
int used[10];
vector<char> nonzero;
vector<pair<int, char>> piece;

#if DEB
stack<pair<int, int>> spi;
#endif

bool ok(char n) {
  rep(i, nonzero.size()) if (nonzero[i] == n) return false;
  return true;
}

int solve(int cnt, int sum) {
  if (cnt > piece.size())
    return 0;
  if (cnt == piece.size()) {
#if DEB
    if (sum == 0) {
      stack<pair<int, int>> tmp = spi;
      while (!tmp.empty()) {
        printf("%c:%d\\n", (char)tmp.top().first, tmp.top().second);
        tmp.pop();
      }
      puts("------------------");
    }
#endif
    return sum == 0;
  }
  int minn = 9, maxn = 0;
  rep(num, 10) if (!used[num]) {
    minn = min(minn, num);
    maxn = max(maxn, num);
  }
  int lower = 0, upper = 0;
  for (int i = cnt; i < piece.size(); i++) {
    if (piece[i].first > 0) {
      upper += piece[i].first * maxn;
      lower += piece[i].first * minn;
    } else {
      upper += piece[i].first * minn;
      lower += piece[i].first * maxn;
    }
  }
  if (sum + upper < 0 || 0 < sum + lower)
    return 0;
  // printf("lower, upper = %d, %d\\n",lower,upper);

  int ret = 0;
  rep(num, 10) if (!used[num]) {
    if (num == 0) {
      if (!ok(piece[cnt].second))
        continue;
    }
    used[num] = 1;
#if DEB
    spi.push(mp(piece[cnt].second, num));
#endif
    ret += solve(cnt + 1, sum + piece[cnt].first * num);

#if DEB
    spi.pop();
#endif

    used[num] = 0;
  }
  return ret;
}

int main() {
  int n, sz, k;
  char str[16];

  while (scanf("%d", &n), n) {
    piece.clear();
    nonzero.clear();
    rep(i, 256) alpha[i] = check[i] = least[i] = 0;
    memset(used, 0, sizeof(used));

    rep(i, n - 1) {
      scanf("%s", str);
      sz = strlen(str);
      k = 1;
      if (sz > 1) {
        least[str[0]] = 1;
      }
      rep(j, sz) {
        alpha[str[sz - j - 1]] += k;
        check[str[sz - j - 1]] = 1;
        k *= 10;
      }
    }
    scanf("%s", str);
    sz = strlen(str);
    k = 1;
    if (sz > 1) {
      least[str[0]] = 1;
    }
    rep(j, sz) {
      alpha[str[sz - j - 1]] -= k;
      check[str[sz - j - 1]] = 1;
      k *= 10;
    }

#if DEB
    rep(i, 256) if (alpha[i] != 0) {
      printf("%c : %d\\n", (unsigned char)i, alpha[i]);
    }
#endif
    rep(i, 256) if (check[i] != 0) { piece.push_back(mp(alpha[i], (char)i)); }
    sort(all(piece));
    rep(i, 256) if (least[i] != 0) { nonzero.push_back((char)i); }

    printf("%d\\n", solve(0, 0));
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#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;

#define REP(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) REP(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define mp make_pair
#define pb push_back
#define EPS 1e-8
#define DEB 0
int alpha[256], check[256], least[256];
int used[10];
vector<int> piece, nonzero;

#if DEB
stack<pair<int, int>> spi;
#endif

bool ok(int n) {
  rep(i, nonzero.size()) if (nonzero[i] == n) return false;
  return true;
}

int solve(int cnt, int sum) {
  if (cnt > piece.size())
    return 0;
  if (cnt == piece.size()) {
#if DEB
    if (sum == 0) {
      stack<pair<int, int>> tmp = spi;
      while (!tmp.empty()) {
        printf("%c:%d\\n", (char)tmp.top().first, tmp.top().second);
        tmp.pop();
      }
      puts("------------------");
    }
#endif
    return sum == 0;
  }

  int ret = 0;
  rep(num, 10) if (!used[num]) {
    if (num == 0) {
      if (!ok(piece[cnt]))
        continue;
    }
    used[num] = 1;
#if DEB
    spi.push(mp(piece[cnt], num));
#endif
    ret += solve(cnt + 1, sum + alpha[piece[cnt]] * num);

#if DEB
    spi.pop();
#endif

    used[num] = 0;
  }
  return ret;
}
int main() {
  int n, sz, k;
  char str[16];

  while (scanf("%d", &n), n) {
    piece.clear();
    nonzero.clear();
    rep(i, 256) alpha[i] = check[i] = least[i] = 0;
    memset(used, 0, sizeof(used));

    rep(i, n - 1) {
      scanf("%s", str);
      sz = strlen(str);
      k = 1;
      if (sz > 1) {
        least[str[0]] = 1;
      }
      rep(j, sz) {
        alpha[str[sz - j - 1]] += k;
        check[str[sz - j - 1]] = 1;
        k *= 10;
      }
    }
    scanf("%s", str);
    sz = strlen(str);
    k = 1;
    if (sz > 1) {
      least[str[0]] = 1;
    }
    rep(j, sz) {
      alpha[str[sz - j - 1]] -= k;
      check[str[sz - j - 1]] = 1;
      k *= 10;
    }

#if DEB
    rep(i, 256) if (alpha[i] != 0) {
      printf("%c : %d\\n", (unsigned char)i, alpha[i]);
    }
#endif
    rep(i, 256) if (check[i] != 0) { piece.push_back(i); }
    rep(i, 256) if (least[i] != 0) { nonzero.push_back(i); }

    printf("%d\\n", solve(0, 0));
  }
  return 0;
}