半平面交

存板子。

常数比较糟糕的一个板子 ,不过比较好敲

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 #define DB double
  4 const int maxn=100005;
  5 const DB pi=acos(-1);
  6 const DB eps=1e-6;
  7 int n,t; DB ans;
  8 struct N{
  9     DB x,y;
 10     N(DB a=0,DB b=0){x=a,y=b;}
 11 }c[maxn];
 12 struct L{
 13     N a,b; double f;
 14     L(N p=N(),N q=N()){
 15         a=p,b=q; f=atan2(b.y-a.y,b.x-a.x);
 16     }
 17 }a[maxn],b[maxn];
 18 N operator+(N a,N b){
 19     return N(a.x+b.x,a.y+b.y);
 20 }
 21 N operator-(N a,N b){
 22     return N(a.x-b.x,a.y-b.y);
 23 }
 24 DB operator*(N a,N b){
 25     return a.x*b.y-a.y*b.x;
 26 }
 27 DB dot(N a,N b){
 28     return a.x*b.x+a.y*b.y;
 29 }
 30 DB sqr(DB a){return a*a;}
 31 DB dis(N a,N b){
 32     return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
 33 }
 34 DB abs(N a){//
 35     return sqrt(a.x*a.x+a.y*a.y);
 36 }
 37 DB COS(N a,N b){//夹角[0,pi]的cos
 38     return dot(a,b)/abs(a)/abs(b);
 39 }
 40 DB SIN(N a,N b){//夹角sin
 41     return fabs(a*b)/abs(a)/abs(b);
 42 }
 43 L go(L s,DB m){//垂直左移m
 44     N c=N(-sin(s.f)*m,cos(s.f)*m);
 45     s.a=s.a+c; s.b=s.b+c; return s;
 46 }
 47 bool cmpL(L a,L b){
 48     return fabs(a.f-b.f)>eps?a.f<b.f:(a.b-a.a)*(b.b-a.a)<-eps;//lefter
 49 }
 50 bool ON(N p,L e){//点在线段上
 51     return fabs((e.a-p)*(e.b-p))<eps
 52     &&(e.a.x-p.x)*(e.b.x-p.x)<eps
 53     &&(e.a.y-p.y)*(e.b.y-p.y)<eps;
 54 }
 55 N inter(L a,L b){//如果f相同,回inf或nan
 56     DB k1,k2,t;
 57     k1=(b.b-a.a)*(a.b-a.a);
 58     k2=(a.b-a.a)*(b.a-a.a);
 59     t=k1/(k1+k2);
 60     return N(b.b.x+(b.a.x-b.b.x)*t,b.b.y+(b.a.y-b.b.y)*t);
 61 }
 62 bool jud(L a,L b,L t){
 63     N p=inter(a,b);
 64     return (t.b-t.a)*(p-t.a)<eps;
 65 }
 66 void hpi(){
 67     //anticlockwise
 68     //保留L.a->L.b的左半平面
 69     sort(a+1,a+n+1,cmpL);
 70     t=0;
 71     for (int i=1;i<=n;++i)
 72     if (i==1||fabs(a[i].f-a[t].f)>eps) a[++t]=a[i];
 73     n=t;
 74     for (int i=1;i<n;++i)
 75         if (a[i+1].f-a[i].f>=pi-eps){
 76             if (fabs(a[i+1].f-a[i].f-pi)<eps&&(a[i+1].b-a[i].a)*(a[i].b-a[i].a)>-eps){
 77                 printf("%.4lf\n",0.0); exit(0);
 78             }
 79             puts("-1"); exit(0);
 80         }
 81     if (a[1].f+2*pi-a[n].f>=pi-eps){
 82         if (fabs(a[1].f+2*pi-a[n].f-pi)<eps&&(a[1].b-a[n].a)*(a[n].b-a[n].a)>-eps){
 83             printf("%.4lf\n",0.0); exit(0);
 84         }
 85         puts("-1"); exit(0);
 86     }
 87     int l=1,r=0; t=0;
 88     for (int i=1;i<=n;++i)
 89     if (i==1||fabs(a[i].f-a[t].f)>eps) a[++t]=a[i];
 90     for (int i=1;i<=t;++i){
 91         while (l<r&&jud(b[r-1],b[r],a[i])) --r;
 92         while (l<r&&jud(b[l+1],b[l],a[i])) ++l;
 93         b[++r]=a[i];
 94     }
 95     while (l<r&&jud(b[r-1],b[r],b[l])) --r;
 96     while (l<r&&jud(b[l+1],b[l],b[r])) ++l;
 97     b[l-1]=b[r]; t=0;
 98     for (int i=l;i<=r;++i) c[++t]=inter(b[i-1],b[i]);
 99 }
100 int main(){
101     scanf("%d",&n);
102     for (int i=1;i<=n;++i){
103         DB A,B,C;       //Ax+By+C>=0
104         scanf("%lf%lf%lf",&A,&B,&C);
105         if (fabs(B)>eps){
106             if (B>0) a[i]=L(N(0,-C/B),N(1,(-A-C)/B));
107                 else a[i]=L(N(1,(-A-C)/B),N(0,-C/B));
108         }else{
109             if (A>0) a[i]=L(N(-C/A,1),N(-C/A,0));
110                 else a[i]=L(N(-C/A,0),N(-C/A,1));
111         }
112     }
113     hpi();
114     
115     ans=0;
116     for (int i=2;i<t;++i) ans+=(c[i+1]-c[1])*(c[i]-c[1]);
117     printf("%.4lf\n",-ans/2);
118     return 0;
119 }
恋い雪

 

posted @ 2017-12-19 10:06  cyz666  阅读(139)  评论(0编辑  收藏