math专辑
1.hdoj 3310 Volume of a cylinder
求两个圆柱相交部分的体积。
第一象限积分公式:sqrt(R * R - (r - x) * (r - x)) * sqrt(r * r - (r - x) * (r - x)); 从0积到r 。最后结果乘8。
可是不知道为什么我用龙贝格积分却错了,用分割小块就AC了,忘路过大牛指点。
分割小块:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; const int cntStep = 1000000; double solve(double R, double r) { double step, ans = 0; double w, h, pos; int i; step = r / (cntStep * 1.0); for(i=0; i<cntStep; ++i) { pos = i * step + step/2; h = sqrt(R * R - (r - pos) * (r - pos)); w = sqrt(r * r - (r - pos) * (r - pos)); ans += w * h; } return ans * step * 8; } int main() { // freopen("c:/aaa.txt", "r", stdin); int T; double temp, R, r; scanf("%d", &T); while(T --) { scanf("%lf %lf", &R, &r); if(R < r) { temp = R; R = r; r = temp; } printf("%.2lf\n", solve(R, r)); } return 0; }
龙贝格法:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; #define ep 0.000001 //精度限制 const int M = 100; double ans[M][M]; double R, r; double f(double x) { return 4 * sqrt(R * R - (r - x) * (r - x)) * sqrt(r * r - (r - x) * (r - x)); } double Romberg(double a,double b) { //从a积到b double h,temp; double v; int i,j,k,n; bool flag=1; h = b - a; ans[0][0] = h/2 * ( f(a) + f(b) ); for(i=1;i<20;++i){ for(j=0;j<=i;++j){ if(j==0) { ans[i][0] = ans[i-1][0]/2; n = (int)pow(2.0,i); for(k=1,temp=0;k<=n/2;++k){ v = h/n*(2*k-1) + a; temp+=f(v); } temp = temp*h/n; ans[i][0]+=temp; } else{ n=(int)pow(4.0,j); ans[i][j] = (ans[i][j-1]*n - ans[i-1][j-1])/(n-1); } } temp = fabs(ans[i][i] - ans[i-1][i-1]) ; if(temp <= ep){ return ans[i][i]; } } return ans[19][19]; } int main() { // freopen("c:/aaa.txt", "r", stdin); int T; double temp; scanf("%d", &T); while(T --) { scanf("%lf %lf", &R, &r); if(R < r) { temp = R; R = r; r = temp; } printf("%.2lf\n", 2 * Romberg(0, r)); } return 0; }