ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

自适应辛普森积分

2020-07-14 16:03:25  阅读:278  来源: 互联网

标签:适应 return int 积分 seg db 辛普森 fa find


感觉就是骗分工具,就像模拟退火一样

神仙的博客

P4526自适应辛普森法2

#include<bits/stdc++.h>
typedef double db;
using namespace std;
const db eps=1e-7;
db a;
db f(db x)
{
	return pow(x,a/x-x);
}
db simpson(db l,db r)
{
	return (f(l)+f(r)+4*(f((l+r)/2)))*(r-l)/6;
}
db integral(db l,db r,db eps,db a)
{
	db mid=(l+r)/2;
	db L=simpson(l,mid),R=simpson(mid,r);
	if(abs(L+R-a)<=eps*15) return L+R+(L+R-a)/15;
	return integral(l,mid,eps/2,L)+integral(mid,r,eps/2,R);
}
int main()
{
	scanf("%lf",&a);
	if(a<0) printf("orz\n");
	else printf("%.5lf\n",integral(eps,20,eps,simpson(eps,20)));
	return 0;
} 

也可以用来求圆的面积并(尽管不是正解)

#include<bits/stdc++.h>
typedef double db;
using namespace std;
const int N=1100;
const db blo=10;
struct seg
{
	db l,r;
	seg(db x=0,db y=0):l(x),r(y){}
};
int fa[N];
db mx[N],mn[N];
int n;
db x[N],y[N],r[N];
map<double,double> hav;
int find(int x)
{
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
}
void merge(int a,int b)
{
	a=find(a),b=find(b);
	fa[a]=b;
	mx[b]=max(mx[b],mx[a]);
	mn[b]=min(mn[b],mn[a]);
	return;
}
int cmp(seg a,seg b)
{
	return a.l<b.l;
}
db f(db X)
{
	vector<seg> a;
	for(int i=1;i<=n;i++)
	{
		db d=abs(x[i]-X);
		if(r[i]<d) continue;
		d=sqrt(r[i]*r[i]-d*d);
		a.push_back(seg(y[i]-d,y[i]+d));
	}
	sort(a.begin(),a.end(),cmp);
	int siz=a.size();
	if(siz==0) return 0;
	db sum=0,l=a[0].l,r=a[0].r;
	for(int i=1;i<siz;i++)
	{
		if(a[i].l<=r) r=max(a[i].r,r);
		else
		{
			sum+=r-l;
			l=a[i].l;
			r=a[i].r;
		}
	}
	sum+=r-l;
	return sum;
}
db simpson(db l,db r)
{
	return (f(l)+f(r)+4*f((l+r)/2))*(r-l)/6;
}
db integral(db l,db r,db eps,db a)
{
	db mid=(l+r)/2;
	db L=simpson(l,mid),R=simpson(mid,r);
	if(abs(L+R-a)<=eps*15) return L+R+(L+R-a)/15;
	return integral(l,mid,eps/1.5,L)+integral(mid,r,eps/1.5,R);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&x[i],&y[i],&r[i]);
	for(int i=1;i<=n;i++) fa[i]=i,mn[i]=x[i]-r[i],mx[i]=x[i]+r[i];
	for(int i=1;i<=n;i++)
	{
		for(int j=i+1;j<=n;j++)
		{
			if(abs(x[i]-x[j])<=r[i]+r[j])
			{
				merge(i,j);
			}
		}
	}
	db ans=0;
	double cnt=0;
	for(int i=1;i<=n;i++) if(fa[i]==i) cnt+=1;
	for(int i=1;i<=n;i++) if(fa[i]==i) ans+=integral(mn[i],mx[i],1e-3/cnt,simpson(mn[i],mx[i]));
	printf("%.3lf\n",ans);
	return 0;
} 

标签:适应,return,int,积分,seg,db,辛普森,fa,find
来源: https://www.cnblogs.com/SegmentTree/p/13299529.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有