HDU 6209 数学

简略题意:问分母在1e5范围内的最简分数中,距离 y=k/x y=(x) 的在第一象限的交点的 x 坐标最近的分数是什么。

k/x=(x) => x=k2/3
我们可以先暴力找到最接近k的整数部分,如果直接找到了答案就输出即可。
否则答案即在 x11x1 之间,这部分的复杂度是 O(k2/3) 的。

然后考虑如何在这段区间找数。
给出闭区间 [l,r] ,二分找一个数挺显然的,不过为了使得我们二分出的分数是最简分数,我们可以参考法里数列的构造法。
对于 [luld,rurd] ,每次取二分中点 [lu+ruld+rd] 即可保证每次为最简分数。
关于法里数列可以看这里

#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const long double eps = 1e-8;
//int dcmp(long double x) { if(_abs(x)<=eps) return 0; return (x>0)?1:-1;};
typedef long long LL;

long double _abs(long double x) {
    return x<0?-x:x;
}

namespace solver {
    int t;
    LL k;
    void solve() {
        scanf("%d", &t);
        LL a1,a2, b1, b2, m1, m2, A, B;
        while(t--) {
            scanf("%lld", &k);
            LL x = 0;
            while(x*x*x<k*k) x++;
            if(x*x*x==k*k) printf("%lld/1\n", x);
            else {
                long double tt = k * k;
                LL au = x-1, bu = x;
                LL ad = 1, bd = 1;
                long double minv = 1e60;
                for(;;) {
                    LL mu = au + bu, md = ad + bd;
                    if(md > 100000) break;
                    long double u = mu, v = md;
                    long double val = u*u*u/v/v/v;
                    if(_abs(val-tt) < minv) {
                        minv = _abs(val-tt);
                        A = mu, B = md;
                    }
                    if(val > tt) bu = mu, bd = md;
                    else au = mu, ad = md;
                }
                printf("%lld/%lld\n", A, B);
            }
        }
    }
}

int main() {
    solver::solve();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值