您的位置:首页 > 其它

HAUT 1261 地狱飞龙

2017-07-06 17:22 274 查看
最近clover迷上了皇室战争,他抽到了一种地狱飞龙,很开心。假设地域飞龙会对距离为d的敌人每秒造成k/d2伤害。假设地域飞龙位于坐标轴原点,以每秒v1的速度向y轴正方向移动,敌人在(x,0)的位置,以每秒v2的速度向x轴负方向移动。问,敌人至少有多少血量永远才不会被地狱飞龙喷死。(伤害是连续造成的,不是一秒一秒间断的)


Input

第一行为数据组数T(1<=T<=1000)
每组数据一行,包含4个实数,分别为v1,v2,x,k(1≤v1,v2,x,k≤10)。


Output

每组数据输出一行,为敌人最小血量,结果保留2为有效数字.


Sample Input

1
1 1 1 1


Sample Output

2.36


【分析】就是一个积分问题,题意很简单,被积函数和上下限也好写,然后当时我就直接在那里积分,结果积了半天发现我水平有限积不出来,没办法问了问大佬,大佬们说用自适应辛普森 数值积分,没办法,实在太菜,只是会用模板,还不知道原因。有时间懂了,再来更新。

【代码】

#include<bits/stdc++.h>

const double eps=1e-6;
double v1,v2,x,k;

double F(double t)//这里写被积函数
{
double a=v1*v1*t*t+(v2*t-x)*(v2*t-x);
return k/a;
}

double getAppr(double le,double ri)
{
double mid=(le+ri)/2;
return (F(le)+4.0*F(mid)+F(ri))*(ri-le)/6.0;
}

double Simpson(double le,double ri)
{
double A=getAppr(le,ri);
double mid=(le+ri)/2;
double L=getAppr(le,mid);
double R=getAppr(mid,ri);
return (fabs(A-L-R)<eps)?A:Simpson(le,mid)+Simpson(mid,ri);
}

int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lf%lf%lf%lf",&v1,&v2,&x,&k);
double ans=Simpson(0,1000000);
printf("%.2f\n",ans);
}
return 0;
}


【续】三个函数里面只用写F()就行,里面写上被积函数,调用Simpsom的时候两个参数分别是积分上下限,这里无穷远处我定义为了1e6,应该是够大。

【分析2】后来还是不甘心,去找了一本高数书,最后面的附录上有二次函数做分母的积分,然后就照着书上抄了一下这个公式实现了一下,也可以过。

【代码2】

#include<bits/stdc++.h>
const double pi=3.141592653;
int main()
{
int t;
scanf("%d",&t);
double v1,v2,x,k;
while(t--)
{
scanf("%lf%lf%lf%lf",&v1,&v2,&x,&k);
double ans=pi/2/v1/x-atan(-v2/v1)/v1/x;
printf("%.2f\n",ans*k);
}
return 0;
}


【续】这里的积分公式直接是我从高数书上抄的,然后将积分上下限直接带进去得到的结果,公式如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: