标签:次数 inter number follow https nes integer down algo
acm.hdu.edu.cn/showproblem.php?pid=4629
题意:
给出n个三角形,分别求出他们相交i次的面积,i∈[1,n]
在求面积并的基础上修改
求面积并:https://www.cnblogs.com/TheRoadToTheGold/p/12221288.html
当计算中位线的长度时,把端点离散化,利用前缀和差分计算覆盖次数
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const double eps=1e-10; const int inf=101; int n; struct Point { double x,y; Point(double x_=0,double y_=0) : x(x_),y(y_) {} }tri[51][4],seg[51]; typedef Point Vector; double px[25001],ans[51]; double has[25001]; int cnt[101]; Point operator - (Point A,Point B) { return Point(A.x-B.x,A.y-B.y); } Vector operator + (Vector A,Vector B) { return Vector(A.x+B.x,A.y+B.y); } Vector operator * (Vector A,double p) { return Vector(A.x*p,A.y*p); } int dcmp(double x) { if(fabs(x)<eps) return 0; return x<0 ? -1 : 1; } double Cross(Vector A,Vector B) { return A.x*B.y-A.y*B.x; } bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2) { double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1); return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0; } Point GetLineIntersection(Point P,Vector v,Point Q,Vector w) { Vector u=P-Q; double t=Cross(w,u)/Cross(v,w); return P+v*t; } void cal(double line,double h) { Point up(line,inf),down(line,-inf); int m=0,k,tot=0; double py[3]; for(int i=1;i<=n;++i) { k=0; for(int j=0;j<3;++j) if(SegmentProperIntersection(tri[i][j],tri[i][j+1],up,down)) py[++k]=GetLineIntersection(tri[i][j],tri[i][j+1]-tri[i][j],up,up-down).y; if(k) { seg[++m]=Point(min(py[1],py[2]),max(py[1],py[2])); has[++tot]=py[1]; has[++tot]=py[2]; } } sort(has+1,has+tot+1); int opl,opr; memset(cnt,0,sizeof(cnt)); for(int i=1;i<=m;++i) { opl=lower_bound(has+1,has+tot+1,seg[i].x)-has; opr=lower_bound(has+1,has+tot+1,seg[i].y)-has; cnt[opl]++; cnt[opr]--; } for(int i=1;i<=tot;++i) cnt[i]+=cnt[i-1]; for(int i=1;i<tot;++i) ans[cnt[i]]+=(has[i+1]-has[i])*h; } int main() { int T,m; scanf("%d",&T); while(T--) { scanf("%d",&n); m=0; for(int i=1;i<=n;++i) { for(int j=0;j<3;++j) { scanf("%lf%lf",&tri[i][j].x,&tri[i][j].y); px[++m]=tri[i][j].x; } tri[i][3]=tri[i][0]; } for(int i=1;i<n;++i) for(int j=i+1;j<=n;++j) for(int k=0;k<3;++k) for(int l=0;l<3;++l) if(SegmentProperIntersection(tri[i][k],tri[i][k+1],tri[j][l],tri[j][l+1])) px[++m]=GetLineIntersection(tri[i][k],tri[i][k+1]-tri[i][k],tri[j][l],tri[j][l+1]-tri[j][l]).x; sort(px+1,px+m+1); memset(ans,0,sizeof(ans)); for(int i=2;i<=m;++i) if(dcmp(px[i]-px[i-1])) cal((px[i]+px[i-1])/2,px[i]-px[i-1]); for(int i=1;i<=n;++i) printf("%.10lf\n",ans[i]); } return 0; }
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 705 Accepted Submission(s): 283
Special Judge
标签:次数 inter number follow https nes integer down algo
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12222507.html