自适应辛普森
来源:互联网 发布:华为中央软件院 知乎 编辑:程序博客网 时间:2024/06/03 01:29
数学没学好还真吃亏。
首先介绍下辛普森公式(没法帖图片,只能口述),对于一段函数,我们要求面积,除了求反导之外,有一种近似方法,即用辛普森公式。
(来自维基)
a,b分别指函数最左端和最右端,这个公式推导可以去维基上看,他有个直观的应用便是求拟柱体(比如棱柱)体积,f函数便代表截面面积,套一套求体积的公式或许会好理解一点。
仅仅是套公式是不行的,或许这三个点均是特殊点(比如极值),误差那不是一般的大。怎么办呢?我们可是学信息的,一边不行多套几边公式计算机还是办得到的。
下面介绍自适应辛普森
将一段区间二分,再将两端区间求出的面积合并,如此递归下去。为了保证误差足够小,如果两端用上述公式算出面积之和近似等于该区间用上述公式求出面积,便不再递归,返回值。
如此一来,即缩小误差,又节省了在函数图象较平整区域的计算时间。
题目参见:http://hi.baidu.com/cheezer94/blog/item/541e5cd5d761d8c38c1029e6.html
我写的不是很漂亮,卡精度才过的(主要是求f值时,每次我都得扫一遍o(n)),cheezer哲爷写的应该不错
uses math;const eps=0.00001; eps1=0.01;//type real=extended;var x,y,mid,m,r,l,h:array[1..1000]of real; n:longint; ans,w,w0,hh:real;function dist(x1,x2,y1,y2:real):real;inline;begin exit(sqrt(sqr(x1-x2)+sqr(y1-y2)))end;function delt(b,a,c:real):real;inline;begin exit(sqrt(sqr(b)-4*a*c))end;function func(x:real):real;inline;var tmp,cosi,min,a,b,c,d,ne:real; i:longint;begin func:=maxlongint;min:=maxlongint; for i:=1 to n do if (-cos(l[i])<=-cos(x))and(-cos(x)<=-cos(h[i])) then begin tmp:=abs(x-m[i]); if tmp<eps then min:=mid[i]-r[i] else begin tmp:=abs(x-l[i]); if tmp<eps then min:=sqrt(sqr(mid[i])-sqr(r[i])) else begin tmp:=abs(x-h[i]); if tmp<eps then min:=sqrt(sqr(mid[i])-sqr(r[i])) else begin ne:=abs(x-m[i]); a:=1;b:=-2*mid[i]*cos(ne);c:=sqr(mid[i])-sqr(r[i]); d:=delt(b,a,c); cosi:=(-b-d)/(2*a); if cosi>=0 then min:=cosi end end end; if min<func then func:=min end; tmp:=abs(x-pi/2); if (tmp>eps)and(x<pi/2)and(x<>0) then begin min:=(w-w0)*tan(x); min:=dist(w,w0,min,0) end else if (x>pi/2)and(tmp>eps) then begin min:=-w0*tan(x); min:=dist(w0,0,min,0) end else if x=0 then min:=w-w0; tmp:=abs(x-pi); if min<func then func:=min; if (abs(x-pi/2)>eps)and(x<>0)and(tmp>eps) then begin min:=hh/tan(x)+w0; min:=dist(w0,min,hh,0) end else if (x<>0)and(tmp>eps) then begin min:=hh end; if min<func then func:=min; func:=(1/2)*sqr(func)end;function simpson(l,r,tmp1,tmp2,tmp3:real):real;inline;begin exit((r-l)*(tmp1+tmp3+tmp2*4)/6)end;function count(tmp1,tmp2,tmp3,l,r:real):real;inline;var m,x,tmpl,tmpr,tmp:real;begin m:=(l+r)/2; x:=simpson(l,r,tmp1,tmp2,tmp3); tmpl:=func((l+m)/2);tmpr:=func((m+r)/2); tmp:=simpson(l,m,tmp1,tmpl,tmp2)+simpson(m,r,tmp2,tmpr,tmp3); if abs(x-tmp)<eps1 then exit(tmp) else begin count:=count(tmp1,tmpl,tmp2,l,m)+count(tmp2,tmpr,tmp3,m,r) endend;procedure init;var i:longint; mm,ne,tmp1,tmp2,tmp3:real;begin readln(n,w,hh,w0); for i:=1 to n do begin readln(x[i],y[i],r[i]); mid[i]:=dist(x[i],w0,y[i],0); if x[i]>w0 then mm:=arctan(y[i]/(x[i]-w0)) else if x[i]<w0 then mm:=pi-arctan(y[i]/(w0-x[i])) else mm:=pi/2; ne:=arcsin(r[i]/mid[i]); l[i]:=mm-ne;h[i]:=mm+ne;m[i]:=mm end; tmp1:=func(0);tmp2:=func(pi/2);tmp3:=func(pi); ans:=count(tmp1,tmp2,tmp3,0,pi); writeln(ans/(w*hh):0:8)end;beginassign(input,'yc.in');reset(input);assign(output,'yc.out');rewrite(output); init;close(output);close(input)end.
- 自适应辛普森
- 自适应辛普森公式模版
- 自适应辛普森模板
- 自适应辛普森积分
- 自适应辛普森积分算法
- 自适应辛普森积分
- 自适应
- 自适应
- UVA 1356 - Bridge(自适应辛普森)
- 自适应辛普森公式求积分
- UVA 1356 Bridge 自适应辛普森
- LA 3485 自适应辛普森公式
- Hdu 4498 自适应辛普森积分
- hdu-1742Ellipse(自适应辛普森)
- Hdu 1724 Ellipse (自适应辛普森积分法)
- HDU 1724 Ellipse (自适应辛普森公式)
- HDU 1724 Ellipse 自适应辛普森积分
- BZOJ 1502 月下柠檬树 自适应辛普森积分
- SQL语句的执行过程
- epoll使用详解(精髓)
- 共享免费美国大学课程资料地址
- 用C语言创建第一个Win32 Application
- Oracle-PL/SQL错误处理
- 自适应辛普森
- 尼克的任务
- Visaul C++ 2010 入门经典 学习笔记(1)
- Java工程师可能不知道的那些FE潜规则
- 我的爱情(一)
- 利用PowerDesigner比较2个数据库结构
- 鱼缸里的鱼
- 今天给大家讲解一下在自定义View中,如何实现画图。
- Java泛型的好处