题目要求一个x使得 最后折线通过 点(a,b)
显然 b>a时,无解,b==a时,解为b
当a>b时,一定存在解;
容易得知
如果(a,b)在上斜边上,那么该边与x轴交点为(a-b,0),称为点C
如果(a,b)在下斜边上,那么该边与x轴交点为(a+b,0),称为点C
讨论a+b的情况
先假设解为x 那么 令y=(a+b)/(2*x)必然是一个整数、、表示C点到原点的距离可以为2*y段x;
1、从而x=(a+b)/(2*y)、我们要x尽可能小,那么y就要尽可能大
2、x必须满足x>=b ;否则根本没办法过(a,b)点
从而 我们假设x最小的情况合法,也就是x=b; 得到y=(a+b)/(2*b)、此时得到的y不一定是整数,是带小数部分的,
另Y=y的整数部分、那么c点到原点的距离为2*Y段x,再加上小数部分段(例如0.7段)的x、 那么我们现在只需要把 小数部分段的多出来的值 平均分配到 Y段就可以了。也就是稍稍增大x的值。。
也就是 直接对y向下取整,然后(a+b)/(2*y)得到的值就是最小的X了,也就是上一句所说的 从b再稍稍增大的x;
code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
double ans,a;
int x,y;
const double inf= 1000000005.00;
int main()
{
int a,b;
scanf("%d%d",&a,&b);
if (a==b)
{
printf("%.9lf\n",(double)a);
return 0;
}
if (b>a)
{
printf("-1\n");
return 0;
}
double tmp=a+b;
double y=(tmp)/2/b;
int k=(int)y;
double x=tmp/k/2;
double ans=inf;
if (x<ans)
ans=x;
tmp=a-b;
y=(tmp)/2/b;
k=(int)y;
x=tmp/k/2;
if (x<ans)
ans=x;
printf("%.9lf\n",ans);
return 0;
}