记录编号 |
117752 |
评测结果 |
AAAAAAAAAA |
题目名称 |
Uyuw的音乐会 |
最终得分 |
100 |
用户昵称 |
cstdio |
是否通过 |
通过 |
代码语言 |
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;
- }