bzoj2618[Cqoi2006]凸多边形

传送门 

半平面交。

抄一份代码de一下午bug。

抄板选手的日常。

  1 //Achen
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<vector>
  7 #include<cstdio>
  8 #include<queue>
  9 #include<cmath>
 10 typedef double db;
 11 typedef long long LL;
 12 using namespace std;
 13 const int N=5e4+7;
 14 const db eps=1e-10;
 15 int n,k,cnt,tot;
 16 
 17 template<typename T>void read(T &x)  {
 18     char ch=getchar(); x=0; T f=1;
 19     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
 20     if(ch=='-') f=-1,ch=getchar();
 21     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
 22 }
 23 
 24 struct pt {
 25     db x,y;
 26     pt(){}
 27     pt(db x,db y):x(x),y(y){}
 28 }p[N];
 29 
 30 pt operator + (pt A,pt B) { return pt(A.x+B.x,A.y+B.y); }
 31 pt operator - (pt A,pt B) { return pt(A.x-B.x,A.y-B.y); }
 32 pt operator * (pt A,db p) { return pt(A.x*p,A.y*p); }
 33 pt operator / (pt A,db p) { return pt(A.x/p,A.y/p); }
 34 db dot(pt A,pt B) { return A.x*B.x+A.y*B.y; }
 35 db cross(pt A,pt B) { return A.x*B.y-A.y*B.x; }
 36 db length(pt A) { return sqrt(dot(A,A)); }
 37 db dcmp(db x) { return (fabs(x)<eps)?0:(x<0?-1:1); }
 38 
 39 struct Line {
 40     pt a,b;
 41     db slop;
 42     friend bool operator <(const Line&A,const Line&B) {
 43         return (A.slop<B.slop)||(A.slop==B.slop&&cross(A.b-A.a,B.b-A.a)<0);
 44     } 
 45 }L[N],a[N];
 46 
 47 db get_Area(int n) {
 48     if(n<3) return 0;
 49     db res=0; p[n+1]=p[1];
 50     for(int i=1;i<=n;i++) res+=cross(p[i],p[i+1]);
 51     return fabs(res)/2.0;
 52 }
 53 
 54 pt inter(Line A,Line B) {
 55     pt rs;
 56     db k1=cross(B.b-A.a,A.b-A.a);
 57     db k2=cross(A.b-A.a,B.a-A.a);
 58     db t=k1/(k1+k2);
 59     rs.x=B.b.x+(B.a.x-B.b.x)*t;
 60     rs.y=B.b.y+(B.a.y-B.b.y)*t;
 61     return rs;
 62 }
 63 
 64 int ck(Line A,Line B,Line P) {
 65     pt t=inter(A,B);
 66     return cross(t-P.a,P.b-P.a)>0;
 67 }
 68 
 69 db solve(int n) {
 70     sort(L+1,L+n+1);
 71     for(int i=1;i<=n;i++) 
 72         if(i==1||L[i].slop!=L[i-1].slop) a[++tot]=L[i];
 73     cnt=0; int ql=1,qr=0;
 74     L[++qr]=a[1]; L[++qr]=a[2];    
 75     for(int i=3;i<=tot;i++) {
 76         while(qr>ql&&ck(L[qr-1],L[qr],a[i])) qr--;
 77         while(qr>ql&&ck(L[ql+1],L[ql],a[i])) ql++;
 78         L[++qr]=a[i];
 79     }
 80     while(qr>ql&&ck(L[qr-1],L[qr],L[ql])) qr--;
 81     while(qr>ql&&ck(L[ql+1],L[ql],L[qr])) ql++;
 82     L[qr+1]=L[ql];
 83     for(int i=ql;i<=qr;i++) 
 84         p[++cnt]=inter(L[i],L[i+1]);
 85     return get_Area(cnt);    
 86 }
 87 
 88 int main() {
 89 #ifdef DEBUG
 90     freopen(".in","r",stdin);
 91     freopen(".out","w",stdout);
 92 #endif
 93     read(n);
 94     while(n--) {
 95         read(k);
 96         for(int i=1;i<=k;i++) {
 97             read(p[i].x); read(p[i].y);
 98         }
 99         p[k+1]=p[1];
100         for(int i=1;i<=k;i++) {
101             L[++cnt].a=p[i]; L[cnt].b=p[i+1];
102             L[cnt].slop=atan2(L[cnt].b.y-L[cnt].a.y,L[cnt].b.x-L[cnt].a.x); 
103         }    
104     }
105     printf("%.3lf\n",solve(cnt));
106     return 0;
107 }
108 /*
109 2
110 6
111 -2 0
112 -1 -2
113 1 -2
114 2 0
115 1 2
116 -1 2
117 4
118 0 -3
119 1 -1
120 2 2
121 -1 0
122 */
View Code

 

posted @ 2018-02-23 15:58  啊宸  阅读(225)  评论(0编辑  收藏  举报