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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define lengthof(array) (sizeof(array) / sizeof(*array))
#define dump(a) (cerr << (#a) << " = " << (a) << endl)
#define FOR(it, c)                                                             \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define RFOR(it, c)                                                            \\
  for (__typeof((c).rbegin()) it = (c).rbegin(); it != (c).rend(); ++it)

template <class T> inline void chmax(T &a, const T &b) {
  if (b > a)
    a = b;
}
template <class T> inline void chmin(T &a, const T &b) {
  if (b < a)
    a = b;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << '(' << p.first << ", " << p.second << ')';
  return os;
}

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
  return os;
}

const int MAX_N = 7;

int p, q, a, n;
int tmp[MAX_N];
int size = 0;
int product = 1;

inline pair<int, int> add(int n1, int d1, int n2, int d2) {
  int deno = d1 / __gcd(d1, d2) * d2;
  int nume = deno / d1 * n1 + deno / d2 * n2;
  const int g = __gcd(nume, deno);
  return make_pair(nume / g, deno / g);
}

inline int dfs(int nume, int deno) {
  if (nume == p && deno == q)
    return 1;

  if (size == n || nume * q > deno * p)
    return 0;

  int res = 0;
  for (int i = (size ? tmp[size - 1] : 1); product * i <= a; ++i) {
    const pair<int, int> check = add(nume, deno, n - size, i);
    if (check.first * q < check.second * p)
      break;

    product *= i;
    tmp[size++] = i;
    const pair<int, int> result = add(nume, deno, 1, i);
    res += dfs(result.first, result.second);
    product /= i;
    --size;
  }

  return res;
}

int main() {
  while (scanf("%d %d %d %d", &p, &q, &a, &n), p) {
    const int g = __gcd(p, q);
    p /= g;
    q /= g;
    printf("%d\\n", dfs(0, 1));
  }

  return EXIT_SUCCESS;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define lengthof(array) (sizeof(array) / sizeof(*array))
#define dump(a) (cerr << (#a) << " = " << (a) << endl)
#define FOR(it, c)                                                             \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define RFOR(it, c)                                                            \\
  for (__typeof((c).rbegin()) it = (c).rbegin(); it != (c).rend(); ++it)

template <class T> inline void chmax(T &a, const T &b) {
  if (b > a)
    a = b;
}
template <class T> inline void chmin(T &a, const T &b) {
  if (b < a)
    a = b;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << '(' << p.first << ", " << p.second << ')';
  return os;
}

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
  return os;
}

const int MAX_N = 7;

int p, q, a, n;
int tmp[MAX_N];
int size = 0;
int product = 1;

inline pair<int, int> add(int n1, int d1, int d2) {
  int deno = d1 / __gcd(d1, d2) * d2;
  int nume = deno / d1 * n1 + deno / d2;
  const int g = __gcd(nume, deno);
  return make_pair(nume / g, deno / g);
}

inline int dfs(int nume, int deno) {
  if (nume == p && deno == q)
    return 1;

  if (size == n || nume * q > deno * p)
    return 0;

  int res = 0;
  for (int i = (size ? tmp[size - 1] : 1); product * i <= a; ++i) {
    product *= i;
    tmp[size++] = i;
    const pair<int, int> result = add(nume, deno, i);
    res += dfs(result.first, result.second);
    product /= i;
    --size;
  }

  return res;
}

int main() {
  while (scanf("%d %d %d %d", &p, &q, &a, &n), p) {
    const int g = __gcd(p, q);
    p /= g;
    q /= g;
    printf("%d\\n", dfs(0, 1));
  }

  return EXIT_SUCCESS;
}