The Intersection HDU - 6209(二分分数+法里数列构造)

The Intersection HDU - 6209

A given coefficient K leads an intersection of two curves f(x) and gK(x). In the first quadrant, the curve f is a monotone increasing function that f(x)=x−−√. The curve g is decreasing and g(x)=K/x.
To calculate the x-coordinate of the only intersection in the first quadrant is the following question. For accuracy, we need the nearest rational number to x and its denominator should not be larger than 100000
.
Input
The first line is an integer T (1≤T≤100000) which is the number of test cases.
For each test case, there is a line containing the integer K (1≤K≤100000)
, which is the only coefficient.
Output
For each test case, output the nearest rational number to x
. Express the answer in the simplest fraction.
Sample Input

5
1
2
3
4
5

Sample Output

1/1
153008/96389
50623/24337
96389/38252
226164/77347

题意:

问分母在1e5范围内的最简分数中,距离y=Kxy=x 的在第一象限的交点的x 座标最近的分数是什么。

分析:

我们发现交点实际上是满足

x3=K2

我们可以先暴力找到最接近k的整数部分,如果直接找到了答案就输出即可。

然后二分分数
答案即在x11x1 之间,这部分的复杂度是O(K32) 的。

这里学习到了一个新玩意叫法里数列

比如对于[ab,cd] ,我们二分的新的分数为:a+cb+d

然后和目标的数字进行比较而决定左移右移即可。

code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double lb;

ll k,lz,rz,lm,rm,val,A,B;
lb Mn,aim;

lb ABS(lb x){
    return x > 0 ? x : -x;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        ll k;
        scanf("%lld",&k);
        val = 1;
        while(val * val * val < k * k)
            val++;
        if(val * val * val == k * k){
            printf("%lld/1\n",val);
            continue;
        }
        lz = val - 1;
        lm = 1;
        aim = k * k;
        rz = val;
        rm = 1;
        Mn = 1e60;
        while(1){
            ll a = lz + rz;
            ll b = lm + rm;
            if(b > 100000) break;
            lb u = a;
            lb v = b;
            lb now = u * u * u / v / v / v;
            if(ABS(now - aim) < Mn){
                Mn = ABS(now - aim);
                A = a;
                B = b;
            }
            if(now > aim){
                rz = a;
                rm = b;
            }
            else{
                lz = a;
                lm = b;
            }
        }
        printf("%lld/%lld\n",A,B);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章