hdu 1724 自适应simpson 或 romberg
题意:
求椭圆面积, x^2/a^2+y^2/b^2=1, 给出a,b,l,r, 求椭圆被直线x=l, x=r所夹面积。
思路:
1. 自适应simpson,精度不是很高,所以eps要设小一点。
2. romberg,精度很好,但效率不是很高。
自适应simpson:
/*hdu 1724
题意:
求椭圆面积, x^2/a^2+y^2/b^2=1, 给出a,b,l,r, 求椭圆被直线x=l, x=r所夹面积。
思路:
自适应simpson,精度不是很高,所以eps要设小一点。
*/
#include
#include
#include
using namespace std;
const double eps=1e-6;
double a,b;
double f(double x){ //积分函数
return 2*b*sqrt(1-x*x/(a*a));
}
//三点simpson法
double simpson(double a,double b){
double c = a+(b-a)/2;
return (f(a) + 4*f(c) + f(b))*(b-a)/6;
}
//自适应Simpson公式(递归过程)。已知整个区间[a,b]上的三点simpson值A
double asr(double a , double b ,double eps ,double A){
double c = a+ (b-a)/2;
double L = simpson(a,c) ,R = simpson(c,b);
if(fabs(A-L-R)<=15*eps) return L + R +(A-L-R)/15;
return asr(a,c,eps/2,L) + asr(c,b,eps/2,R);
}
//自适应Simpson公式(主过程)
double asr(double a, double b, double eps){
return asr(a, b, eps, simpson(a, b));
}
int main(){
int T;
double l,r;
scanf("%d",&T);
while(T--){
scanf("%lf%lf%lf%lf",&a,&b,&l,&r);
printf("%.3f\n",asr(l,r,eps));
}
return 0;
}
romberg:
/*hdu 1724
题意:
求椭圆面积, x^2/a^2+y^2/b^2=1, 给出a,b,l,r, 求椭圆被直线x=l, x=r所夹面积。
思路:
romberg,精度很好,但效率不是很高。
*/
#include
#include
#include
#include
using namespace std;
#define PB push_back
const double EPS=1e-4;
template
double romberg(const T &f,double a,double b){ vector
t; double h=b-a,last,curr; int k=1,i=1; t.PB(h*(f(a)+f(b))/2); //梯形 do{ last=t.back(); curr=0; double x=a+h/2; for(int j=0;j
EPS); return t.back(); } double a,b; double f(double x){ //积分函数 return 2*b*sqrt(1-x*x/(a*a)); } int main(){ int T; scanf("%d",&T); double l,r; while(T--){ scanf("%lf%lf%lf%lf",&a,&b,&l,&r); printf("%.3f\n",romberg(f,l,r)); } return 0; }