poj1650 近似整数

题意描述

给定一个浮点数A和一个整数L,求在范围[1,L]内的两个整数n和d,使得n和d能近似等于A,且使误差|A-n/d|最小。

输入格式

一行两个数:浮点数A,整数L。数据保证有解。

输出格式

一行两个整数n和d

输入样例

3.14159265358979 10000

输出样例

355 113

思路:

        所谓“追赶法”,顾名思义,正如两个人“赛跑”,甲超过乙之后乙不服,要超过甲,甲被超过之后又超过乙,以此轮换。而两个数的“追赶”则是保持一定比例,使a/b在k左右“徘徊”。如果a/b>k,说明分子太大或者分母太小,对分子减小,或者使分母增大。如果a/b<k则反之。

        本题中,A分为两种情况:A>=1,0<A<1.对于前一种情况,n>=d,后一种情况n<d。假定d为1,如果后一种情况n将<1,不利于处理。故判断A情况,若为第二种,A = 1/A并将其记录。

        然后,初始d为1,n为A*d,然后不断判断n/d和A的大小,如果前者比后者大,说明d太小,d++,否则n++。定义变量保存最优解。

代码:

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int main(){
	double A;
	int L;
	bool flag = true;
	scanf("%lf %d",&A,&L);
	if(A < 1){
		A = 1/A;
		flag = false;
	}
	int l = 1,r = (int)A,res_l = l,res_r = r;
	double now = (double)INF;
	while(l <= r && r <= L){
		double tmp = (double)r/l;
		if(abs(tmp - A) < now){//为更优解 
			res_l = l;
			res_r = r;
			now = abs(tmp - A);
		}
		if(tmp < A)r++;
		else l++;
	}
	if(flag)printf("%d %d",res_r,res_l);
	else printf("%d %d",res_l,res_r);//如果A < 1交换结果输出顺序 
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值