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

#include <iostream>
#include <vector>
using namespace std;
int gcd(int a, int b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
struct Rational {
  int p, q;
  Rational() : p(1), q(1) {}
  Rational(int p, int q) : p(p), q(q) {}
  Rational operator+(const Rational &t) {
    Rational r;
    r.p = p * t.q + t.p * q;
    r.q = q * t.q;
    r.Simplify();
    return r;
  }
  Rational operator*(const Rational &t) {
    Rational r(p * t.p, q * t.q);
    return r.Simplify();
  }
  bool operator<(const Rational &t) { return p * t.q - q * t.p < 0; }
  bool operator==(const Rational &t) { return p == t.p && q == t.q; }
  Rational Simplify() {
    int r = gcd(p, q);
    p /= r;
    q /= r;
    return *this;
  }
};
ostream &operator<<(ostream &os, const Rational &r) {
  os << r.p << '/' << r.q;
  return os;
}
struct Denoms {
  vector<int> v;
  Denoms() : product(1) {}
  void push(int a) {
    product *= a;
    v.push_back(a);
  }
  void pop() {
    product /= v[v.size() - 1];
    v.pop_back();
  }
  int product;
};
ostream &operator<<(ostream &os, const Denoms &v) {
  for (unsigned int i = 0; i < v.v.size(); ++i)
    os << v.v[i] << ' ';
  os << "PRODUCT: " << v.product;
  return os;
}
int ans;
void solve(Rational target, int a, int n, int denom_now, Rational now,
           Denoms &v) {
  now.Simplify();
  // cout << "TARGET :" << target << " NOW: " << now << endl;
  if (target == now) {
    /*cout << "N: "<< n << "NOW: " << now << endl;
    cout << v << "\\n--------------------------------" << endl;*/
    ans++;
  }
  if (n == 0)
    return;
  for (int i = denom_now + 1; i <= a / v.product + 1; ++i) {
    if ((now + Rational(n, 1) * Rational(1, i)).Simplify() < target) {
      break;
    }
    v.push(i);
    if (v.product > a || target < (now + Rational(1, i)).Simplify()) {
      v.pop();
      continue;
    }
    solve(target, a, n - 1, i - 1, now + Rational(1, i), v);
    v.pop();
  }
}
int main() {
  while (true) {
    int p, q;
    int a, n;
    Rational target;
    Denoms tmp;

    scanf("%d%d%d%d", &p, &q, &a, &n);

    if (!(p || q || a || n))
      break;

    target.p = p;
    target.q = q;
    target.Simplify();
    ans = 0;
    solve(target, a, n, 0, Rational(0, 1), tmp);

    printf("%d\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <vector>
using namespace std;
int gcd(int a, int b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
struct Rational {
  int p, q;
  Rational() : p(1), q(1) {}
  Rational(int p, int q) : p(p), q(q) {}
  Rational operator+(const Rational &t) {
    Rational r;
    r.p = p * t.q + t.p * q;
    r.q = q * t.q;
    r.Simplify();
    return r;
  }
  Rational operator*(const Rational &t) {
    Rational r(p * t.p, q * t.q);
    return r.Simplify();
  }
  bool operator<(const Rational &t) { return p * t.q - q * t.p < 0; }
  bool operator==(const Rational &t) { return p == t.p && q == t.q; }
  Rational Simplify() {
    int r = gcd(p, q);
    p /= r;
    q /= r;
    return *this;
  }
};
ostream &operator<<(ostream &os, const Rational &r) {
  os << r.p << '/' << r.q;
  return os;
}
struct Denoms {
  vector<int> v;
  Denoms() : product(1) {}
  void push(int a) {
    product *= a;
    v.push_back(a);
  }
  void pop() {
    product /= v[v.size() - 1];
    v.pop_back();
  }
  int product;
};
ostream &operator<<(ostream &os, const Denoms &v) {
  for (unsigned int i = 0; i < v.v.size(); ++i)
    os << v.v[i] << ' ';
  os << "PRODUCT: " << v.product;
  return os;
}
int ans;
void solve(Rational target, int a, int n, int denom_now, Rational now,
           Denoms &v) {
  now.Simplify();
  // cout << "TARGET :" << target << " NOW: " << now << endl;
  if (target == now) {
    /*cout << "N: "<< n << "NOW: " << now << endl;
    cout << v << "\\n--------------------------------" << endl;*/
    ans++;
  }
  if (n == 0)
    return;
  for (int i = denom_now + 1; i <= a / v.product + 1; ++i) {
    v.push(i);
    if (v.product > a || target < (now + Rational(1, i)).Simplify() ||
        (now + Rational(n, 1) * Rational(1, i)).Simplify() < target) {
      v.pop();
      continue;
    }
    solve(target, a, n - 1, i - 1, now + Rational(1, i), v);
    v.pop();
  }
}
int main() {
  cout << Rational(0, 1) + Rational(1, 6) << endl;
  while (true) {
    int p, q;
    int a, n;
    Rational target;
    Denoms tmp;

    scanf("%d%d%d%d", &p, &q, &a, &n);

    if (!(p || q || a || n))
      break;

    target.p = p;
    target.q = q;
    target.Simplify();
    cout << target << endl;
    ans = 0;
    solve(target, a, n, 0, Rational(0, 1), tmp);

    printf("%d\\n", ans);
  }
  return 0;
}