1.题目链接。给定一个k,求出一个分母小于100000的分数,最接近pow(k,2.0/3).
2.这个题看起来像高精度?但是这题卡long double。这个题目其实考到了一些比较有趣的东西,SB树和分数二分。首先把整数部分求出来,然后小数部分采用分数二分求出一个满足条件最接近的解即可。
#include<bits/stdc++.h>
#define ld long double
#define ll long long
using namespace std;
int fz, fm;
void solve(int z1, int m1, int z2, int m2, ld xs)
{
if (z1 == z2 && m1 == m2) return;
if (m1 > 100000 || m2 > 100000) return;
if (abs((ld)fz / fm - xs) > abs((ld)z1 / m1 - xs)) fz = z1, fm = m1;
if (abs((ld)fz / fm - xs) > abs((ld)z2 / m2 - xs)) fz = z2, fm = m2;
int z = z1 + z2, m = m1 + m2;
ld tt = (ld)z / m;
if (tt < xs) solve(z, m, z2, m2, xs);
else solve(z1, m1, z, m, xs);
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
ll k;
scanf("%lld", &k);
int flag = 0;
for (ll i = 1; i <= 10000; i++)
{
if (i * i * i == k * k)
{
flag = 1;
printf("%lld/1\n", i);
break;
}
if (i * i * i == k)
{
flag = 1;
printf("%lld/1\n", i * i);
break;
}
}
if (flag) continue;
ld x = (ld)pow((ld)k, (ld)2.0 / 3.0);
int zs = (int)floor(x);
ld xs = x - zs;
fz = 0, fm = 1;
solve(0, 1, 1, 1, xs);
printf("%d/%d\n", zs * fm + fz, fm);
}
}