[codev 2190]有理逼近//2018.1.31

题目

题目描述

输入
输入文件的第一行为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); 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值