Integer Approximation
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 5827 | Accepted: 1968 |
Description
The FORTH programming language does not support floating-point arithmetic at all. Its author, Chuck Moore, maintains that floating-point calculations are too slow and most of the time can be emulated by integers with proper scaling. For example, to calculate the area of the circle with the radius R he suggests to use formula like R * R * 355 / 113, which is in fact surprisingly accurate. The value of 355 / 113 ≈ 3.141593 is approximating the value of PI with the absolute error of only about 2*10
-7. You are to find the best integer approximation of a given floating-point number A within a given integer limit L. That is, to find such two integers N and D (1 <= N, D <= L) that the value of absolute error |A - N / D| is minimal.
Input
The first line of input contains a floating-point number A (0.1 <= A < 10) with the precision of up to 15 decimal digits. The second line contains the integer limit L. (1 <= L <= 100000).
Output
Output file must contain two integers, N and D, separated by space.
Sample Input
3.14159265358979 10000
Sample Output
355 113
POJ1650
最初这题是在算法竞赛宝典二分中看到的,大意是可以枚举分母二分分子。
挺麻烦的,后来查了下可以利用追赶法搜索。
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
double ans;
int limit;
while(cin>>ans>>limit)
{
int l=1,r=1;
int ansl=1,ansr=1;
double lastcha=999999;
while(l<=limit&&r<=limit)
{
double chazhi=ans-(double)l/r;
double chazhi2=fabs(chazhi);
if(chazhi2<lastcha)
{
lastcha=chazhi2;/// 不要写成chazhi!!!
ansl=l,ansr=r;
}
if(chazhi>0)
l++;
else
r++;
}
cout<<ansl<<' '<<ansr<<endl;
}
}
另外还有一题POJ3039
Close Encounter
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3547 | Accepted: 1306 |
Description
Lacking even a fifth grade education, the cows are having trouble with a fraction problem from their textbook. Please help them. The problem is simple:
Given a properly reduced fraction (i.e., the greatest common divisor of the numerator and denominator is 1, so the fraction cannot be further reduced) find the smallest properly reduced fraction with numerator and denominator in the range 1..32,767 that is closest (but not equal) to the given fraction.
Given a properly reduced fraction (i.e., the greatest common divisor of the numerator and denominator is 1, so the fraction cannot be further reduced) find the smallest properly reduced fraction with numerator and denominator in the range 1..32,767 that is closest (but not equal) to the given fraction.
Input
* Line 1: Two positive space-separated integers N and D (1 <= N < D <= 32,767), respectively the numerator and denominator of the given fraction
Output
* Line 1: Two space-separated integers, respectively the numerator and denominator of the smallest, closest fraction different from the input fraction.
Sample Input
2 3
Sample Output
21845 32767
Hint
INPUT DETAILS:
2/3
OUTPUT DETAILS:
21845/32767 = .666676839503.... ~ 0.666666.... = 2/3.
2/3
OUTPUT DETAILS:
21845/32767 = .666676839503.... ~ 0.666666.... = 2/3.
同样原理
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
double ans;
int a,b;
int limit=32767;
while(cin>>a>>b)
{
ans=(double)a/b;
int l=1,r=1;
int ansl=1,ansr=1;
double lastcha=999999;
while(l<=limit&&r<=limit)
{
double chazhi=ans-(double)l/r;
double chazhi2=fabs(chazhi);
if(chazhi2<lastcha&&!(l%a==0&&r%b==0))
{
lastcha=chazhi2;
ansl=l,ansr=r;
}
if(chazhi>0)
l++;
else
r++;
if(l==a&&r==b)
{
if(l<32767)
l++;
else
r++;
}
}
cout<<ansl<<' '<<ansr<<endl;
}
}