记录编号 229972 评测结果 AAAAAAAAAA
题目名称 Uyuw的音乐会 最终得分 100
用户昵称 GravatarSatoshi 是否通过 通过
代码语言 C++ 运行时间 1.994 s
提交时间 2016-02-21 04:01:47 内存使用 1.52 MiB
显示代码纯文本
#include <fstream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <deque>
#include <iomanip>
#define N 20010
using namespace std;
typedef long double ld;
ifstream in("concert.in");
ofstream out("concert.out");
ld eps=1e-10,pi=2*asin(1.0);
int n;


class point
{
public:
	ld x,y;
	void make(ld a,ld b)
	{
		x=a;
		y=b;
	}
	void print()
	{
		out<<x<<' '<<y<<endl;
	}
};
ld operator ^(point a,point b)
{
	ld solo;
	solo=a.x*b.y-a.y*b.x;
	return solo;
};
point operator -(point a,point b)
{
	point c;
	c.x=a.x-b.x;
	c.y=a.y-b.y;
	return c;
}
point operator +(point a,point b)
{
	point c;
	c.x=a.x+b.x;
	c.y=a.y+b.y;
	return c;
}
class line
{
public:
	ld A,B,C;
	ld an;
	void make(ld a,ld b,ld c,ld d)
	{
		A=a;B=b;C=c;an=d;
	}
	void print()
	{
		out<<an<<' '<<A<<' '<<' '<<B<<' '<<C<<endl;
	}
}H[N];
deque<line> Q;
point P[N];
bool operator <(line a,line b)
{
	return a.an<b.an;
}
ld operator *(point a,line b)
{
	ld solo;
	solo=a.x*b.A+a.y*b.B;
	return solo;
}
bool inside(point a,line b)
{
	return a*b<(b.C-eps);
}
point cross(line a,line b)
{
	point c;
	c.x=(a.C*b.B-a.B*b.C)/(a.A*b.B-a.B*b.A);
	c.y=(a.A*b.C-a.C*b.A)/(a.A*b.B-a.B*b.A);
	return c;
}
void insert(line &o,ld x1,ld y1,ld x2,ld y2)
{
	o.an=atan2(y1-y2,x1-x2);
	if(o.an<0)o.an+=2*pi;
	o.make(y2-y1,x1-x2,x1*y2-x2*y1,o.an);
}
void print(ld x,int y)
{
	out <<setprecision(y) <<std::fixed <<x <<endl;
}
void read()
{
	int i;
	ld x1,x2,y1,y2;
	for(i=1;i<=n;i++)
	{
		in>>x1>>y1>>x2>>y2;
		insert(H[i],x1,y1,x2,y2);
	}
	insert(H[++n],0,10000,0,0);
	insert(H[++n],0,0,10000,0);
	insert(H[++n],10000,0,10000,10000);
	insert(H[++n],10000,10000,0,10000);
}
void init()
{
	sort(H+1,H+n+1);
	
	int tot=0;
	int i;
	//print(eps,17);
	for(i=1;i<=n;i++)
	{
		if(!tot||fabs(H[tot].an-H[i].an)>eps)H[++tot]=H[i];
		else if(H[i].C<H[tot].C)H[tot]=H[i];
	}
	n=tot;
	Q.clear();
	//for(i=1;i<=n;i++)H[i].print();
	for(i=1;i<=n;i++)
	{
		while(Q.size()>=2&&!inside(cross(Q.back(),Q[Q.size()-2]),H[i]))Q.pop_back();
		while(Q.size()>=2&&!inside(cross(Q[0],Q[1]),H[i]))Q.pop_front();
		Q.push_back(H[i]);
	}
	while(Q.size()>=2&&!inside(cross(Q.back(),Q[Q.size()-2]),Q[0]))Q.pop_back();
}
void work()
{
	int i;
	ld ans=0;
	init();
	//for(i=0;i<Q.size();i++)Q[i].print();
	if(Q.size()<=2)
	{
		print(0.0,1);
		return ;
	}
	for(i=1;i<Q.size();i++)
	{
		P[i+1]=cross(Q[i-1],Q[i]);
	}
	P[1]=cross(Q[0],Q.back());
	n=Q.size();
	P[n+1]=P[1];
	//for(i=1;i<=n;i++)P[i].print();
	for(i=1;i<=n;i++)ans+=P[i]^P[i+1];
	ans/=2;
	print(ans,1);
}
int main()
{
	int T;
	//print(pi,10);
	while(!in.eof()&&in>>n)
	{
	    read();
	    work();
	}
	return 0;
}