2017杭电ACM集训队单人排位赛 - 2 -1002 地狱飞龙 (辛普森公式求积分)(模板)

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

题解:
我们根据题意,设时间为t,x1为飞龙距离x轴的距离,x2为敌人距离y轴的距离,那么 x1=v1t , x2=xv2t ,人和龙之间的距离为 d=x12+x22 ,所以伤害 y=k/(x12+x22)=k/(v12t2+(xv2t)2) ,对y求定积分,范围是0到正无穷大。
这时候就要用到一个求积分的万能公式,辛普森公式。

直接看代码就可以明白:

#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
#define pb(a) push_back(a)
#define fir first
#define se second
#define LL long long
typedef pair<int,int> pii;
typedef pairint> pli;
typedef pair pll;
const int maxn = 1e5+5;
const int inf = 0x3f3f3f3f;
LL mod = 1e9+7;
double eeps = 0.00000001;  //设置精度需要,按需要设置,太小会超时!
double PI = acos(-1);

double k,v1,v2,x;

double F(double t){   //这里输入你的公式
    double ans;
    ans = k/((v1*t)*(v1*t) + (x-v2*t)*(x-v2*t));
    return ans;  
}  
double simpson(double a, double b){  
    double c = a + (b-a)/2.0;  
    return (F(a) +4*F(c) + F(b)) * (b-a) / 6.0;  
}  
double asr(double a, double b, double eps, double A){  
    double c = a + (b-a) / 2.0;  
    double L = simpson(a, c), R = simpson(c, b);  
    if(fabs(L+R-A) <= 15*eps) return L+R+(L+R-A)/15.0;  
    return asr(a, c, eps/2.0, L) + asr(c, b, eps/2.0, R);  
}  
double asr(double a, double b, double eps){  
    return asr(a, b, eps, simpson(a,b));  
}  

int main() {
    //freopen("in.txt","r",stdin);
    //freopen("out1.txt","w",stdout);
    int t,dd = 1;
    cin>>t;
    while(t--) {
        cin>>v1>>v2>>x>>k;
        double ans  =  asr(0,1000000.0,eeps); //这里定义范围即可
        printf("%.2f\n",ans);
    }
}

你可能感兴趣的:(数论,模板,杭电,acm,辛普森公式)