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

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

bool isHead[10];
int var[10], coe[10];
vector<char> ch;

typedef pair<int, int> P; // first=sum, second=state
vector<P> va, vb;

void solve(int dep, int st, int en, int sum, int state) {
  if (dep > en) {
    if (st == 0)
      va.push_back(P(sum, state));
    else
      vb.push_back(P(sum, state));
  } else { // coe[dep] の係数をiとする
    for (int i = 0; i < 10; i++) {
      if (!i && isHead[dep])
        ++i;

      int nState = state | (1 << i);
      if (nState == state)
        continue;
      solve(dep + 1, st, en, sum + coe[dep] * i, nState);
    }
  }
}

int main() {
  int n, ans;
  string s;

  while (cin >> n && n) {
    ch.clear();
    for (int j = 0; j < 10; j++) {
      coe[j] = 0;
      isHead[j] = false;
    }

    for (int i = 1; i < n; i++) {
      cin >> s;
      for (int j = s.length() - 1, k = 1, l; j >= 0; j--, k *= 10) {
        for (l = 0; l < (int)ch.size() && ch[l] != s[j]; l++)
          ;
        if (l == (int)ch.size())
          ch.push_back(s[j]);
        coe[l] += k;
        if (j == 0 && s.length() > 1)
          isHead[l] = true;
      }
    }
    cin >> s; // 右辺の文字列
    for (int j = s.length() - 1, k = 1, l; j >= 0; j--, k *= 10) {
      for (l = 0; l < (int)ch.size() && ch[l] != s[j]; l++)
        ;
      if (l == (int)ch.size())
        ch.push_back(s[j]);
      coe[l] -= k;
      if (j == 0 && s.length() > 1)
        isHead[l] = true;
    }

    bool f;
    do {
      f = false;
      for (unsigned int i = 1; i < ch.size(); i++) {
        if (coe[i - 1] < coe[i]) {
          swap(coe[i - 1], coe[i]);
          swap(isHead[i - 1], isHead[i]);
          f = true;
        }
      }
    } while (f);

    va.clear();
    vb.clear();
    int l = ch.size() / 2;
    solve(0, 0, l - 1, 0,
          0); // solve( int dep, int st, int en, int sum, int state)
    solve(l, l, ch.size() - 1, 0, 0);

    /*
    cout << "ch.size="<<ch.size()
         << " va.size="<<va.size() << " vb.size="<<vb.size()
         << " l="<<l<<endl;
    */

    sort(va.begin(), va.end());
    sort(vb.begin(), vb.end());

    ans = 0;
    vector<P>::iterator it;
    for (unsigned int i = 0; i < va.size(); i++) {
      // vb を二分探索
      int vai = -va[i].first;
      it = lower_bound(vb.begin(), vb.end(), P(vai, 0));

      while (it != vb.end()) {
        P p = *it;
        if (p.first != vai)
          break;
        if (va[i].second & p.second) {
        } else
          ans++;
        it++;
      }
    }
    cout << ans << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <vector>
using namespace std;

bool isHead[10];
int var[10];
int coe[10];
vector<char> ch;

int ans;
void solve(int depth, int sum) {
  if (depth == (int)ch.size()) {
    if (sum == 0)
      ans++;

  } else {
    if (sum < 0 && coe[depth] < 0) // sum>0 とならない。減る一方
      return;
    for (int i = 0, j; i < 10; i++) {
      if (i == 0 && isHead[depth])
        ++i; // 先頭が0
      for (j = 0; j < depth && var[j] != i; j++)
        ;
      if (j != depth)
        continue;
      var[depth] = i;

      solve(depth + 1, sum + coe[depth] * var[depth]);
    }
  }
}

int main() {
  int n;
  string s;

  while (cin >> n && n) {
    ch.clear();
    for (int j = 0; j < 10; j++) {
      coe[j] = 0;
      isHead[j] = false;
    }

    for (int i = 1; i < n; i++) {
      cin >> s;
      for (int j = s.length() - 1, k = 1, l; j >= 0; j--, k *= 10) {
        for (l = 0; l < (int)ch.size() && ch[l] != s[j]; l++)
          ;
        if (l == (int)ch.size())
          ch.push_back(s[j]);
        coe[l] += k;
        if (j == 0 && s.length() > 1)
          isHead[l] = true;
      }
    }
    cin >> s; // 右辺の文字列
    for (int j = s.length() - 1, k = 1, l; j >= 0; j--, k *= 10) {
      for (l = 0; l < (int)ch.size() && ch[l] != s[j]; l++)
        ;
      if (l == (int)ch.size())
        ch.push_back(s[j]);
      coe[l] -= k;
      if (j == 0 && s.length() > 1)
        isHead[l] = true;
    }

    bool f;
    do {
      f = false;
      for (unsigned int i = 1; i < ch.size(); i++) {
        if (coe[i - 1] < coe[i]) {
          swap(coe[i - 1], coe[i]);
          swap(isHead[i - 1], isHead[i]);
          f = true;
        }
      }
    } while (f);

    /*
    cout << "\\nunknown chars : "<< ch.size() << endl;
    for( unsigned int i=0;i<ch.size();i++ )
      cout << ch[i] << " ";
    cout << endl;

    for( unsigned int i=0;i<ch.size();i++ )
      if( isHead[i] ) cout << "T ";
      else cout <<"F ";
    cout << endl;

    for( unsigned int i=0;i<ch.size();i++ )
      cout << coe[i] << " ";
    cout << endl;
    */

    ans = 0;
    solve(0, 0);
    cout << ans << endl;
  }

  return 0;
}