记录编号 158217 评测结果 AAAAAAAAAA
题目名称 Uyuw的音乐会 最终得分 100
用户昵称 Gravatarztx 是否通过 通过
代码语言 C++ 运行时间 0.702 s
提交时间 2015-04-13 16:16:10 内存使用 2.12 MiB
显示代码纯文本
/****************************************\
* Author : ztx
* Title  : [poj] 2451 Uyuw's Concert
* ALG    : 半平面交O(nlog)学习
* CMT    :
* Time   :
\****************************************/

#include <cstdio>
#define Rep(i,l,r) for(i=(l);i<=(r);i++)
#define Rev(i,r,l) for(i=(r);i>=(l);i--)
typedef long long ll ;
int CH , NEG ;
template <typename TP>inline void read(TP& ret) {
    ret = NEG = 0 ; while (CH=getchar() , CH<'!') ;
    if (CH == '-') NEG = true , CH = getchar() ;
    while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ;
    if (NEG) ret = -ret ;
}
template <typename TP>inline void reads(TP& ret) {
	while (ret=getchar() , ret<'!') ;
	while (CH=getchar() , CH>'!') ;
}

#include <algorithm>
#include <cmath>

#define  maxn  20010LL
#define  infi  10000LL
#define  eps   1e-10
inline int sign(double x) { return (x>eps)-(x<-eps) ; }

struct POINT {
	double x,y;
	POINT operator - (const POINT& b) const
	{ return (POINT){x-b.x,y-b.y} ; }
	double operator * (const POINT& b) const
	{ return x*b.y-b.x*y; }
} p[maxn],o ;
typedef POINT VECTOR ;

struct LINE {
	POINT a , b ; double ang ;
	void init(double x,double y,double xx,double yy)
	{ a.x=x;a.y=y;b.x=xx;b.y=yy; }
} L[maxn] , q[maxn] ;
int n , m , cnt ;

inline double Cross(POINT a,POINT b,POINT c)
{ return (b-a)*(c-a) ; }

inline POINT GetCross(LINE& a,LINE& b) {
	double k1 = Cross(a.a,b.b,b.a) ;
	double k2 = Cross(a.b,b.a,b.b) ;
	POINT tmp=a.b-a.a,ans;
	ans.x=a.a.x+tmp.x*k1/(k1+k2) ;
	ans.y=a.a.y+tmp.y*k1/(k1+k2) ;
	return ans ;
}

inline bool cmp(const LINE& a,const LINE& b)
{ return sign(a.ang-b.ang) ? a.ang>b.ang : sign(Cross(a.a,a.b,b.a))<0 ; }

inline void Cut() {
int i , l , r ;
	std::sort(L+1,L+n+1,cmp) ;
	m = 1 ;
	Rep (i,2,n) if (sign(L[i].ang-L[m].ang)) L[++m] = L[i] ;
	q[l=1]=L[1],q[r=2]=L[2] ;
	Rep (i,3,m) {
		while (l<r && sign(Cross(L[i].a,L[i].b,GetCross(q[r],q[r-1])))<0) r-- ;
		while (l<r && sign(Cross(L[i].a,L[i].b,GetCross(q[l],q[l+1])))<0) l++ ;
		q[++r] = L[i] ;
	}
	while (l<r && sign(Cross(q[l].a,q[l].b,GetCross(q[r],q[r-1])))<0) r-- ;
	while (l<r && sign(Cross(q[r].a,q[r].b,GetCross(q[l],q[l+1])))<0) l++ ;
	if (l == r) return ;
	cnt = 0 ;
	Rep (i,l,r-1) p[++cnt] = GetCross(q[i],q[i+1]) ;
	if (r-1>l) p[++cnt] = GetCross(q[l],q[r]) ;
}

inline double GetArea() {
int i ;
	double ret = 0.0 ;
	p[cnt+1] = p[1] ;
	Rep (i,1,cnt) ret += Cross(o,p[i],p[i+1]) ;
	return ret ;
}

int main() {
int i ;
	#define READ
	#ifdef  READ
		freopen("concert.in" ,"r",stdin ) ;
		freopen("concert.out","w",stdout) ;
	#endif
	while (scanf("%d",&n)!=EOF && n) {
		Rep (i,1,n) {
			scanf("%lf%lf%lf%lf",&L[i].a.x,&L[i].a.y,&L[i].b.x,&L[i].b.y) ;
			L[i].ang = atan2(L[i].b.y-L[i].a.y,L[i].b.x-L[i].a.x) ;
		}
		L[n+1].init(0,0,infi,0) ;
		L[n+2].init(0,infi,0,0) ;
		L[n+3].init(infi,0,infi,infi) ;
		L[n+4].init(infi,infi,0,infi) ;
		Rep (i,n+1,n+4) L[i].ang=atan2(L[i].b.y-L[i].a.y,L[i].b.x-L[i].a.x) ;
		n += 4 ;
		Cut() ;
		printf("%.1lf\n", (double)fabs(GetArea())*0.5) ;
	}
	#ifdef  READ
		fclose(stdin) ; fclose(stdout) ;
	#else
		getchar() ; getchar() ;
	#endif
	return 0 ;
}