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

#include <cstdio>
#include <iostream>
// #include <cstdlib>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
// #include <stack>
// #include <limits>
#include <sstream>
// #include <functional>
using namespace std;

#define len(array) (sizeof(array) / sizeof *(array))
#define rep(i, s, e) for (int i = s; i < e; i++)
#define rrep(i, e, s) for (int i = e; s <= i; i--)
#define vrange(v) v.begin(), v.end()
#define vrrange(v) v.rbegin(), v.rend()
#define vsort(v) sort(vrange(v))
#define vrsort(v) sort(vrrange(v))
#define arange(a) a, a + len(a)
#define asort(a) sort(arange(a))
#define arsort(a, t) sort(arange(a), greater<t>())
#define afill(a, v) fill(arange(a), v)
#define afill2(a, v, t) fill((t *)a, (t *)(a + len(a)), v)
#define fmax(a, b) (a < b ? b : a)
#define fmin(a, b) (a > b ? b : a)
#define fabs(a) (a < 0 ? -a : a)
typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
const int INF = (int)1e9;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-10;
// const int dx[] = {1, -1, 0, 0, 1, -1, -1, 1};
// const int dy[] = {0, 0, 1, -1, -1, -1, 1, 1};
// const int weight[] = {0,1,10,100,1000,10000,100000,1000000,10000000};
// priority_queue< int, vector<int>, greater<int> > q;
int p, q, a, n, ans;

int gcd(int a, int b) {
  if (a < b)
    swap(a, b);
  return b != 0 ? gcd(b, a % b) : a;
}

int calc(int limit, int pos, int nume, int deno, int prev) {
  // printf("limit = %d, pos = %d, nume = %d,  deno = %d\\n", limit, pos, nume,
  // deno);
  int res = 0;
  if (a < deno || pos == limit + 1)
    return 0;
  if (p * deno == q * nume)
    return 1;
  rep(i, prev, a + 1) {
    //(nume / deno) + (1/i) = (i*nume + deno) / (deno * i)
    int den = deno * i;
    int num = i * nume + deno;
    if (a < den)
      break;
    if (p * den - q * num < 0)
      continue;
    res += calc(limit, pos + 1, num, den, i);
  }
  return res;
}

void doIt() {
  int gcd0;
  while (true) {
    cin >> p >> q >> a >> n;
    if (p + q + a + n == 0)
      break;
    gcd0 = gcd(p, q);
    p /= gcd0;
    q /= gcd0;
    ans = calc(n, 0, 0, 1, 1);

    cout << ans << endl;
  }
}

int main() {
  doIt();
  return 0;
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <iostream>
// #include <cstdlib>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
// #include <stack>
// #include <limits>
#include <sstream>
// #include <functional>
using namespace std;

#define len(array) (sizeof(array) / sizeof *(array))
#define rep(i, s, e) for (int i = s; i < e; i++)
#define rrep(i, e, s) for (int i = e; s <= i; i--)
#define vrange(v) v.begin(), v.end()
#define vrrange(v) v.rbegin(), v.rend()
#define vsort(v) sort(vrange(v))
#define vrsort(v) sort(vrrange(v))
#define arange(a) a, a + len(a)
#define asort(a) sort(arange(a))
#define arsort(a, t) sort(arange(a), greater<t>())
#define afill(a, v) fill(arange(a), v)
#define afill2(a, v, t) fill((t *)a, (t *)(a + len(a)), v)
#define fmax(a, b) (a < b ? b : a)
#define fmin(a, b) (a > b ? b : a)
#define fabs(a) (a < 0 ? -a : a)
typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
const int INF = (int)1e9;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-10;
// const int dx[] = {1, -1, 0, 0, 1, -1, -1, 1};
// const int dy[] = {0, 0, 1, -1, -1, -1, 1, 1};
// const int weight[] = {0,1,10,100,1000,10000,100000,1000000,10000000};
// priority_queue< int, vector<int>, greater<int> > q;
int p, q, a, n, ans;

int gcd(int a, int b) {
  if (a < b)
    swap(a, b);
  return b != 0 ? gcd(b, a % b) : a;
}

int calc(int limit, int pos, int nume, int deno, int prev) {
  // printf("limit = %d, pos = %d, nume = %d,  deno = %d\\n", limit, pos, nume,
  // deno);
  int res = 0;
  if (a < deno)
    return 0;
  if (pos == limit) {
    int gcd0;
    gcd0 = gcd(deno, nume);
    deno /= gcd0;
    nume /= gcd0;
    // printf("limit = %d, nume = %d,  deno = %d\\n", limit, nume, deno);
    // if(nume == p && deno == q) cout << nume << "/" << deno << ", lim = " <<
    // limit << endl;
    if (nume == p && deno == q)
      return 1;
    else
      return 0;
  }
  rep(i, prev, 12001) {
    //(nume / deno) + (1/i) = (i*nume + deno) / (deno * i)
    int den = deno * i;
    int num = i * nume + deno;
    if (a < den)
      break;
    if (p * den - q * num < 0)
      continue;
    res += calc(limit, pos + 1, num, den, i);
  }
  return res;
}

void doIt() {
  int gcd0;
  while (true) {
    cin >> p >> q >> a >> n;
    if (p + q + a + n == 0)
      break;
    gcd0 = gcd(p, q);
    p /= gcd0;
    q /= gcd0;
    ans = 0;
    rep(i, 1, n + 1) { ans += calc(i, 0, 0, 1, 1); }
    cout << ans << endl;
  }
}

int main() {
  doIt();
  return 0;
}