记录编号 117752 评测结果 AAAAAAAAAA
题目名称 Uyuw的音乐会 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 1.972 s
提交时间 2014-08-31 14:03:32 内存使用 1.23 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#include<iomanip>
using namespace std;
const double eps=1e-10,pi=acos(-1.0);
const int SIZEN=20010;
class POINT{
public:
	double x,y;
};
double cross(POINT a,POINT b){
	return a.x*b.y-b.x*a.y;
}
class HPL{//半平面
public:
	double a,b,c;//ax+by<=c
	double pa;//极角
	void print(void){cout<<"极角:"<<pa<<" 不等式:";cout<<a<<"x + "<<b<<"y <= "<<c<<endl;}
};
void print(HPL h){h.print();}
void print(POINT p){cout<<"("<<p.x<<" "<<p.y<<")";}
bool cmp(HPL s,HPL t){
	return s.pa<t.pa;
}
bool inside(POINT p,HPL h){
	return p.x*h.a+p.y*h.b<h.c-eps;
}
POINT inter(HPL s,HPL t){//交点,要求s,t的极角不同
	POINT ans;
	ans.x=(s.c*t.b-t.c*s.b)/(s.a*t.b-t.a*s.b);
	ans.y=(s.c*t.a-t.c*s.a)/(s.b*t.a-t.b*s.a);
	return ans;
}
void HPL_Intersection(HPL h[],int N,deque<HPL> &Q){
	//要求此时已经计算出了所有半平面的极角
	//Q中将返回约束了核的那些半平面
	//半平面是h[1]~h[N]
	//将所有半平面,极角相同者取约束最紧的
	sort(h+1,h+1+N,cmp);
	int tot=0;
	for(int i=1;i<=N;i++){
		if(tot==0||fabs(h[tot].pa-h[i].pa)>eps) h[++tot]=h[i];
		else if(h[i].c<h[tot].c) h[tot]=h[i];
	}
	N=tot;
	Q.clear();
	for(int i=1;i<=N;i++){
		//从队列两端删除
		//顺序不能错!
		while(Q.size()>=2&&!inside(inter(Q.back(),Q[Q.size()-2]),h[i])) Q.pop_back();
		while(Q.size()>=2&&!inside(inter(Q[0],Q[1]),h[i])) Q.pop_front();
		Q.push_back(h[i]);
	}
	while(Q.size()>=2&&!inside(inter(Q.back(),Q[Q.size()-2]),Q[0])) Q.pop_back();
}
int N;
HPL H[SIZEN];
deque<HPL> Q;
POINT P[SIZEN];
void work(void){
	HPL_Intersection(H,N,Q);
	if(Q.size()<=2){
		printf("0.0\n");
		return;
	}
	for(int i=1;i<Q.size();i++) P[i+1]=inter(Q[i-1],Q[i]);
	P[1]=inter(Q[0],Q.back());
	double ans=0;
	int n=Q.size();
	for(int i=1;i<n;i++) ans+=cross(P[i],P[i+1]);
	ans+=cross(P[n],P[1]);
	ans/=2.0;
	printf("%.1lf\n",ans);
}
void assign(HPL &h,double x1,double y1,double x2,double y2){
	h.pa=atan2(y1-y2,x1-x2);
	if(h.pa<0) h.pa+=2*pi;
	h.a=y2-y1,h.b=x1-x2,h.c=x1*y2-x2*y1;
}
bool init(void){
	if(scanf("%d",&N)==EOF) return false;
	double x1,y1,x2,y2;
	for(int i=1;i<=N;i++){
		scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
		assign(H[i],x1,y1,x2,y2);
	}
	assign(H[++N],0,10000,0,0);
	assign(H[++N],0,0,10000,0);
	assign(H[++N],10000,0,10000,10000);
	assign(H[++N],10000,10000,0,10000);
	return true;
}
int main(){
	freopen("concert.in","r",stdin);
	freopen("concert.out","w",stdout);
	while(init()) work();
	return 0;
}