这道题直接枚举就行了。关键是注意精度。
不过,我看完题时,想到了 《具体数学》 4.5 介绍的 Stern-Brocot tree。通过它可以构造出所有 >= 0 的最简分数。并且这个 tree 有一个优美的性质,给出一个大于0的实数r,我们能以二叉搜索的方式在树上搜索最接近r的最简分式。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <cassert>
#include <algorithm>
#include <cmath>
#include <limits>
#include <set>
using namespace std;
#define MIN(a, b) a < b ? a : b
#define MAX(a, b) a > b ? a : b
#define F(i, n) for (int i=0;i<(n);++i)
#define REP(i, s, t) for(int i=s;i<=t;++i)
#define UREP(i, s, t) for(int i=s;i>=t;--i)
#define REPOK(i, s, t, o) for(int i=s;i<=t && o;++i)
#define MEM0(addr, size) memset(addr, 0, size)
#define LBIT(x) x&-x
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define eps 1e-15
#define MAXN 30
#define MAXM 100000
#define MOD 1000000007
typedef long long LL;
const double maxdouble = numeric_limits<double>::max();
LL gcd(LL a, LL b);
#define DEBUG
#define ALGO2
int cmp_double(double a, double b)
{
if (a - b > eps) return 1;
if (a - b < -eps) return -1;
return 0;
}
int cmp(LL a, LL b, LL x, LL y)
{
if (!y)
return -1;
if (!b)
return 1;
return cmp_double((double)a/b, (double)x/y);
}
void Sub(LL a, LL b, LL x, LL y, double & ret)
{
if (!b) {
ret = maxdouble;
return;
}
ret = (double)a / b - ((double)x / y);
}
void print(LL a, LL b) {
cout << a << "/" << b << endl;
}
int main()
{
freopen("input.in", "r", stdin);
//freopen("input.in", "w", stdout);
LL x, y, n;
cin >> x >> y >> n;
LL la, lb, ra, rb, a, b;
bool equ;
la = 0;
lb = 1;
ra = 1;
rb = 0;
equ = false;
int g = gcd(x, y);
x /= g;
y /= g;
for(;;) {
if (lb + rb > n)
break;
a = la + ra;
b = lb + rb;
#ifdef ALGO2
int re = cmp(a, b, x, y);
#endif
if (re > 0) {
ra = a;
rb = b;
} else if (re < 0) {
la = a;
lb = b;
} else {
equ = true;
break;
}
}
if (equ)
print(a, b);
else {
LL a1, b1, a2, b2;
double z1, z2;
#ifdef ALGO2
Sub(ra, rb, x, y, z1);
Sub(x, y, la, lb, z2);
int re = cmp_double(z1, z2);
#endif // ALGO2
if (re > 0) {
print(la, lb);
} else if (re < 0) {
print(ra, rb);
} else {
if (lb < rb) {
print(la, lb);
} else if (lb > rb) {
print(ra, rb);
} else {
if (la <= ra)
print(la, lb);
else
print(ra, rb);
}
}
}
return 0;
}
LL gcd(LL a, LL b)
{
return b == 0 ? a : gcd(b, a % b);
}