bzoj2618[Cqoi2006]凸多边形

Posted Achen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 long long LL;
 11 typedef double db;
 12 const db eps=1e-10;
 13 const int N=50007;
 14 using namespace std;
 15 int n,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(db x=0,db y=0):x(x),y(y){} 
 27 }p[N]; 
 28 typedef  pt vc; 
 29 
 30 vc operator + (vc A,vc B) { return vc(A.x+B.x,A.y+B.y);}
 31 vc operator - (vc A,vc B) { return vc(A.x-B.x,A.y-B.y);}
 32 vc operator * (vc A,db p) { return vc(A.x*p,A.y*p);}
 33 vc operator / (vc A,db p) { return vc(A.x/p,A.y/p);}
 34 bool operator <(const vc&A,const vc&B) { return A.x<B.x||(A.x==B.x&&A.y<B.y);}
 35 int dcmp(double x) { if(fabs(x)<eps) return 0; else return x<0?-1:1;}
 36 bool operator == (const vc&A,const vc&B) { return dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)==0; }
 37 
 38 db dot(vc A,vc B) { return A.x*B.x+A.y*B.y; }
 39 db length(vc A) { return dot(A,A); }
 40 db cross(vc A,vc B) { return A.x*B.y-A.y*B.x; }
 41 
 42 struct ln {
 43     pt a,b; db slop;
 44     friend bool operator <(const ln&A,const ln&B) {
 45         return A.slop==B.slop?cross(A.b-A.a,B.b-A.a)>0:A.slop<B.slop;
 46     }
 47 }L[N],a[N],que[N];
 48 
 49 db polygonArea(int n) {
 50     if(n<3) return 0;
 51     db res=0;
 52     for(int i=1;i<n-1;i++)
 53         res+=cross(p[i]-p[0],p[i+1]-p[0]);
 54     return fabs(res)/2;
 55 }
 56 
 57 pt inter(ln A,ln B) {
 58     pt res;
 59     db s1=cross(B.b-A.a,A.b-A.a);
 60     db s2=cross(A.b-A.a,B.a-A.a);
 61     db k=s1/(s1+s2);
 62     res.x=B.b.x+(B.a.x-B.b.x)*k;
 63     res.y=B.b.y+(B.a.y-B.b.y)*k;
 64     return res;
 65 }
 66 
 67 bool ck(ln A,ln B,ln P) {
 68     pt pp=inter(A,B);
 69     return cross(P.b-P.a,pp-P.a)<0;
 70 }
 71 
 72 db solve() {
 73     sort(L+1,L+cnt+1);
 74     for(int i=1;i<=cnt;i++) {
 75         if(L[i].slop!=L[i-1].slop) tot++;
 76         a[tot]=L[i];
 77     }
 78     int ql=1,qr=0;
 79     L[++qr]=a[1]; L[++qr]=a[2];
 80     for(int i=3;i<=tot;i++) {
 81         while(qr>ql&&ck(L[qr-1],L[qr],a[i])) qr--;
 82         while(qr>ql&&ck(L[ql+1],L[ql],a[i])) ql++;
 83         L[++qr]=a[i];
 84     }
 85     while(qr>ql&&ck(L[qr-1],L[qr],L[ql])) qr--;
 86     while(qr>ql&&ck(L[ql+1],L[ql],L[qr])) ql++;
 87     L[qr+1]=L[ql];
 88     cnt=0;
 89     for(int i=ql;i<=qr;i++) 
 90         p[cnt++]=inter(L[i],L[i+1]);
 91     return polygonArea(cnt); 
 92 }
 93 
 94 int main() {
 95     read(n);
 96     for(int i=1;i<=n;i++) {
 97         int k;
 98         read(k);
 99         for(int j=1;j<=k;j++) { read(p[j].x);read(p[j].y); }
100         for(int j=1;j<k;j++) {
101             L[++cnt].a=p[j]; L[cnt].b=p[j+1];
102         }
103         L[++cnt].a=p[k]; L[cnt].b=p[1];
104     }
105     for(int i=1;i<=cnt;i++) 
106         L[i].slop=atan2(L[i].b.y-L[i].a.y,L[i].b.x-L[i].a.x);
107     printf("%.3lf\n",solve());
108     return 0;
109 }
110 /*
111 2
112 6
113 -2 0
114 -1 -2
115 1 -2
116 2 0
117 1 2
118 -1 2
119 4
120 0 -3
121 1 -1
122 2 2
123 -1 0
124 */
View Code

 

以上是关于bzoj2618[Cqoi2006]凸多边形的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2618 2618: [Cqoi2006]凸多边形 (半平面交)

半平面交BZOJ2618[Cqoi2006]凸多边形

BZOJ2618[Cqoi2006]凸多边形 半平面交

bzoj2618 [Cqoi2006]凸多边形

bzoj2618[Cqoi2006]凸多边形 半平面交

CQOI2006凸多边形