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

#include <bits/stdc++.h>
#define double long double
#define int long long
using namespace std;

typedef pair<int, int> P;
typedef pair<string, string> P1;
typedef pair<int, string> P2;
typedef pair<P, P2> P3;

int fac(int n) {
  int res = 1;
  for (int i = 1; i <= n; i++)
    res *= i;
  return res;
}

double get(int i) {
  return fac(8) * pow(1.0 / 4, i) * pow(3.0 / 4, 8 - i) / (fac(i) * fac(8 - i));
}

string s[5];
string target;
double ans;

vector<P3> calcOrder(set<string> teams) {

  map<string, int> points, diff, ggoals;

  for (int i = 0; i < 5; i++) {

    for (int j = 0; j < (int)s[i].size(); j++) {

      if (s[i][j] != '-')
        continue;

      string t1 = s[i].substr(1, 3);
      string t2 = s[0].substr(j - 1, 3);

      if (teams.count(t1) == 0)
        continue;
      if (teams.count(t2) == 0)
        continue;

      int t1p = s[i][j - 1] - '0';
      int t2p = s[i][j + 1] - '0';

      if (t1p > t2p)
        points[t1] += 3;
      if (t1p == t2p)
        points[t1]++, points[t2]++;
      if (t1p < t2p)
        points[t2] += 3;

      diff[t1] += t1p - t2p;
      diff[t2] += t2p - t1p;

      ggoals[t1] += t1p;
      ggoals[t2] += t2p;
    }
  }

  vector<P3> res;

  for (string team : teams) {
    res.push_back(P3(P(points[team], diff[team]), P2(ggoals[team], team)));
  }

  sort(res.begin(), res.end(), greater<P3>());

  return res;
}

void cal(double p) {

  set<string> teams;

  for (int i = 0; i < 5; i++) {

    for (int j = 0; j < (int)s[i].size(); j++) {

      if (s[i][j] != '-')
        continue;

      string t1 = s[i].substr(1, 3);
      string t2 = s[0].substr(j - 1, 3);

      teams.insert(t1);
      teams.insert(t2);
    }
  }

  vector<P3> order = calcOrder(teams);

  int cnt = 5, add = 0, L, R;

  while (cnt--) {

    int A, B, C;

    for (int i = 0; i < (int)order.size(); i++) {

      if (order[i].second.second == target) {
        A = order[i].first.first;
        B = order[i].first.second;
        C = order[i].second.first;
      }
    }

    int l = 4, r = 0;

    for (int i = 0; i < (int)order.size(); i++) {

      if (A == order[i].first.first && B == order[i].first.second &&
          C == order[i].second.first) {

        l = min(l, i);
        r = max(r, i);
      }
    }

    teams.clear();

    for (int i = l; i <= r; i++)
      teams.insert(order[i].second.second);

    add += l;

    L = l, R = r;

    order = calcOrder(teams);
  }

  if (L == R) {

    if (add <= 1)
      ans += p;

  } else {

    if (add <= 1) {

      double chance = 1 - add + 1;
      double all = R - L + 1;

      ans += p * chance / all;
    }
  }
}

vector<P> YX;

signed main() {

  int T;
  cin >> T;

  while (T--) {

    YX.clear();
    ans = 0;

    for (int i = 0; i < 5; i++)
      cin >> s[i];

    for (int i = 0; i < (int)s[0].size(); i++) {
      if (s[0][i] == '*')
        target = s[0].substr(i + 1, 3);
    }

    for (int i = 0; i < 5; i++) {
      for (int j = 0; j < (int)s[i].size(); j++) {
        if (s[i][j] == '-' && s[i][j - 1] == '_')
          YX.push_back(P(i, j - 1));

        if (s[i][j] == '-' && s[i][j + 1] == '_')
          YX.push_back(P(i, j + 1));
      }
    }

    for (int i = 0; i <= 8; i++) {
      for (int j = 0; j <= 8; j++) {
        for (int k = 0; k <= 8; k++) {
          for (int l = 0; l <= 8; l++) {

            s[YX[0].first][YX[0].second] = i + '0';
            s[YX[1].first][YX[1].second] = j + '0';
            s[YX[2].first][YX[2].second] = k + '0';
            s[YX[3].first][YX[3].second] = l + '0';

            cal(get(i) * get(j) * get(k) * get(l));
          }
        }
      }
    }

    printf("%.7Lf\\n", ans);
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define double long double
#define int long long
using namespace std;

typedef pair<int, int> P;
typedef pair<string, string> P1;
typedef pair<int, string> P2;
typedef pair<P, P2> P3;

int fac(int n) {
  int res = 1;
  for (int i = 1; i <= n; i++)
    res *= i;
  return res;
}

double get(int i) {
  return fac(8) * pow(1.0 / 4, i) * pow(3.0 / 4, 8 - i) / (fac(i) * fac(8 - i));
}

string s[5];
string target;
double ans;

vector<P3> calcOrder(set<string> teams) {

  map<string, int> points, diff, ggoals;

  for (int i = 0; i < 5; i++) {

    for (int j = 0; j < (int)s[i].size(); j++) {

      if (s[i][j] != '-')
        continue;

      string t1 = s[i].substr(1, 3);
      string t2 = s[0].substr(j - 1, 3);

      if (teams.count(t1) == 0)
        continue;
      if (teams.count(t2) == 0)
        continue;

      int t1p = s[i][j - 1] - '0';
      int t2p = s[i][j + 1] - '0';

      if (t1p > t2p)
        points[t1] += 3;
      if (t1p == t2p)
        points[t1]++, points[t2]++;
      if (t1p < t2p)
        points[t2] += 3;

      diff[t1] += t1p - t2p;
      diff[t2] += t2p - t1p;

      ggoals[t1] += t1p;
      ggoals[t2] += t2p;
    }
  }

  vector<P3> res;

  for (string team : teams) {
    res.push_back(P3(P(points[team], diff[team]), P2(ggoals[team], team)));
  }

  sort(res.begin(), res.end(), greater<P3>());

  return res;
}

void cal(double p) {

  set<string> teams;

  for (int i = 0; i < 5; i++) {

    for (int j = 0; j < (int)s[i].size(); j++) {

      if (s[i][j] != '-')
        continue;

      string t1 = s[i].substr(1, 3);
      string t2 = s[0].substr(j - 1, 3);

      teams.insert(t1);
      teams.insert(t2);
    }
  }

  vector<P3> order = calcOrder(teams);

  int cnt = 10, add = 0, L, R;

  while (cnt--) {

    int A, B, C;

    for (int i = 0; i < (int)order.size(); i++) {

      if (order[i].second.second == target) {
        A = order[i].first.first;
        B = order[i].first.second;
        C = order[i].second.first;
      }
    }

    int l = 4, r = 0;

    for (int i = 0; i < (int)order.size(); i++) {

      if (A == order[i].first.first && B == order[i].first.second &&
          C == order[i].second.first) {

        l = min(l, i);
        r = max(r, i);
      }
    }

    teams.clear();

    for (int i = l; i <= r; i++)
      teams.insert(order[i].second.second);

    add += l;

    L = l, R = r;

    order = calcOrder(teams);
  }

  if (L == R) {

    if (add <= 1)
      ans += p;

  } else {

    if (add <= 1) {

      double chance = 1 - add + 1;
      double all = R - L + 1;

      ans += p * chance / all;
    }
  }
}

vector<P> YX;

signed main() {

  int T;
  cin >> T;

  while (T--) {

    YX.clear();
    ans = 0;

    for (int i = 0; i < 5; i++)
      cin >> s[i];

    for (int i = 0; i < (int)s[0].size(); i++) {
      if (s[0][i] == '*')
        target = s[0].substr(i + 1, 3);
    }

    for (int i = 0; i < 5; i++) {
      for (int j = 0; j < (int)s[i].size(); j++) {
        if (s[i][j] == '-' && s[i][j - 1] == '_')
          YX.push_back(P(i, j - 1));

        if (s[i][j] == '-' && s[i][j + 1] == '_')
          YX.push_back(P(i, j + 1));
      }
    }

    for (int i = 0; i <= 8; i++) {
      for (int j = 0; j <= 8; j++) {
        for (int k = 0; k <= 8; k++) {
          for (int l = 0; l <= 8; l++) {

            s[YX[0].first][YX[0].second] = i + '0';
            s[YX[1].first][YX[1].second] = j + '0';
            s[YX[2].first][YX[2].second] = k + '0';
            s[YX[3].first][YX[3].second] = l + '0';

            cal(get(i) * get(j) * get(k) * get(l));
          }
        }
      }
    }

    printf("%.7Lf\\n", ans);
  }

  return 0;
}