链接:https://ac.nowcoder.com/acm/contest/3006/D
来源:牛客网
题目描述:
牛牛在辛苦的一天的比赛之后,要去找牛妹玩,其实牛妹那天也在比赛。他为了找到牛妹,要尽快的从自己的比赛地到她的比赛地。
还记得吗,比赛地都是只在xxx轴上的,所以两个人的坐标都满足y=0。牛牛除了可以以111单位距离/单位时间的速度移动任意时间以外,还可以花费1单位时间进行闪现。每次闪现时,如果当前他的坐标是x=k,他将闪现到x=
k
3
\sqrt[3]{k}
3k的位置。
请帮他算算,最短需要多少时间,他可以找到牛妹~
输入描述:
输入数据包括多组用例,输入第一行包含一个数字T(1≤T≤5×105),表示数据组数。
接下来T行,每行包括两个整数a,b(∣a∣,∣b∣≤106),表示牛牛所在的位置和牛妹所在的位置。
输出描述:
输出共T行,每行包括一个实数,表示牛牛所花费的最短时间。
如果你的答案是a,标准答案是b,当∣a−b∣≤10−6时,你的答案将被判定为正确。
输入样例:
2
3 -1
1 2
输出样例:
3.442249570
1.000000000
核心思想:
闪现到x=
k
3
\sqrt[3]{k}
3k,意味着闪现只能向原点靠近,所以两种操作的出现顺序只能是以下几种情况:
1、只使用闪现
2、只使用基础位移
3、先使用若干次闪现,再使用若干次基础位移。
所以,我们只需要先使用闪现,直到闪现的收益不如基础位移,就改用基础位移。
注意:pow函数的底数不允许为负数,分类讨论一下。
代码如下:
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
bool pd(double a,double b)
{
if(a>=0)
{
if(fabs(pow(a,1.0/3)-b)<fabs(a-b)-1)
return 1;
return 0;
}
if(fabs(pow(-a,1.0/3)+b)<fabs(a-b)-1)
return 1;
return 0;
}
int main()
{
int T;
double a,b,ans;
cin>>T;
while(T--)
{
scanf("%lf%lf",&a,&b);
ans=0;
while(pd(a,b))
{
if(a>=0)
a=pow(a,1.0/3);
else
a=-pow(-a,1.0/3);
ans++;
}
ans+=fabs(a-b);
printf("%.9f\n",ans);
}
return 0;
}