• 【计算几何】【辛普森积分法】UVALive


    春节前后想了好久才在队友的讲解下想明白……

    太难讲了,我就不讲了,大概就是考虑直着走到高速上还是斜着走到高速上,然后平移直线和大圆相切,把生成的最大的“桥”和大圆并一下就行了。

    #include<cstdio>
    #include<cmath>
    using namespace std;
    #define EPS 0.00000000001
    const double PI=acos(-1.0);
    double v0,v1,D,T;
    double x0,R,x3,x1,Y1,k,b,A,B,C,x2,y2,k2,b2;
    double f(double x)
    {
    	return k*x+b-(sqrt(R*R-x*x)-D);
    }
    double area(double l,double r)
    {
    	return (r-l)/6.0*(f(l)+4.0*f((l+r)/2.0)+f(r));
    }
    double Sinp(double l,double r)
    {
    	double m=(l+r)*0.5;
    	double t2=area(l,r),t3=area(l,m)+area(m,r);
    	if(fabs(t2-t3)<EPS)
    	  return t2;
    	return Sinp(l,m)+Sinp(m,r);
    }
    
    double g(double x)
    {
    	return -sqrt(R*R-x*x)+D;
    }
    double are2(double l,double r)
    {
    	return (r-l)/6.0*(g(l)+4.0*g((l+r)/2.0)+g(r));
    }
    double Sin2(double l,double r)
    {
    	double m=(l+r)*0.5;
    	double t2=are2(l,r),t3=are2(l,m)+are2(m,r);
    	if(fabs(t2-t3)<EPS)
    	  return t2;
    	return Sin2(l,m)+Sin2(m,r);
    }
    
    double w(double x)
    {
    	return -sqrt(R*R-x*x)-D-(k*x+b);
    }
    double are3(double l,double r)
    {
    	return (r-l)/6.0*(w(l)+4.0*w((l+r)/2.0)+w(r));
    }
    double Sin3(double l,double r)
    {
    	double m=(l+r)*0.5;
    	double t2=are3(l,r),t3=are3(l,m)+are3(m,r);
    	if(fabs(t2-t3)<EPS)
    	  return t2;
    	return Sin3(l,m)+Sin3(m,r);
    }
    
    double sqr(double x)
    {
    	return x*x;
    }
    int main()
    {
    	//freopen("a.in","r",stdin);
    	int zu=0;
    	while(scanf("%lf%lf%lf%lf",&v0,&v1,&D,&T)!=EOF)
    	  {
    	  	++zu;
    	  	x0=-D*v1/v0+v1*T;
    	  	R=v0*T;
    	  	x3=sqrt(R*R-D*D);
    	  	x1=sqr(T*v0-D)/x0;
    	  	Y1=sqrt(sqr(T*v0-D)-x1*x1);
    	  	k=Y1/(x1-x0);
    	  	b=R*sqrt(1.0+k*k)-D;
    	  	x0=-b/k;
    	  	k2=-1.0/k;
    	  	b2=-D;
    	  	A=1.0+k2*k2;
    	  	B=2.0*(b2+D)*k2;
    	  	C=sqr(b2+D)-R*R;
    	  	x2=(-B+sqrt(B*B-4.0*A*C))/(2.0*A);
    	  	y2=k*x2+b;
    	  	if(y2<EPS)
    	  	  {
    	  	  	printf("Case %d: %.8lf
    ",zu,PI*R*R);
    	  	  	continue;
    	  	  }
    	  	double __area=Sinp(x2,x3)+(x0-x3)*(k*x3+b)*0.5;
    	  	  	
    	  	k=-k;
    		b=-b;
    	  	A=1.0+k*k;
    	  	B=2.0*(b+D)*k;
    	  	C=sqr(b+D)-R*R;
    	  	x2=(-B+sqrt(B*B-4.0*A*C))/(2.0*A);
    	  	y2=k*x2+b;
    	  	if(y2+D>(-EPS))
    	  	  __area+=(Sin2(x3,x2)+(x0-x2)*(k*x2+b)*(-0.5));
    	  	else
    	  	  __area+=(Sin2(x3,R)+Sin3(x2,R)+(x0-R)*(k*R+b)*(-0.5));
    	  	printf("Case %d: %.8lf
    ",zu,__area*2.0+PI*R*R);
    	  }
    	return 0;
    }
  • 相关阅读:
    Windows下PATH等环境变量详解
    html表单,做个申请邮箱界面练习。
    截取字符串,去空格的练习。
    for循环
    c# if else的练习,判断闰年,输入日期,输出这是今年的的多少天!
    HTML
    输入输出2
    输入输出练习1
    Map练习
    数据库设计范式
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/6358200.html
Copyright © 2020-2023  润新知