记录编号 117752 评测结果 AAAAAAAAAA
题目名称 Uyuw的音乐会 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 1.972 s
提交时间 2014-08-31 14:03:32 内存使用 1.23 MiB
显示代码纯文本
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstring>
  5. #include<vector>
  6. #include<queue>
  7. #include<algorithm>
  8. #include<iomanip>
  9. using namespace std;
  10. const double eps=1e-10,pi=acos(-1.0);
  11. const int SIZEN=20010;
  12. class POINT{
  13. public:
  14. double x,y;
  15. };
  16. double cross(POINT a,POINT b){
  17. return a.x*b.y-b.x*a.y;
  18. }
  19. class HPL{//半平面
  20. public:
  21. double a,b,c;//ax+by<=c
  22. double pa;//极角
  23. void print(void){cout<<"极角:"<<pa<<" 不等式:";cout<<a<<"x + "<<b<<"y <= "<<c<<endl;}
  24. };
  25. void print(HPL h){h.print();}
  26. void print(POINT p){cout<<"("<<p.x<<" "<<p.y<<")";}
  27. bool cmp(HPL s,HPL t){
  28. return s.pa<t.pa;
  29. }
  30. bool inside(POINT p,HPL h){
  31. return p.x*h.a+p.y*h.b<h.c-eps;
  32. }
  33. POINT inter(HPL s,HPL t){//交点,要求s,t的极角不同
  34. POINT ans;
  35. ans.x=(s.c*t.b-t.c*s.b)/(s.a*t.b-t.a*s.b);
  36. ans.y=(s.c*t.a-t.c*s.a)/(s.b*t.a-t.b*s.a);
  37. return ans;
  38. }
  39. void HPL_Intersection(HPL h[],int N,deque<HPL> &Q){
  40. //要求此时已经计算出了所有半平面的极角
  41. //Q中将返回约束了核的那些半平面
  42. //半平面是h[1]~h[N]
  43. //将所有半平面,极角相同者取约束最紧的
  44. sort(h+1,h+1+N,cmp);
  45. int tot=0;
  46. for(int i=1;i<=N;i++){
  47. if(tot==0||fabs(h[tot].pa-h[i].pa)>eps) h[++tot]=h[i];
  48. else if(h[i].c<h[tot].c) h[tot]=h[i];
  49. }
  50. N=tot;
  51. Q.clear();
  52. for(int i=1;i<=N;i++){
  53. //从队列两端删除
  54. //顺序不能错!
  55. while(Q.size()>=2&&!inside(inter(Q.back(),Q[Q.size()-2]),h[i])) Q.pop_back();
  56. while(Q.size()>=2&&!inside(inter(Q[0],Q[1]),h[i])) Q.pop_front();
  57. Q.push_back(h[i]);
  58. }
  59. while(Q.size()>=2&&!inside(inter(Q.back(),Q[Q.size()-2]),Q[0])) Q.pop_back();
  60. }
  61. int N;
  62. HPL H[SIZEN];
  63. deque<HPL> Q;
  64. POINT P[SIZEN];
  65. void work(void){
  66. HPL_Intersection(H,N,Q);
  67. if(Q.size()<=2){
  68. printf("0.0\n");
  69. return;
  70. }
  71. for(int i=1;i<Q.size();i++) P[i+1]=inter(Q[i-1],Q[i]);
  72. P[1]=inter(Q[0],Q.back());
  73. double ans=0;
  74. int n=Q.size();
  75. for(int i=1;i<n;i++) ans+=cross(P[i],P[i+1]);
  76. ans+=cross(P[n],P[1]);
  77. ans/=2.0;
  78. printf("%.1lf\n",ans);
  79. }
  80. void assign(HPL &h,double x1,double y1,double x2,double y2){
  81. h.pa=atan2(y1-y2,x1-x2);
  82. if(h.pa<0) h.pa+=2*pi;
  83. h.a=y2-y1,h.b=x1-x2,h.c=x1*y2-x2*y1;
  84. }
  85. bool init(void){
  86. if(scanf("%d",&N)==EOF) return false;
  87. double x1,y1,x2,y2;
  88. for(int i=1;i<=N;i++){
  89. scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
  90. assign(H[i],x1,y1,x2,y2);
  91. }
  92. assign(H[++N],0,10000,0,0);
  93. assign(H[++N],0,0,10000,0);
  94. assign(H[++N],10000,0,10000,10000);
  95. assign(H[++N],10000,10000,0,10000);
  96. return true;
  97. }
  98. int main(){
  99. freopen("concert.in","r",stdin);
  100. freopen("concert.out","w",stdout);
  101. while(init()) work();
  102. return 0;
  103. }