BZOJ 1845 [Cqoi2005] 三角形面积并 计算几何扫描线

题意:链接方法:扫描线解析:扫描线裸题。先搞出所有边。之后求一下所有边的交点。按照x坐标排序。之后每两个不同的坐标间的面积其实就是中间截出来的所有梯形以及三角形的中位线的和乘以高度。至于中位线,再用这个与y轴平行的线截一下所有的三角形即可。统计长度。把所有的加起来即可。卡精!代码:;int n;struct Point{long double x,y;Point(){}Point(b):x(a),y(b){}friend istream& operator >> (istream &_,Point &a){cin>>a.x>>a.y;return _;}Point operator + (const Point &a){return Point(x+a.x,y+a.y);}Point operator – (const Point &a){return Point(x-a.x,y-a.y);}Point operator * (long double rate){return Point(x*rate,y*rate);}* (const Point &a){return x*a.x+y*a.y;}^ (const Point &a){return x*a.y-y*a.x;} };struct Line{Point p,v;Line(){}Line(Point a,Point b):p(a),v(b-a){}friend bool inside(Line &a,Point &b){long double x1=min(a.p.x,(a.p+a.v).x);long double x2=max(a.p.x,(a.p+a.v).x);return b.x>=x1&&b.x<=x2;}}l[N];int lines;Line MakeLine(Point &a,Point &b){l[++lines]=Line(a,b);return l[lines];}struct Triangle{Point a,b,c;Line l1,l2,l3;Triangle(){}Triangle(Point _a,Point _b,Point _c):a(_a),b(_b),c(_c){l1=MakeLine(_a,_b);l2=MakeLine(_b,_c);l3=MakeLine(_c,_a);}}tri[N];struct Interval{long double l,r;Interval(){}Interval(y):l(x),r(y){}< (Interval a,Interval b){if(a.l==b.l)return a.r<b.r;return a.l<b.l;}}interval[N];int intervals;Point Get_Intersection(Line &l1,Line &l2){Point u=l1.p-l2.p;long double tmp=(l2.v^u)/(l1.v^l2.v);return l1.p+l1.v*tmp;}long double X[M];int Xs;x,long double height){intervals=0;for(int i=1;i<=n;i++){Point p1=tri[i].a,p2=tri[i].b,p3=tri[i].c;if(x<min(p1.x,min(p2.x,p3.x))+eps||x+eps>max(p1.x,max(p2.x,p3.x)))continue;Line tmp=Line(Point(x,0),Point(x,1));Point pp1=Get_Intersection(tri[i].l1,tmp);Point pp2=Get_Intersection(tri[i].l2,tmp);Point pp3=Get_Intersection(tri[i].l3,tmp);if(!inside(tri[i].l1,pp1)){interval[++intervals].l=min(pp2.y,pp3.y);interval[intervals].r=max(pp2.y,pp3.y);}else if(!inside(tri[i].l2,pp2)){interval[++intervals].l=min(pp1.y,pp3.y);interval[intervals].r=max(pp1.y,pp3.y);}else{interval[++intervals].l=min(pp1.y,pp2.y);interval[intervals].r=max(pp1.y,pp2.y);}}sort(interval+1,interval+intervals+1);int j;long double length=0;for(int i=1;i<=intervals;i=j){for(j=i+1;j<=intervals;j++){if(interval[j].l<interval[i].r-eps)interval[i].r=max(interval[i].r,interval[j].r);else break;}length+=interval[i].r-interval[i].l;}return length*height;}int main(){scanf(“%d”,&n);for(int i=1;i<=n;i++){Point a,b,c;cin>>a>>b>>c;tri[i]=Triangle(a,b,c);}for(int i=1;i<=3*n;i++){for(int j=i+1;j<=3*n;j++){if(fabs(l[i].v^l[j].v)>eps)X[++Xs]=Get_Intersection(l[i],l[j]).x;}}sort(X+1,X+Xs+1);long double ans=0;for(int i=2;i<=Xs;i++){if(fabs(X[i]-X[i-1])>eps){long double tmpx=(X[i]+X[i-1])/2.0;long double height=X[i]-X[i-1];ans+=Triangle_Intersect(tmpx,height);}}cout<<fixed<<setprecision(2)<<ans-eps<<endl;}

,分之百的把自己推销给自己。

BZOJ 1845 [Cqoi2005] 三角形面积并 计算几何扫描线

相关文章:

你感兴趣的文章:

标签云: