acdream 1234 Two Cylinders

Two Cylinders

Special JudgeTime Limit: 10000/5000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others)

Problem Description

      In this problem your task is very simple.

      Consider two infinite cylinders in three-dimensional space, of radii R1 and R2 respectively, located in such a way that their axes intersect and are perpendicular.

      Your task is to find the volume of their intersection.

Input

      Input file contains two real numbers R1 and R2 (1 <= R1,R2 <= 100).

Output

      Output the volume of the intersection of the cylinders. Your answer must be accurate up to 10-4.

Sample Input

1 1

Sample Output

5.3333

Source

Andrew Stankevich Contest 3

Manager



題解及代碼:

        這道題的意思很簡單,就是求兩個垂直相交的圓柱的重合體積。推導的思想可以見:點擊打開鏈接

        根據上面的方法我們可以推出截面公式是sqrt(R*R-x*x)*sqrt(r*r-x*x),然後積分的上下限是0--r。

        雖然這公式推出來了,但是積分很困難(沒推出來= =!),下面的代碼用的是辛普森積分法,學習了一下,挺簡單的。

        主要就是這個:

        這個公式在數比較小的時候,誤差不大,但是數比較大的時候,誤差就很大了,所以計算過程中要使用二分來把區間減小,減小誤差。


#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double eps=1e-7;

double R,r;

double f(double n)
{
    return 8*sqrt(R*R-n*n)*sqrt(r*r-n*n);
}

double simpson(double a,double b)
{
    return (b-a)/6.0*(f(a)+4*f((a+b)/2.0)+f(b));
}

double cal(double a,double b)
{
    double sum=simpson(a,b),mid=(a+b)/2.0;
    double t=simpson(a,mid)+simpson(mid,b);

    if(fabs(t-sum)<eps) return sum;
    return cal(a,mid)+cal(mid,b);
}
int main()
{
    scanf("%lf%lf",&R,&r);
    if(R<r) swap(R,r);

    printf("%.5lf\n",cal(0,r));
    return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章