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

#include <bits/stdc++.h>
using namespace std;

#define int long long
#define MAX2 47
#define MAX5 23
int g[10][MAX2][MAX5];
char s[20];

int32_t main() {
  memset(g, 0, sizeof g);
  int pot10[10];
  pot10[0] = 1;
  for (int i = 1; i <= 9; ++i)
    pot10[i] = pot10[i - 1] * 10;

  int n;
  scanf("%lld", &n);

  int ans = 0;
  for (int i = 0; i < n; ++i) {
    scanf("%s", s);
    string a, b;
    bool ponto = false;
    for (int j = 0; s[j]; ++j) {
      if (s[j] == '.')
        ponto = true;
      else {
        if (!ponto)
          a.push_back(s[j]);
        else
          b.push_back(s[j]);
      }
    }
    string c = a + b;

    int x = stoll(c);
    int qntdFats2 = 0;
    int qntdFats5 = 0;

    while (x) {
      if (x % 2 == 0) {
        qntdFats2++;
        x /= 2;
      } else if (x % 5 == 0) {
        qntdFats5++;
        x /= 5;
      } else {
        break;
      }
    }

    int numCasas = b.size();
    int qntdZeros = min(qntdFats2, qntdFats5);
    if (numCasas > 0 && qntdZeros > 0) {
      qntdFats2 -= min(numCasas, qntdZeros);
      qntdFats5 -= min(numCasas, qntdZeros);
      numCasas -= min(numCasas, qntdZeros);
    }

    // cerr << "String fats2 fats5 casas\\n";
    // cerr << s << " " << qntdFats2 << " " << qntdFats5 << " " << numCasas <<
    // endl;

    // query
    // se numCasas > 0, ou qntdFats2 > 0 ou qntdFats5 > 0
    // quero
    for (int i = 0; i < MAX2; ++i) {
      for (int j = 0; j < MAX5; ++j) {
        // i + qntdFats2 eh a qntd de fats2 no prod
        // j + qntdFats5 eh a qntd de fats5 no prod
        for (int k = 0; k < 10; ++k) {
          if (g[k][i][j] == 0)
            continue;
          int prodFats2 = i + qntdFats2;
          int prodFats5 = j + qntdFats5;
          int casas = numCasas + k;
          // cerr << casas << " " << prodFats2 << " " << prodFats5 << endl;
          // cerr << g[k][i][j] << endl;
          if (min(prodFats2, prodFats5) >= casas)
            ans += g[k][i][j];
        }
      }
    }

    // update
    for (int i = qntdFats2; i <= qntdFats2; ++i) {
      for (int j = qntdFats5; j <= qntdFats5; ++j) {
        g[numCasas][i][j]++;
      }
    }
  }
  printf("%lld\\n", ans);
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define int long long
#define MAX2 50
#define MAX5 30
int g[10][MAX2][MAX5];
char s[20];

int32_t main() {
  memset(g, 0, sizeof g);
  int pot10[10];
  pot10[0] = 1;
  for (int i = 1; i <= 9; ++i)
    pot10[i] = pot10[i - 1] * 10;

  int n;
  scanf("%lld", &n);

  int ans = 0;
  for (int i = 0; i < n; ++i) {
    scanf("%s", s);
    string a, b;
    bool ponto = false;
    for (int j = 0; s[j]; ++j) {
      if (s[j] == '.')
        ponto = true;
      else {
        if (!ponto)
          a.push_back(s[j]);
        else
          b.push_back(s[j]);
      }
    }
    string c = a + b;

    int x = stoll(c);
    int qntdFats2 = 0;
    int qntdFats5 = 0;

    while (x) {
      if (x % 2 == 0) {
        qntdFats2++;
        x /= 2;
      } else if (x % 5 == 0) {
        qntdFats5++;
        x /= 5;
      } else {
        break;
      }
    }

    int numCasas = b.size();
    int qntdZeros = min(qntdFats2, qntdFats5);
    if (numCasas > 0 && qntdZeros > 0) {
      qntdFats2 -= min(numCasas, qntdZeros);
      qntdFats5 -= min(numCasas, qntdZeros);
      numCasas -= min(numCasas, qntdZeros);
    }

    // cerr << "String fats2 fats5 casas\\n";
    // cerr << s << " " << qntdFats2 << " " << qntdFats5 << " " << numCasas <<
    // endl;

    // query
    // se numCasas > 0, ou qntdFats2 > 0 ou qntdFats5 > 0
    // quero
    for (int i = 0; i < MAX2; ++i) {
      for (int j = 0; j < MAX5; ++j) {
        // i + qntdFats2 eh a qntd de fats2 no prod
        // j + qntdFats5 eh a qntd de fats5 no prod
        for (int k = 0; k < 10; ++k) {
          if (g[k][i][j] == 0)
            continue;
          int prodFats2 = i + qntdFats2;
          int prodFats5 = j + qntdFats5;
          int casas = numCasas + k;
          // cerr << casas << " " << prodFats2 << " " << prodFats5 << endl;
          // cerr << g[k][i][j] << endl;
          if (min(prodFats2, prodFats5) >= casas)
            ans += g[k][i][j];
        }
      }
    }

    // update
    for (int i = qntdFats2; i <= qntdFats2; ++i) {
      for (int j = qntdFats5; j <= qntdFats5; ++j) {
        g[numCasas][i][j]++;
      }
    }
  }
  printf("%lld\\n", ans);
}