AOJ-problem-849

                                                                                                           分数

Description

上完物理实验课,紧接着就上数学课,课上大名鼎鼎的Z老师按照惯例先给大家讲一个故事,今天的第一堂课当然是讲他的得意弟子青年数学家恽之玮勇夺国际数学奥林匹克(International Mathematical Olympiad,简称IMO)金牌的故事,故事讲完后,Z老师组织大家讨论了一道当年恽之玮学长遇到的难题,问题并不复杂:给你一个最简真分数,找出另一个分子分母都在1到32767之间的最简真分数,使它与给定的分数最为接近,这里最为接近指的是两数之间的差最小,如5/6就比3/4更接近4/5,因为5/6与4/5相差不到0.4,而3/4与4/5相差了0.5。所谓最简真分数也就是说分子和分母的最大公约数为1,并且分子小于分母。



Input

输入数据仅有一行包含两个用空格隔开的正整数N和D,其中1≤N<D≤32767,分别是给你的分数的分子和分母。


Output

输出数据仅有一行包含两个正整数,分别是你求出的最接近的真分数的分子和分母,并且分子分母都在1到32767之间。如果满足条件的真分数不止一个,输出其中数值最小的那个。输出时两数之间严格用一个空格隔开,行末没有多余的空格。


样例解释:21845/32767=0.666676839503... ≈0.666666... = 2/3。
100%的数据满足:1≤N<D≤32767

思路:
为了减小时间复杂度,分母从2递增至32767,相对应的分子=N/D*分母
①注意要判断分子,分母是否为最简真分数
②输出分子,分母均为整数,则对分子进行四舍五入,注意:采用分子+0.5后取整的方式会因为精度问题产生误差,不推荐也不建议使用
#include<stdio.h>
#include<math.h>
int main()
{
	int i,a,b,x,y,m,n,q;
	double p,min=1;
	scanf("%d%d",&a,&b);
	for(i=2;i<=32767;i++)
	{
		p=(double)i*a/b;
		q=(int)p;
		if(fabs(p-q)<=1e-6)
			x=q-1;
		else if(p-q<=q+1-p)
			x=q;
		else
			x=q+1;                //四舍五入,加0.5会出现精度问题
		y=i;
		if(fabs((double)x/y-(double)a/b)<min)
		{
			min=fabs((double)x/y-(double)a/b);
			m=x;
			n=y;
		}
	}
	for(i=2;i<=32767;i++)
		if(m%i==0&&n%i==0)
		{
			m/=i;
			n/=i;
		}
		printf("%d %d",m,n);
		return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值