zoj2369

/*辛普森积分公式,以r1以x为轴,r2以y为轴
那么从z方向看过去,每个平行于xoy平面的前面都是矩形,
所以矩形面积=4*sqrt(r1*r1-z*z)*sqrt(r2*r2-z*z)
所以因为对称性所以体积为2*simpson(0,r1,f),f为矩形面积函数

0和r1是积分上下限,且要保证r1<=r2

在zoj上交一直出现分段错,

在比较float和double类型的时候,
因为float/double精度的问题
 
比如 1.000000001 可能和1.0000000000001相等
 
不应该直接使用 a > b 等类似的方式进行比较
 
而是采用 两个数做差取绝对值然后跟 你指定的精度进行比较 
便可得出 两个double/float的大小

*/
#include
#include
#include
using namespace std;
double ep=1e-9;
double r1,r2;
inline int sig(double x)
{
return (x>ep)-(x<-ep);
}
inline double f(double x)
{
return 4.*sqrt(r1*r1-x*x)*sqrt(r2*r2-x*x);
}
inline double simpson(double a,double b)
{
return (b-a)*(f(a)+4.*f((a+b)/2.)+f(b))/6.;
}
inline double cacl(double a,double b,int depth)
{
double total=simpson(a,b),mid=(a+b)/2.;
double tmp=simpson(a,mid)+simpson(mid,b);
if(sig(total-tmp)==0 && depth>3) return total;
return cacl(a,mid,depth+1)+cacl(mid,b,depth+1);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lf%lf",&r1,&r2);
double t;
if(sig(r1-r2)>0) swap(r1,r2);//这里是个注意点,不能直接比较大小

printf("%.4lf\n",2.*cacl(0.,r1,0));
}
return 0;
}

你可能感兴趣的:(计算几何)