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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章