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

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <set>

using namespace std;
typedef long long int lli;

lli tejun2(int s) {
  lli res = 0;

  for (lli i = 1; i < 1e7; i *= 10)
    res = max(res, (s % i) * (s / i));
  return res;
}

int main(void) {
  int q;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    int n;
    scanf("%d", &n);

    set<lli> hist;
    lli last = n;
    for (int i = 0; i < 100000; i++) {
      if (last / 10 == 0) {
        printf("%d\\n", i);
        goto BR;
      }
      if (hist.find((last = tejun2(last))) == hist.end()) {
        hist.insert(last);
      }
    }
    printf("-1\\n");
  BR:;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

vector<long long int> list, oddlist;
int listcnt, oddlistcnt;

int oddrec(int target, int sum, int cnt, int maxcnt) {
  int res = 0xFFFF;
  if (maxcnt < cnt)
    return 0xFFFE;
  if (sum == target)
    return cnt;
  for (int i = oddlistcnt - 1; 0 <= i; i--) {
    if (sum + oddlist[i] > target)
      continue;
    res = min(res, oddrec(target, sum + oddlist[i], cnt + 1, maxcnt));
    if (res == 0xFFFE)
      break;
  }
  return res;
}

int ress;
void mama(int x) {
  if (x == 0)
    return;
  int tmp[oddlistcnt];
  memset(tmp, 0, sizeof(tmp));
  for (int i = 0; i < oddlistcnt; i++) {
    tmp[i] = x / oddlist[i];
    if (tmp[i] == 0) {
      ress += tmp[i - 1];
      mama(x % tmp[i - 1]);
      break;
    }
  }
}

int main(void) {
  for (long long int i = 1; i * (i + 1) * (i + 2) / 6 < 1e6; i++) {
    list.push_back(i * (i + 1) * (i + 2) / 6);
    if (i * (i + 1) * (i + 2) / 6 % 2)
      oddlist.push_back(i * (i + 1) * (i + 2) / 6);
  }

  listcnt = list.size();
  oddlistcnt = oddlist.size();
  while (true) {
    int n;
    scanf("%d", &n);
    if (!n)
      break;

    int res = 5, oddres = 1000;
    for (int i = listcnt - 1; 0 <= i; i--) {
      if (list[i] > n)
        continue;
      if (list[i] == n) {
        res = 1;
        break;
      }
      if (res <= 2)
        continue;
      for (int j = listcnt - 1; 0 <= j; j--) {
        if (list[i] + list[j] > n)
          continue;
        if (list[i] + list[j] == n)
          res = 2;
        if (res <= 3)
          continue;
        for (int k = listcnt - 1; 0 <= k; k--) {
          if (list[i] + list[j] + list[k] > n)
            continue;
          if (list[i] + list[j] + list[k] == n)
            res = 3;
          if (res <= 4)
            continue;
          for (int l = listcnt - 1; 0 <= l; l--) {
            if (list[i] + list[j] + list[k] + list[l] > n)
              continue;
            if (list[i] + list[j] + list[k] + list[l] == n)
              res = 4;
            if (res <= 4)
              break;
          }
        }
      }
    }

    if ((oddres = oddrec(n, 0, 0, 1)) >= 0xFFFE) {
      for (int i = 2;; i = i * 3 / 2) {
        if ((oddres = oddrec(n, 0, 0, i)) < 0xFFFE)
          break;
      }
    }

    printf("%d %d\\n", res, oddres);
    /*
            ress=0;
            mama(n);
            printf("%d %d\\n",res,ress);*/
  }

  return 0;
}