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

#include <cstdio>
#include <cstring>

int n;
char str[16][12];
int nstr[16][10];
int flag[27], flag2[27];
int cnt, nz[11], num[27], used[11], len[11], all;

void dfs(int v) {
  if (v != all) {
    for (int i = 0; i <= 9; i++) {
      if (i == 0 && nz[v] == 1)
        continue;
      if (!used[i]) {
        used[i] = 1;
        num[v] = i;
        dfs(v + 1);
        used[i] = 0;
      }
    }
  } else {
    int ans = 0, nownum = 0;
    for (int j = 0; j < len[n - 1]; j++) {
      ans = ans * 10 + num[nstr[n - 1][j]];
    }
    for (int i = 0; i < n - 1; i++) {
      nownum = 0;
      for (int j = 0; j < len[i]; j++) {
        nownum = nownum * 10 + num[nstr[i][j]];
      }
      ans -= nownum;
      if (ans < 0)
        break;
    }
    if (ans == 0)
      cnt++;
  }
}
int main(void) {
  while (1) {
    scanf("%d", &n);
    if (n == 0)
      break;
    all = cnt = 0;
    memset(flag, 0, sizeof(flag));
    memset(nz, 0, sizeof(nz));
    memset(flag2, 0, sizeof(flag2));
    for (int i = 0; i < n; i++) {
      scanf("%s", str[i]);
      len[i] = strlen(str[i]);
      for (int j = 0; j < len[i]; j++) {
        flag[str[i][j] - 'A'] = 1;
        if (j == 0 && len[i] > 1)
          flag2[str[i][j] - 'A'] = 1;
      }
    }
    for (int i = 0; i < 26; i++) {
      if (flag[i]) {
        num[i] = all;
        if (flag2[i])
          nz[all] = 1;
        all++;
      }
    }
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < len[i]; j++) {
        nstr[i][j] = num[str[i][j] - 'A'];
      }
    }
    dfs(0);
    printf("%d\\n", cnt);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>

using namespace std;

int n;
char str[16][12];
int nstr[16][10];
int flag[27], flag2[27];
int cnt, nz[11], num[27], used[11], len[11], all;
int dd[16][10];
void dfs(int v) {
  if (v != all) {
    for (int i = 9; i >= 0; i--) {
      if (i == 0 && nz[v] == 1)
        continue;
      if (!used[i]) {
        used[i] = 1;
        num[v] = i;
        dfs(v + 1);
        used[i] = 0;
      }
    }
  } else {
    int ans = 0, nownum = 0;
    for (int j = 0; j < len[n - 1]; j++) {
      ans = ans * 10 + num[nstr[n - 1][j]];
    }
    for (int i = 0; i < n - 1; i++) {
      nownum = 0;
      for (int j = 0; j < len[i]; j++) {
        nownum = nownum * 10 + num[nstr[i][j]];
      }
      ans -= nownum;
      if (ans < 0)
        break;
    }
    if (ans == 0)
      cnt++;
  }
}
int main(void) {
  while (1) {
    scanf("%d", &n);
    if (n == 0)
      break;
    all = 0;
    cnt = 0;
    memset(flag, 0, sizeof(flag));
    memset(nz, 0, sizeof(nz));
    memset(flag2, 0, sizeof(flag2));
    for (int i = 0; i < n; i++) {
      scanf("%s", str[i]);
      len[i] = strlen(str[i]);
      for (int j = 0; j < len[i]; j++) {
        dd[i][j] = str[i][j] - 'A';
        flag[dd[i][j]] = 1;
        if (j == 0 && len[i] > 1)
          flag2[dd[i][j]] = 1;
      }
    }
    for (int i = 0; i < 26; i++) {
      if (flag[i]) {
        num[i] = all;
        if (flag2[i])
          nz[all] = 1;
        all++;
      }
    }
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < len[i]; j++) {
        nstr[i][j] = num[dd[i][j]];
      }
    }
    dfs(0);
    printf("%d\\n", cnt);
  }
  return 0;
}