A Problem about Polyline
There is a polyline going through points (0, 0) – (x, x) – (2x, 0) – (3x, x) – (4x, 0) – ... - (2kx, 0) – (2kx + x, x) – ....
We know that the polyline passes through the point (a, b). Find minimum positive value x such that it is true or determine that there is no such x.
Input
Only one line containing two positive integers a and b (1 ≤ a, b ≤ 109).
Output
Output the only line containing the answer. Your answer will be considered correct if its relative or absolute error doesn't exceed 10 - 9. If there is no such x then output - 1 as the answer.
Sample test(s)
input
3 1
output
1.000000000000
input
1 3
output
-1
input
4 1
output
1.250000000000
Note
You can see following graphs for sample 1 and sample 3.
根据题意,列出数学公式 :
b = a + 2*k*x;( (a,b)在斜率为1的直线上);由于斜率为1,画图易得 a-b = 2*k*x;
b = -a + 2*(k+1)*x;( (a,b)在斜率为-1的直线上);同样斜率为-1,a+b = 2*(k+1)*x;
因此 x = min( (a-b)/(2*k) , (a+b)/(2*(k+1)) );
要想做到x最小,要求(2*k) 和 ( 2*(k+1) )最大即可;
由于 x 最小也不会小于 b,并且(2*k)是偶数,所以 m1 = (2*k)max = one maximal even number (<=(a-b)/b);(注意!m1 可能为 0);
同理,m2 = (2*(k+1))max = one maximal even number(<=(a+b)/b);
求得 x = min( (a-b)/m1 , (a+b)/m2 );(当m1为0时,x = (a+b)/m2);
复杂度 O(1);
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int main(){ int a,b; scanf("%d%d",&a,&b); if(a < b){puts("-1");return 0;} double ans; bool flag = 0; int k = (a-b)/b; if(k%2)k--; if(k){ flag = 1; ans = (double)(a-b)/k; } k = (a+b)/b; if(k%2)k--; double temp = (double)(a+b)/k; if(flag) ans = min(ans,temp); else ans = temp; printf("%.9f ",ans); return 0;
}