Hdu 6209 The Intersection(Stern-Brocot tree+二分)

題目地址: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;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章