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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

int answerNum(vector<pair<int, bool>> plus, vector<pair<int, bool>> minus,
              int total, vector<bool> &used) {
  if (plus.size() == 0 && minus.size() == 0) {
    if (total == 0)
      return 1;
    else
      return 0;
  }

  int tmp = total;
  int a = -1;
  for (unsigned i = 0; i < plus.size(); ++i) {
    while (used[++a])
      ;
    tmp += plus[i].first * a;
  }
  a = 10;
  for (unsigned i = 0; i < minus.size(); ++i) {
    while (used[--a])
      ;
    tmp += minus[i].first * a;
  }
  if (tmp > 0)
    return 0;

  tmp = total;
  a = 10;
  for (unsigned i = 0; i < plus.size(); ++i) {
    while (used[--a])
      ;
    tmp += plus[i].first * a;
  }
  a = -1;
  for (unsigned i = 0; i < minus.size(); ++i) {
    while (used[++a])
      ;
    tmp += minus[i].first * a;
  }
  if (tmp < 0)
    return 0;

  bool isNonZero;
  if (minus.size() == 0 ||
      (plus.size() > 0 && plus[0].first > -minus[0].first)) {
    a = plus[0].first;
    isNonZero = plus[0].second;
    plus.erase(plus.begin());
  } else {
    a = minus[0].first;
    isNonZero = minus[0].second;
    minus.erase(minus.begin());
  }

  int answer = 0;
  for (int i = (isNonZero ? 1 : 0); i < 10; ++i) {
    if (!used[i]) {
      used[i] = true;
      answer += answerNum(plus, minus, total + a * i, used);
      used[i] = false;
    }
  }
  return answer;
}

void solve(vector<string> &mask) {
  vector<int> num(26, 0);
  vector<bool> isUsed(26, false);
  vector<bool> isNonZero(26, false);
  for (unsigned i = 0; i < mask.size(); ++i) {
    int tmp = 1;
    for (int j = mask[i].size() - 1; j >= 0; --j) {
      if (i < mask.size() - 1)
        num[mask[i][j] - 'A'] += tmp;
      else
        num[mask[i][j] - 'A'] -= tmp;
      tmp *= 10;
      isUsed[mask[i][j] - 'A'] = true;
    }
    if (mask[i].size() > 1)
      isNonZero[mask[i][0] - 'A'] = true;
  }

  vector<pair<int, bool>> plus;
  vector<pair<int, bool>> minus;
  for (int i = 0; i < 26; ++i) {
    if (isUsed[i]) {
      if (num[i] >= 0)
        plus.push_back(make_pair(num[i], isNonZero[i]));
      if (num[i] < 0)
        minus.push_back(make_pair(num[i], isNonZero[i]));
    }
  }
  sort(plus.rbegin(), plus.rend());
  sort(minus.begin(), minus.end());

  vector<bool> used(10, false);
  cout << answerNum(plus, minus, 0, used) << endl;
}

int main() {
  for (;;) {
    int n;
    cin >> n;
    if (n == 0)
      break;

    vector<string> mask(n);
    for (int i = 0; i < n; ++i) {
      cin >> mask[i];
    }

    solve(mask);
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

int answerNum(vector<pair<int, bool>> plus, vector<pair<int, bool>> minus,
              int total, vector<bool> &used) {
  if (plus.size() == 0 && minus.size() == 0) {
    if (total == 0)
      return 1;
    else
      return 0;
  }

  int tmp = total;
  int a = 10;
  for (unsigned i = 0; i < plus.size(); ++i) {
    while (used[--a])
      ;
    tmp += plus[i].first * a;
  }
  a = -1;
  for (unsigned i = 0; i < minus.size(); ++i) {
    while (used[++a])
      ;
    tmp += minus[i].first * a;
  }
  if (tmp < 0)
    return 0;

  bool isNonZero;
  if (minus.size() == 0 ||
      (plus.size() > 0 && plus[0].first > -minus[0].first)) {
    a = plus[0].first;
    isNonZero = plus[0].second;
    plus.erase(plus.begin());
  } else {
    a = minus[0].first;
    isNonZero = minus[0].second;
    minus.erase(minus.begin());
  }

  int answer = 0;
  for (int i = (isNonZero ? 1 : 0); i < 10; ++i) {
    if (!used[i]) {
      used[i] = true;
      answer += answerNum(plus, minus, total + a * i, used);
      used[i] = false;
    }
  }
  return answer;
}

void solve(vector<string> &mask) {
  vector<int> num(26, 0);
  vector<bool> isUsed(26, false);
  vector<bool> isNonZero(26, false);
  for (unsigned i = 0; i < mask.size(); ++i) {
    int tmp = 1;
    for (int j = mask[i].size() - 1; j >= 0; --j) {
      if (i < mask.size() - 1)
        num[mask[i][j] - 'A'] += tmp;
      else
        num[mask[i][j] - 'A'] -= tmp;
      tmp *= 10;
      isUsed[mask[i][j] - 'A'] = true;
    }
    if (mask[i].size() > 1)
      isNonZero[mask[i][0] - 'A'] = true;
  }

  vector<pair<int, bool>> plus;
  vector<pair<int, bool>> minus;
  for (int i = 0; i < 26; ++i) {
    if (num[i] > 0)
      plus.push_back(make_pair(num[i], isNonZero[i]));
    if (num[i] < 0)
      minus.push_back(make_pair(num[i], isNonZero[i]));
  }
  sort(plus.rbegin(), plus.rend());
  sort(minus.begin(), minus.end());

  vector<bool> used(10, false);
  int answer = answerNum(plus, minus, 0, used);
  int a = 26 - count(num.begin(), num.end(), 0);
  int b = count(isUsed.begin(), isUsed.end(), true) - a;
  for (int i = 0; i < b; ++i)
    answer *= 10 - a - i;
  cout << answer << endl;
}

int main() {
  for (;;) {
    int n;
    cin >> n;
    if (n == 0)
      break;

    vector<string> mask(n);
    for (int i = 0; i < n; ++i) {
      cin >> mask[i];
    }

    solve(mask);
  }

  return 0;
}