社区讨论
simpson积分为什么会被卡啊(不是精度问题)
学术版参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mi7x3j34
- 此快照首次捕获于
- 2025/11/21 05:02 4 个月前
- 此快照最后确认于
- 2025/11/21 05:02 4 个月前
比如bzoj2178圆的面积并
CPP2
-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 条回复,欢迎继续交流。
正在加载回复...