A Problem about Polyline

 A Problem about Polyline

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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\n",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/ACMessi/p/4820997.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值