Problem p00712 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define INF 1000000000
#define EPS 1e-9
#define PI acos(-1)

typedef long long ll;

#define MAX_P 800
#define MAX_Q 800
#define MAX_A 12000
#define MAX_N 7

int p, q, a, n;
vector<int> ans_list;

//*********************************************************
// 最大公約数（Greatest Common Divisor）を返す。
// 引数に０がある場合は０を返す。
//*********************************************************
int gcd(int m, int n) {
  // 引数に０がある場合は０を返す
  if ((0 == m) || (0 == n))
    return 0;

  // ユークリッドの方法
  while (m != n) {
    if (m > n)
      m = m - n;
    else
      n = n - m;
  }
  return m;
} // gcd

//*********************************************************
// 最小公倍数（Least Common Multiple）を返す。
// 引数に０がある場合は０を返す。
//*********************************************************
int lcm(int m, int n) {
  // 引数に０がある場合は０を返す
  if ((0 == m) || (0 == n))
    return 0;

  return ((m / gcd(m, n)) * n); // lcm = m * n / gcd(m,n)
} // lcm

// solve(現在の分解数, 現在の分数の分子, 現在の分数の分母, 分母の積,
// 前の分母の値)
int solve(int num, int P, int Q, int seki, int pre) {

  int ans = 0;
  if (num > n)
    return 0;
  if (seki > a)
    return 0;

  if (P * q == Q * p && P != 0 && Q != 0)
    return 1;

  if ((double)p / q < (double)P / Q)
    return 0;

  for (int i = pre; i * seki <= a; i++) {
    if (num == 0)
      ans += solve(1, 1, i, i, i);
    else {
      int tmp = lcm(Q, i);
      ans += solve(num + 1, P * tmp / Q + 1 * tmp / i, tmp, seki * i, i);
    }
  }

  return ans;
}

int main() {

  while (true) {
    cin >> p >> q >> a >> n;
    if (p == 0 && q == 0 && a == 0 && n == 0)
      break;

    ans_list.push_back(solve(0, 0, 0, 1, 1));
  }

  for (int i = 0; i < ans_list.size(); i++) {
    cout << ans_list[i] << endl;
  }

  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define INF 1000000000
#define EPS 1e-9
#define PI acos(-1)

typedef long long ll;

#define MAX_P 800
#define MAX_Q 800
#define MAX_A 12000
#define MAX_N 7

int p, q, a, n;
vector<int> ans_list;

//*********************************************************
// 最大公約数（Greatest Common Divisor）を返す。
// 引数に０がある場合は０を返す。
//*********************************************************
int gcd(int m, int n) {
  // 引数に０がある場合は０を返す
  if ((0 == m) || (0 == n))
    return 0;

  // ユークリッドの方法
  while (m != n) {
    if (m > n)
      m = m - n;
    else
      n = n - m;
  }
  return m;
} // gcd

//*********************************************************
// 最小公倍数（Least Common Multiple）を返す。
// 引数に０がある場合は０を返す。
//*********************************************************
int lcm(int m, int n) {
  // 引数に０がある場合は０を返す
  if ((0 == m) || (0 == n))
    return 0;

  return ((m / gcd(m, n)) * n); // lcm = m * n / gcd(m,n)
} // lcm

// solve(現在の分解数, 現在の分数の分子, 現在の分数の分母, 分母の積,
// 前の分母の値)
int solve(int num, int P, int Q, int seki, int pre) {

  int ans = 0;
  if (num > n)
    return 0;
  if (seki > a)
    return 0;

  if (P * q == Q * p && P != 0 && Q != 0)
    return 1;

  if ((double)p / q < (double)P / Q)
    return 0;

  for (int i = pre; i * seki <= a; i++) {
    if (num == 0)
      ans += solve(1, 1, i, i, i);
    else {
      ans += solve(num + 1, P * i + Q, Q * i, seki * i, i);
    }
  }

  return ans;
}

int main() {

  while (true) {
    cin >> p >> q >> a >> n;
    if (p == 0 && q == 0 && a == 0 && n == 0)
      break;

    ans_list.push_back(solve(0, 0, 0, 1, 1));
  }

  for (int i = 0; i < ans_list.size(); i++) {
    cout << ans_list[i] << endl;
  }

  return 0;
}