【数值积分】 ZOJ 2369 Two Cylinders

先算出积分表达式:4 * sqrt(r1 * r1 - x * x) * sqrt(r2 * r2 - x * x)。。。。然后用simpson积分法积出答案即可。。。

#include <iostream>  
#include <queue>  
#include <stack>  
#include <map>  
#include <set>  
#include <bitset>  
#include <cstdio>  
#include <algorithm>  
#include <cstring>  
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 20005
#define maxm 40005
//#define eps 1e-10
#define mod 10000007
#define INF 1e9
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid  
#define rson o<<1 | 1, mid+1, R  
typedef long long LL;
//typedef int LL;
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
void scanf(int &__x){__x=0;char __ch=getchar();while(__ch==' '||__ch=='\n')__ch=getchar();while(__ch>='0'&&__ch<='9')__x=__x*10+__ch-'0',__ch = getchar();}
LL gcd(LL _a, LL _b){if(!_b) return _a;else return gcd(_b, _a%_b);}
//head

double r1, r2;
double f(double x)
{
	double t1 = r1 * r1 - x * x;
	double t2 = r2 * r2 - x * x;
	return 4 * sqrt(t1) * sqrt(t2);
}
double simpson(double a, double b)
{
	double c = (a + b) / 2;
	return (f(a) + 4 * f(c) + f(b)) * (b - a) / 6;
}
double calc(double a, double b, double eps, double res)
{
	double c = (a + b) / 2;
	double l = simpson(a, c), r = simpson(c, b);
	if(fabs(l + r - res) < 15.0 * eps) return l + r + (l + r - res) / 15.0;
	return calc(a, c, eps / 2, l) + calc(c, b, eps / 2, r);
}
void work(void)
{
	double r = min(r1, r2);
	double ans = calc(-r, r, 1e-5, simpson(-r, r));
	printf("%.4f\n", ans);
}
int main(void)
{
	int _;
	while(scanf("%d", &_)!=EOF) {
		while(_--) {
			scanf("%lf%lf", &r1, &r2);
			work();
			if(_) printf("\n");
		}
	}
	return 0;
}


你可能感兴趣的:(ZOJ)