题目
题目描述
输入
输入文件的第一行为P、N,其中 P、N<30000。
输出
输出文件只有一行,格式为“X/Y U/V”。注意,答案必须是既约的,也就是说分子、分母的最大公约数必须等于1。
题目大意
求X/Y小于sqrt§小于U/V。X、Y、U、V,分子、分母的最大公约数必须等于1(不能大于N)。
解题思路
用二分查找,for找分母,二分找分子,再更新mi1,mi2,ma1,ma2,并约分。
代码
#include<cstdio>
#include<cmath>
using namespace std;
int p,n,l,r,mi1=1,mi2=1,ma1=30000,ma2=1; double a[10001];
inline int ggq(int i,int j){return (j==0)?i:ggq(j,i%j);}
void gqq(int i,int j){int k=ggq(i,j); i%=k;j%=k;}
int main()
{
scanf("%d%d",&p,&n); double k=sqrt(p);
for (register int i=1;i<=n;i++)
{
l=1; r=n; int mid; double rr,ee;
while (l<r) ((double)((double)(mid=(l+r)/2)/(double)i)>k)?r=mid:l=mid+1;
if ((rr=(double)((double)l/(double)i))<(double)((double)ma1/(double)ma2)&&rr>k) { ma1=l; ma2=i;}
if (rr>(double)((double)mi1/(double)mi2)&&rr<k) { mi1=l; mi2=i;}
if ((ee=(double)((double)(l-1)/(double)i))<(double)((double)ma1/(double)ma2)&&ee>k) { ma1=l-1; ma2=i;}
if (ee>(double)((double)mi1/(double)mi2)&&ee<k) { mi1=l-1; mi2=i;}
gqq(ma1,ma2); gqq(mi1,mi2);
}
printf("%d/%d %d/%d",mi1,mi2,ma1,ma2);
}