Problem p00742 (C++) — buggy submission, verdict: Runtime Error


// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1161&lang=jp

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <numeric>
#include <vector>

#define ALL(v) (v).begin(), (v).end()
#define REP(i, p, n) for (int i = p; i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define dump(a) (cerr << #a << "=" << (a) << endl)
#define DUMP(list)                                                             \\
  cout << "{ ";                                                                \\
  for (auto nth : list) {                                                      \\
    cout << nth << " ";                                                        \\
  }                                                                            \\
  cout << "}" << endl;

using namespace std;

vector<int> coefficient;
vector<bool> is_top;

int dfs(int m, int depth, int used, int value) {
  if (depth == m)
    return ((value == 0) ? 1 : 0);

  int ret = 0;
  rep(i, 10) {
    if (is_top[depth] && i == 0)
      continue;
    if (used & (1 << i))
      continue;
    ret += dfs(m, depth + 1, used | (1 << i), value + coefficient[depth] * i);
  }
  return ret;
}

int main() {
  int n;
  while (cin >> n, n) {
    map<char, int> converter;

    // アルファベットの種類を数える
    vector<string> s(n, "");
    rep(i, n) {
      cin >> s[i];
      rep(j, s[i].size()) {
        if (!converter.count(s[i][j]))
          converter.insert(make_pair(s[i][j], converter.size()));
      }
    }

    // 各アルファベットの係数と先頭にあるかを求める
    int m = converter.size();
    coefficient.assign(m, 0);
    is_top.assign(m, false);
    rep(i, n) {
      for (int j = s[i].size() - 1, k = 1; j >= 0; --j, k *= 10) {
        int ctoi = converter[s[i][j]];
        if (j == 0 && s[i].size() > 1)
          is_top[ctoi] = true;
        coefficient[ctoi] += (i == n - 1) ? -k : k;
      }
    }

    // 覆面算が成り立つ式を満たす組み合わせを探索
    cout << dfs(m, 0, 0, 0) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:


// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1161&lang=jp

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <numeric>
#include <vector>

#define ALL(v) (v).begin(), (v).end()
#define REP(i, p, n) for (int i = p; i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define dump(a) (cerr << #a << "=" << (a) << endl)
#define DUMP(list)                                                             \\
  cout << "{ ";                                                                \\
  for (auto nth : list) {                                                      \\
    cout << nth << " ";                                                        \\
  }                                                                            \\
  cout << "}" << endl;

using namespace std;

vector<int> coefficient;
vector<bool> is_top;

int dfs(int m, int depth, int used, int value) {
  if (depth == m)
    return ((value == 0) ? 1 : 0);

  int ret = 0;
  rep(i, 10) {
    if (is_top[depth] && i == 0)
      continue;
    if (used & (1 << i))
      continue;
    ret += dfs(m, depth + 1, used | (1 << i), value + coefficient[depth] * i);
  }
  return ret;
}

int main() {
  int n;
  while (cin >> n, n) {
    map<char, int> converter;

    // アルファベットの種類を数える
    vector<string> s(n, "");
    rep(i, n) {
      cin >> s[i];
      rep(j, s[i].size()) {
        if (!converter.count(s[i][j]))
          converter[s[i][j]] = converter.size();
      }
    }

    // 各アルファベットの係数と先頭にあるかを求める
    int m = converter.size();
    coefficient.assign(m, 0);
    is_top.assign(m, false);
    rep(i, n) {
      for (int j = s[i].size() - 1, k = 1; j >= 0; --j, k *= 10) {
        int ctoi = converter[s[i][j]];
        if (j == 0 && s[i].size() > 1)
          is_top[ctoi] = true;
        coefficient[ctoi] += (i == n - 1) ? -k : k;
      }
    }

    // 覆面算が成り立つ式を満たす組み合わせを探索
    cout << dfs(m, 0, 0, 0) << endl;
  }
  return 0;
}