社区讨论

simpson积分为什么会被卡啊(不是精度问题)

学术版参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mi7x3j34
此快照首次捕获于
2025/11/21 05:02
4 个月前
此快照最后确认于
2025/11/21 05:02
4 个月前
查看原帖
比如bzoj2178圆的面积并
CPP
2
-2 -2 2
1 2 2
这组简单数据就把我代码干掉了,而且精度开大开小都一样
CPP
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;

int n,i,j;

long double p[2005],ans;

struct cr
{
	long double x,y,r;
};
cr c[1005];

cr avi[1005];
int cnt,ccnt;

struct node
{
	long double y,kd;
	bool operator <(const node&a)const
	{
		return y<a.y;
	}
};
node cross[2005];
long double f(long double x)
{
	ccnt=0;
	long double now,l,ret=0;
	for(int i=1;i<=cnt;i++)
		if(abs(x-avi[i].x)<avi[i].r)
			now=sqrt(avi[i].r*avi[i].r-(x-avi[i].x)*(x-avi[i].x)),cross[++ccnt]=(node){avi[i].y-now,1},cross[++ccnt]=(node){avi[i].y+now,-1};
	sort(cross+1,cross+1+ccnt);
	l=cross[1].y;now=1;
	for(int i=2;i<=ccnt;i++)
		if(cross[i].kd==1)
			now++,ret+=(cross[i].y-l)*(now!=0),l=cross[i].y;
		else now--,ret+=cross[i].y-l,l=cross[i].y;
	return ret;
}
long double calc(long double l,long double r)
{
	return (r-l)*(f(l)+f(r)+4*f((l+r)/2))/6;
}
long double simpson(long double l,long double r,long double eps)
{
	if(l>r)
		return 0;
	long double mid=(l+r)/2,L=calc(l,mid),R=calc(mid,r),ans=calc(l,r);
	if(abs(ans-L-R)<eps)
		return ans;
	else return simpson(l,mid,eps/2)+simpson(mid,r,eps/2);
}

char Getchar()
{
	return getchar();
	static char buff[1000000],*p,*end=p;
	if(p==end)
		end=buff+fread(p=buff,1,1000000,stdin);
	if(p==end)
		return -1;
	return *(p++);
}
template<typename T>void read(T &x)
{
	static char rc;static int flag;
	x=0;rc=Getchar();flag=1;
	while(!isdigit(rc))
		flag=(rc=='-'?-1:1),rc=Getchar();
	while(isdigit(rc))
		x=x*10+rc-'0',rc=Getchar();
	x*=flag;
}

int main()
{
//	freopen("in.txt","r",stdin);
	read(n);
	for(i=1;i<=n;i++)
		read(c[i].x),read(c[i].y),read(c[i].r),p[i*2-1]=c[i].x-c[i].r,p[i*2]=c[i].x+c[i].r;
	sort(p+1,p+1+n*2);
	for(i=1;i<n*2;i++)
		if(p[i]!=p[i+1])
		{
			cnt=0;
			for(j=1;j<=n;j++)
				if(p[i]<c[j].x+c[j].r&&c[j].x-c[j].r<p[i+1])
					avi[++cnt]=c[j];
			ans+=simpson(p[i],p[i+1],1e-8);
		}
	printf("%0.3Lf",ans);
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...