参考题目:CQOI2006凸多边形
解析:
联赛结束后统一更模板题题解
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline int getint(){
re int num;
re char c;
re bool f=0;
while(!isdigit(c=gc()))if(c=='-')f=1;num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return f?-num:num;
}
cs double eps=1e-8;
cs int N=505;
int n,tot;
struct Point{
double x,y;
Point(cs double &_x=0,cs double &_y=0):x(_x),y(_y){}
friend Point operator+(cs Point &a,cs Point &b){return Point(a.x+b.x,a.y+b.y);}
friend Point operator-(cs Point &a,cs Point &b){return Point(a.x-b.x,a.y-b.y);}
friend double operator*(cs Point &a,cs Point &b){return a.x*b.y-b.x*a.y;}
friend double dot(cs Point &a,cs Point &b){return a.x*b.x+b.y*a.y;}
friend Point operator*(cs Point &a,cs double &b){return Point(a.x*b,a.y*b);}
}b[N];
inline int sign(cs double &x){
return fabs(x)<=eps?0:(x>0?1:-1);
}
struct Line{
Point s,e;
double rad;
friend bool operator<(cs Line &a,cs Line &b){
return sign(a.rad-b.rad)==0?sign((a.e-a.s)*(b.e-a.s))>0:sign(a.rad-b.rad)<0;
}
}a[N],q[N];
inline Point InterSection(cs Line &a,cs Line &b){
double s1=(a.s-a.e)*(b.e-a.e),s2=(b.s-a.e)*(a.s-a.e);
double k=s2/(s1+s2);
return b.s+(b.e-b.s)*k;
}
inline bool judge(cs Line &a,cs Line &b,cs Line &c){
return sign((c.e-c.s)*(InterSection(a,b)-c.s))<0;
}
int head,tail;
void half_plane_inter(){
n=0;
sort(a+1,a+tot+1);
for(int re i=1;i<=tot;++i){
if(sign(a[i].rad-a[i-1].rad))++n;
a[n]=a[i];
}
head=1,tail=2;
q[1]=a[1],q[2]=a[2];
for(int re i=3;i<=n;++i){
while(head<tail&&judge(q[tail-1],q[tail],a[i]))--tail;
while(head<tail&&judge(q[head+1],q[head],a[i]))++head;
q[++tail]=a[i];
}
while(head<tail&&judge(q[tail-1],q[tail],q[head]))--tail;
while(head<tail&&judge(q[head+1],q[head],q[tail]))++head;
n=0;q[tail+1]=q[head];
for(int re i=head;i<=tail;++i)b[++n]=InterSection(q[i],q[i+1]);
}
inline double area(){
double ans=0;
for(int re i=1;i<=n;++i)ans+=b[i]*b[i%n+1];
return fabs(ans)/2;
}
signed main(){
n=getint();
for(int re i=1;i<=n;++i){
int k=getint();
for(int re j=1;j<=k;++j)b[j].x=getint(),b[j].y=getint();
for(int re j=1;j<=k;++j)a[++tot].s=b[j],a[tot].e=b[j%k+1];
}
for(int re i=1;i<=tot;++i)a[i].rad=atan2(a[i].e.y-a[i].s.y,a[i].e.x-a[i].s.x);
half_plane_inter();
printf("%.3f",area());
return 0;
}