描述
对于一个素数P,我们可以用一系列有理分数(分子、分母都是不大于N的自然数)来逼近sqrt(p),例如P=2,N=5的时候:1/1<5/4<4/3< sqrt(2)<3/2<5/3<2/1。
任 务 :
给定P、N(N>sqrt(p)),求X、Y、U、V,使x/y< sqrt(p) < u/v且x/y与sqrt(p)之间、sqrt(p)与u/v之间都不能再插入满足题意的有理分数。
【题目分析】
二分,代码是常数较小的N^2
【代码】
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ld long double
using namespace std;
int x,n;
int ansl[2],ansr[2];
ld sq;
int gcd(int a,int b)
{
return (b==0)?a:gcd(b,a%b);
}
int main()
{
scanf("%d%d",&x,&n);
sq=sqrt(x*1.0);
ansl[0]=-1e9;ansl[1]=1;
ansr[0]=1e9; ansr[1]=1;
for (int i=1;i<=n;++i)
{
int l=1,r=n;
while (l<r)
{
// printf("%d %d\n",l,r);
int mid=(l+r)/2+1;
if ((ld)mid/(ld)i<=sq) l=mid;
else r=mid-1;
}
// printf("%d %d\n",l,i);
int now=l;
if (now<=n)
while (gcd(now,i)>1&&now) now--;
if ((ld)now/(ld)i>(ld)ansl[0]/ansl[1])
{
ansl[0]=now;
ansl[1]=i;
}
now=l+1;
while (gcd(now,i)>1&&now) now++;
if (now<=n)
if ((ld)now/(ld)i<(ld)ansr[0]/ansr[1])
{
ansr[0]=now;
ansr[1]=i;
}
}
printf("%d/%d ",ansl[0],ansl[1]);
printf("%d/%d\n",ansr[0],ansr[1]);
}