题目地址:
http://acm.hdu.edu.cn/showproblem.php?pid=6209
思路:
1.Stern-Brocot树可以构成所有有理数。
2.对于每次在m1/n1,m2/n2中插入(m1+m2)/(n1+n2)构成下一排。
3.Stern-Brocot树构成的所有分数均为最简分数,即gcd(m,n)==1。
其中,第N排的真分数部分为N阶Farey序,满足对于连续的分数m1/n1,m2/n2,必有m1/n1<m2/n2。
由此,取该数的小数部分,二分答案即可。
注意:此题卡long double。
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
long double lt;
int ansl,ansr;
void solve(int l1,int r1,int l2,int r2)
{
if(l1==l2&&r1==r2) return ;
if(fabs((long double)l1/r1-lt)<fabs((long double)ansl/ansr-lt))
{
ansl=l1;
ansr=r1;
}
if(fabs((long double)l2/r2-lt)<fabs((long double)ansl/ansr-lt))
{
ansl=l2;
ansr=r2;
}
int ml=(l1+l2);
int mr=(r1+r2);
if(mr>100000) return ;
if((long double)ml/mr<lt) solve(ml,mr,l2,r2);
else solve(l1,r1,ml,mr);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int flag=0,k;
scanf("%d",&k);
ansl=ansr=1;
long double tmp=pow((long double)k,(long double)2.0/3.0);
lt=tmp-(int)floor(tmp);
solve(0,1,1,1);
printf("%d/%d\n",(int)floor(tmp)*ansr+ansl,ansr);
}
return 0;
}