Description
给出正整数kk,求离曲线和曲线g(x)=kxg(x)=kx的交点横坐标最近的分母不超过105105的最简有理数
Input
第一行一整数TT表示用例组数,每组用例输入一整数(1≤T≤105,1≤k≤105)(1≤T≤105,1≤k≤105)
Output
对于每组用例,输出离交点横坐标最近的分母不超过105105的最简有理数
Sample Input
5
1
2
3
4
5
Sample Output
1/1
153008/96389
50623/24337
96389/38252
226164/77347
Solution
若ba<dcba<dc,则ba<b+da+c<dcba<b+da+c<dc,其中ba,dcba,dc是最简分数表示
令k=k2k=k2,则问题转化为求离k13k13最近的分母不超过105105的最简分数,求出xx满足,若x3=kx3=k则答案为x1x1,否则令a=c=1,b=x−1,d=xa=c=1,b=x−1,d=x,根据上面的结论对这两个分数二分即可,且注意到以此初值下得到的分数都是最简的,因为xx前面的系数总是整除分母,但后面减掉的值总非负且小于分母
Code
#include<cstdio>
using namespace std;
typedef long long ll;
typedef long double ld;
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
ld Abs(ld x)
{
return x>0?x:-x;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ll x,k;
scanf("%I64d",&k);
k=k*k;
x=1;
while(x*x*x<k)x++;
if(x*x*x==k)printf("%I64d/1\n",x);
else
{
ll a=1,b=x-1,c=1,d=x,p,q;
ld tar=k,ans=x*x*x-tar;
while(1)
{
ll e=a+c,f=b+d;
if(e>1e5)break;
ld temp=(ld)f*f*f/e/e/e;
if(Abs(temp-tar)<ans)
{
ans=Abs(temp-k);
p=e,q=f;
}
if(temp>tar)c=e,d=f;
else a=e,b=f;
}
printf("%I64d/%I64d\n",q,p);
}
}
return 0;
}