SSLZYC 有理逼近

题目大意:
这里写图片描述


思路:
思路一:
水题!
我们可以枚举分子和分母,求出符合要求的两个分数后,输出。
时间复杂度:O(n^2),绝对超时。

思路二:
还是水题!
我们可以枚举分母,二分分子,求出符合要求的两个分数后,输出。
时间复杂度:O(2n log n),绝对不超时。


代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

int n,m,l,r,z,lo,ro;
double k,fm,fz,minz,minm,maxz,maxm;

int main()
{
    freopen("rational.in","r",stdin);
    freopen("rational.out","w",stdout);
    scanf("%d%d",&m,&n);
    k=sqrt(m);
    minm=maxm=1;
    maxz=2147483647;
    for (int i=1;i<=n;i++)  //枚举分母 
    {
        l=1;
        r=n;  //初始化 
        while (l!=lo||r!=ro)  //二分分子 
        {
            lo=l;
            ro=r;
            z=(l+r)/2+1;  
            fm=i;
            fz=z;
            if ((fz/fm)>(minz/minm)&&(fz/fm)<=k)  //如果符合要求 
            {
                minz=fz;
                minm=fm;
            }
            if (fz/fm<=k) l=z;                   
                     else r=z-1;
        }
    }
    printf("%0.0lf/%0.0lf ",minz,minm);
    for (int i=1;i<=n;i++)  //枚举分母 
    {
        l=1;
        r=n;
        while (l!=lo||r!=ro)  //二分分子 
        {
            lo=l;
            ro=r;
            z=(l+r)/2;
            fm=i;
            fz=z;
            if ((fz/fm)<(maxz/maxm)&&(fz/fm)>=k)  //如果符合要求 
            {
                maxz=fz;
                maxm=fm;
            }
            if (fz/fm<k) l=z+1;                  
                    else r=z;
        }
    }
    printf("%0.0lf/%0.0lf\n",maxz,maxm);
    return 0;
}
原文地址:https://www.cnblogs.com/hello-tomorrow/p/9313116.html