Zoj 1601: integer Approximation
Link: http://acm.zju.edu.cn/onlinejudge/showProblem.do? Problemcode = 1601.
For a given floating point number A (0.1 <= A <= 10) and a maximum value L (1 <= L <= 100,000 ), find the two optimal integers n and D (1 <= N, d <= L) between 1 and L ), the result of N/D is the closest to a (that is, | A-N/d | minimum ). For example, for pi = 3.14159265358979, the result of 10000 between 1 and 355/133 is the closest to pi.
Analysis: from an intuitive perspective, there seems to be no special shortcuts except for the "exhaustive" search. In addition, the L value in the question is small and will not exceed. This also implies that our solution is to make a full search within this range.
Obviously, if the division result is the same, the smaller the integer, the better. Therefore, we should search from small to large, so that the subsequent large equivalent division will not overwrite the previous one. Note that the start search point depends on the relationship between A and 1. For example, if a <1, then n <D. So it should be shader n = 1. If a> 1, then D = 1. In order to improve efficiency, we should perform one-by-one search based on a relatively small number, because another number is magnified after calculation. Therefore, if you use a relatively small number for search, the number of cycles will be less than the search based on a relatively large number. But the followingCodeFor the sake of simplicity, it is no difference to search one by one based on D.
For example, if a = 0.1, we start searching from n = 1, D = 10 and accumulate Based on D. N = D * 0.1 will change slowly and reduce the efficiency. Therefore, n search is used to accumulate N. If the step value of D is adjusted to max (1, (INT) (1/A + 0.5), the mathematical analysis of how to get the integer is required, that is to say, it is troublesome to use a fixed step value for D and search based on N (because D is an integer and there is an error between N/.
In the following code, Y/X is the current integer division to be explored, that is, y corresponds to N, and X corresponds to D. Err is the relative error between Y/X and floating point. When selecting the first integer, note the limitation of L. For example, if a = 0.1, the first integer We select should be 1/10. However, if l = 5, 1/10 cannot be selected, and the first integer should be 1/5.
Zoj1601
# Include <stdio. h> # Include <Math. h> Void Findresult ( Double A, Int L, Int * Pn, Int * PD ){ Double Minerr = 100000 , Err; Int X, Y; If (A> = 1 ) {X = 1 ; Y = ( Int ) (X * A + 0.5 ); If (Y> L) y = L ;} Else {Y = 1 ; X = ( Int ) (Y/A + 0.5 ); If (X> L) x = L ;} While (X <= L & Y <= L) {err = FABS (x *- Y ); If (ERR < Minerr ){ * Pn = Y; * Pd = X; minerr = Err ;} ++ X; y = ( Int ) (X * A + 0.5 );}} Int Main ( Int Argc,Char * Argv []) { Double A; Int L, N, D; While (Scanf ( " % Lf % LD " , & A, & L )! = EOF) {findresult (A, l, & N ,& D); printf ( " % LD \ n " , N, d );} Return 0 ;}