凸多邊形的面積並好像有很多搞法,網上有O(N^2logN)的演算法,窩只會O(N^3logN)的掃描線暴力(好像能做到O(N^3)是麼求解。。把所有三角形的端點和交點放在一起排序,這樣所有映像就被分成了若干個區間,每個區間內的面積都是若干個梯形(三角形也可以當做梯形來做),然後求中位線的總長累計面積就行了。求中位線長的時候就用X=mid去得到所有交點,然後排個序,記錄經過某個交點是進一個三角形還是出一個三角形,當為0的時候就累加一下長度,還是很好寫的。。沒怎麼調就過了,,不過答案要-eps才能過。。
#include<cstdio>#include<iostream>#include<cmath>#include<algorithm>#include<cstdio>#include<cmath>#include<iostream>#include<algorithm>#include<memory.h>#define h1 que[head]#define h2 que[head+1]#define t1 que[tail]#define t2 que[tail-1]#define N 510#define eps 1e-8using namespace std;struct point{double x,y;point(){}point(double x,double y):x(x),y(y){}}p[N],p1,p2,h;struct line{point p,v;double angle;}a[N],que[N];int i,j,head,tail,cnt,n,m,tot;double ans;point operator-(point a,point b){return point(a.x-b.x,a.y-b.y);}point operator+(point a,point b){return point(a.x+b.x,a.y+b.y);}point operator*(double k,point a){return point(k*a.x,k*a.y);}double operator*(point a,point b){return a.x*b.y-a.y*b.x;}bool cmp(line a,line b){if (a.angle!=b.angle) return a.angle<b.angle;else return b.v*(a.p-b.p)>0;}point cross(line a,line b){point t=a.p+a.v;double k1=(a.p-b.p)*b.v,k2=b.v*(t-b.p),k=k1/(k1+k2);return k*a.v+a.p;}bool judge(line x1,line x2,line i){point t=cross(x1,x2);return i.v*(t-i.p)>0;}void push(line x){while (head<tail&&!judge(t1,t2,x)) tail--;while (head<tail&&!judge(h1,h2,x)) head++;que[++tail]=x;}void hpi(){int i;sort(a+1,a+1+tot,cmp);a[0].angle=-10.12345;for (i=1,cnt=0;i<=tot;i++)if (a[i].angle!=a[i-1].angle) a[++cnt]=a[i];que[1]=a[1];head=tail=1;for (i=2;i<=cnt;i++) push(a[i]);while (head<tail&&!judge(t1,t2,h1)) tail--;while (head<tail&&!judge(h1,h2,t1)) head++;que[tail+1]=que[head];cnt=0;for (i=head;i<=tail;i++) p[++cnt]=cross(que[i],que[i+1]);}double area(){double s=0;if (cnt<3) return s;p[cnt+1]=p[1];for (int i=1;i<=cnt;i++) s+=p[i]*p[i+1];return fabs(s)/2;}int main(){freopen("2618.in","r",stdin);scanf("%d",&n);tot=0;for (i=1;i<=n;i++){scanf("%d",&m);scanf("%lf%lf",&p1.x,&p1.y);h=p1;for (j=1;j<m;j++){scanf("%lf%lf",&p2.x,&p2.y);a[++tot].p=p1;a[tot].v=p2-p1;a[tot].angle=atan2(a[tot].v.y,a[tot].v.x);p1=p2;}p2=h;a[++tot].p=p1;a[tot].v=p2-p1;a[tot].angle=atan2(a[tot].v.y,a[tot].v.x);}hpi();printf("%.3lf",area());}