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

#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long;
using P = pair<int, int>;

double comb(int n, int k) {
  if (n < k || k < 0)
    return 0;
  double res = 1;
  for (int i = 1; i <= k; i++) {
    res *= n - i + 1;
    res /= i;
  }
  return res;
}

using Q = vector<vector<int>>;

vector<Q> ty[8];

int n, m, l;
P pat[7];

int buf[66];

bool match2(int a, int b, int c) {
  int d[3] = {a, b, c};
  static int bu2[66];
  copy_n(buf, 66, bu2);
  for (int i = 0; i < l; i++) {
    if (pat[i].first == -1)
      continue;
    int u = d[pat[i].first] + pat[i].second;
    if (bu2[u] == 0)
      return false;
    bu2[u]--;
  }
  return true;
}

int co;
bool match() {
  for (int a = 0; a < co; a++) {
    for (int b = 0; b < co; b++) {
      for (int c = 0; c < co; c++) {
        if (match2(a, b, c))
          return true;
      }
    }
  }
  return false;
}

double calc() {
  double sm = 0;
  for (auto t : ty[l]) {
    // printf("pattern:\\n");
    // for (auto v: t) {
    //     for (auto d: v) {
    //         printf("%d ", d);
    //     }
    //     printf("\\n");
    // }
    // printf("patend\\n");
    fill_n(buf, 66, 0);
    co = 0;
    int vs = 0;
    for (auto v : t) {
      vs += (int)v.size();
      for (auto d : v) {
        buf[co++] = d;
      }
      co++;
    }
    co--;
    //        printf("patco: %d m: %d\\n", co, m);
    if (m < co)
      continue;
    if (!match())
      continue;
    //        printf("matched!\\n");
    double re = 1.0;
    for (int i = 0; i < m; i++) {
      re *= comb(n, buf[i]);
    }
    re *= comb(m + 1 - vs, t.size());
    sm += re;
  }
  return sm / comb(n * m, l);
}

bool solve() {
  cin >> n >> m >> l;
  if (n == 0)
    return false;
  for (int i = 0; i < l; i++) {
    string s;
    cin >> s;
    if (s[0] == '*') {
      pat[i] = P(-1, 0);
    } else {
      pat[i].first = s[0] - 'a';
      pat[i].second = s.size() - 1;
    }
    //        printf("te %d %d\\n", pat[i].first, pat[i].second);
  }
  printf("%.20lf\\n", calc());
  return true;
}

Q base[8];

int main() {
  base[0].push_back(vector<int>());
  for (int i = 1; i <= 7; i++) {
    for (int k = 1; k <= i; k++) {
      for (auto v : base[i - k]) {
        v.push_back(k);
        base[i].push_back(v);
      }
    }
  }

  ty[0].push_back(Q());
  for (int i = 1; i <= 7; i++) {
    for (int k = 1; k <= i; k++) {
      for (auto q : ty[i - k]) {
        for (auto b : base[k]) {
          auto qq = q;
          qq.push_back(b);
          ty[i].push_back(qq);
        }
      }
    }
    //        printf("%lu\\n", ty[i].size());
  }

  while (solve()) {
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long;
using P = pair<int, int>;

double comb(int n, int k) {
  if (n < k || k < 0)
    return 0;
  double res = 1;
  for (int i = 1; i <= k; i++) {
    res *= n - i + 1;
    res /= i;
  }
  return res;
}

using Q = vector<vector<int>>;

vector<Q> ty[8];

int n, m, l;
P pat[7];

int buf[66];

bool match2(int a, int b, int c) {
  int d[3] = {a, b, c};
  static int bu2[66];
  copy_n(buf, 66, bu2);
  for (int i = 0; i < l; i++) {
    if (pat[i].first == -1)
      continue;
    int u = d[pat[i].first] + pat[i].second;
    if (bu2[u] == 0)
      return false;
    bu2[u]--;
  }
  return true;
}

bool match() {
  for (int a = 0; a < m; a++) {
    for (int b = 0; b < m; b++) {
      for (int c = 0; c < m; c++) {
        if (match2(a, b, c))
          return true;
      }
    }
  }
  return false;
}

double calc() {
  double sm = 0;
  for (auto t : ty[l]) {
    // printf("pattern:\\n");
    // for (auto v: t) {
    //     for (auto d: v) {
    //         printf("%d ", d);
    //     }
    //     printf("\\n");
    // }
    // printf("patend\\n");
    fill_n(buf, 66, 0);
    int co = 0;
    int vs = 0;
    for (auto v : t) {
      vs += (int)v.size();
      for (auto d : v) {
        buf[co++] = d;
      }
      co++;
    }
    co--;
    //        printf("patco: %d m: %d\\n", co, m);
    if (m < co)
      continue;
    if (!match())
      continue;
    //        printf("matched!\\n");
    double re = 1.0;
    for (int i = 0; i < m; i++) {
      re *= comb(n, buf[i]);
    }
    re *= comb(m + 1 - vs, t.size());
    sm += re;
  }
  return sm / comb(n * m, l);
}

bool solve() {
  cin >> n >> m >> l;
  if (n == 0)
    return false;
  for (int i = 0; i < l; i++) {
    string s;
    cin >> s;
    if (s[0] == '*') {
      pat[i] = P(-1, 0);
    } else {
      pat[i].first = s[0] - 'a';
      pat[i].second = s.size() - 1;
    }
    //        printf("te %d %d\\n", pat[i].first, pat[i].second);
  }
  printf("%.20lf\\n", calc());
  return true;
}

Q base[8];

int main() {
  base[0].push_back(vector<int>());
  for (int i = 1; i <= 7; i++) {
    for (int k = 1; k <= i; k++) {
      for (auto v : base[i - k]) {
        v.push_back(k);
        base[i].push_back(v);
      }
    }
  }

  ty[0].push_back(Q());
  for (int i = 1; i <= 7; i++) {
    for (int k = 1; k <= i; k++) {
      for (auto q : ty[i - k]) {
        for (auto b : base[k]) {
          auto qq = q;
          qq.push_back(b);
          ty[i].push_back(qq);
        }
      }
    }
    //        printf("%lu\\n", ty[i].size());
  }

  while (solve()) {
  }
  return 0;
}