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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章