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

#include <iostream>
using namespace std;
int p, q, a, n;
int solve(int p1, int a1, int r, int depth) {
  if (p1 * q == a1 * p)
    return 1;
  if (depth == n)
    return 0;
  int ret = 0;
  for (int i = r; a1 * i <= a; i++) {
    ret += solve(p1 * i + a1, a1 * i, i, depth + 1);
  }
  return ret;
}
int main() {
  while (cin >> p >> q >> a >> n, p | q | a | n) {
    cout << solve(0, 1, 1, 0) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cmath>
#include <cstdio>
using namespace std;
int gcd(int a, int b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
// ----- Fraction Class ------ //
template <class Type> class Fraction {
public:
  // ------ Variable ------ //
  Type p, q;
  // ------ Constructor ------ //
  Fraction() : p(0), q(1) {}
  Fraction(const Type &p_, const Type &q_)
      : p(p_ / gcd(abs(p_), abs(q_))), q(q_ / gcd(abs(p_), abs(q_))) {
    if (q < 0)
      p = -p, q = -q;
  }
  Fraction(const Fraction<Type> &f) : p(f.p), q(f.q) {}
  // ------ Operator ------ //
  template <class Type2>
  friend bool operator==(const Fraction<Type2> &f1, const Fraction<Type2> &f2) {
    return f1.p == f2.p && f1.q == f2.q;
  }
  template <class Type2>
  friend bool operator!=(const Fraction<Type2> &f1, const Fraction<Type2> &f2) {
    return f1.p != f2.p || f1.q != f2.q;
  }
  template <class Type2>
  friend Fraction operator+(const Fraction<Type2> &f1,
                            const Fraction<Type2> &f2) {
    return Fraction(f1.p * f2.q + f1.q * f2.p, f1.q * f2.q);
  }
  template <class Type2>
  friend Fraction operator-(const Fraction<Type2> &f1,
                            const Fraction<Type2> &f2) {
    return Fraction(f1.p * f2.q - f1.q * f2.p, f1.q * f2.q);
  }
  template <class Type2>
  friend Fraction operator*(const Fraction<Type2> &f1,
                            const Fraction<Type2> &f2) {
    return Fraction(f1.p * f2.p, f1.q * f2.q);
  }
  template <class Type2>
  friend Fraction operator/(const Fraction<Type2> &f1,
                            const Fraction<Type2> &f2) {
    return Fraction(f1.p * f2.q, f1.q * f2.p);
  }
  template <class Type2>
  friend bool operator<(const Fraction<Type2> &f1, const Fraction<Type2> &f2) {
    Fraction f3 = f1 - f2;
    return f3.p < 0;
  }
  template <class Type2>
  friend bool operator>(const Fraction<Type2> &f1, const Fraction<Type2> &f2) {
    Fraction f3 = f1 - f2;
    return f3.p > 0;
  }
  template <class Type2>
  friend bool operator<=(const Fraction<Type2> &f1, const Fraction<Type2> &f2) {
    Fraction f3 = f1 - f2;
    return f3.p <= 0;
  }
  template <class Type2>
  friend bool operator>=(const Fraction<Type2> &f1, const Fraction<Type2> &f2) {
    Fraction f3 = f1 - f2;
    return f3.p >= 0;
  }
  template <class Type2> Fraction &operator+=(const Fraction<Type2> &f1) {
    Fraction f2 = Fraction(p * f1.q + q * f1.p, q * f1.q);
    p = f2.p;
    q = f2.q;
    return *this;
  }
  template <class Type2> Fraction &operator-=(const Fraction<Type2> &f1) {
    Fraction f2 = Fraction(p * f1.q - q * f1.p, q * f1.q);
    p = f2.p;
    q = f2.q;
    return *this;
  }
  template <class Type2> Fraction &operator*=(const Fraction<Type2> &f1) {
    Fraction f2 = Fraction(p * f1.p, q * f1.q);
    p = f2.p;
    q = f2.q;
    return *this;
  }
  template <class Type2> Fraction &operator/=(const Fraction<Type2> &f1) {
    Fraction f2 = Fraction(p * f1.q, q * f1.p);
    p = f2.p;
    q = f2.q;
    return *this;
  }
};
Fraction<int> f;
int p, q, a, n;
int solve(Fraction<int> f1, int a1, int c, int d) {
  if (d + 1 == n) {
    Fraction<int> f2 = f - f1;
    if (f2.p == 1)
      return 1;
    return 0;
  }
  int ret = 0;
  bool flag = false;
  for (int i = c; a1 * i <= a; i++) {
    Fraction<int> f2 = f1 + Fraction<int>(1, i);
    if (f2 == f) {
      ret++;
    }
    if (f2 < f) {
      flag = true;
    }
    if (flag) {
      ret += solve(f1 + Fraction<int>(1, i), a1 * i, i, d + 1);
    }
  }
  return ret;
}
int main() {
  while (~scanf("%d%d%d%d", &p, &q, &a, &n)) {
    if (p == 0 && q == 0 && a == 0 && n == 0)
      break;
    f = Fraction<int>(p, q);
    printf("%d\\n", solve(Fraction<int>(0, 1), 1, 1, 0));
  }
  return 0;
}