zoukankan      html  css  js  c++  java
  • [模板] 半平面交

    做法

    考虑用射线(一个点和一个向量)表示它左侧的半平面

    那么我们可以先按与x轴正半轴夹角(可用atan2(y,x)实现)排序,然后再用双端队列维护当前在交中的射线即可

    之所以要用双端队列,是因为新插入一个半平面时队首和队尾都有可能被弹出,而且要注意的是,要先弹队尾再弹队首

    在最后,还要再用队首的弹一些队尾的

    例题

    luogu4196 凸多边形
     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define CLR(a,x) memset(a,x,sizeof(a))
     4 #define MP make_pair
     5 #define fi first
     6 #define se second
     7 using namespace std;
     8 typedef long long ll;
     9 typedef unsigned long long ull;
    10 typedef unsigned int ui;
    11 typedef long double ld;
    12 const int maxl=2333,maxn=12,maxm=55;
    13 const ld eps=1e-9;
    14 
    15 inline char gc(){
    16     return getchar();
    17     static const int maxs=1<<16;static char buf[maxs],*p1=buf,*p2=buf;
    18     return p1==p2&&(p2=(p1=buf)+fread(buf,1,maxs,stdin),p1==p2)?EOF:*p1++;
    19 }
    20 inline ll rd(){
    21     ll x=0;char c=gc();bool neg=0;
    22     while(c<'0'||c>'9'){if(c=='-') neg=1;c=gc();}
    23     while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=gc();
    24     return neg?(~x+1):x;
    25 }
    26 
    27 struct Node{
    28     ld x,y;
    29     Node(ld _x=0,ld _y=0){x=_x,y=_y;}
    30 }p[maxn][maxm],it[maxl];
    31 struct Line{
    32     Node x,y;
    33     Line(Node _x=0,Node _y=0){x=_x,y=_y;}
    34 }l[maxl];
    35 int N,M[maxn],cnt;
    36 int hd,tl,q[maxl];
    37 
    38 inline ld operator ^(const Node a,const Node b){return a.x*b.y-a.y*b.x;}
    39 inline Node operator +(const Node a,const Node b){return Node(a.x+b.x,a.y+b.y);}
    40 inline Node operator -(const Node a,const Node b){return Node(a.x-b.x,a.y-b.y);}
    41 inline Node operator *(const Node a,const ld b){return Node(a.x*b,a.y*b);}
    42 inline ld myabs(const ld x){return x>0?x:-x;}
    43 inline Node inter(const Line a,const Line b){
    44     ld k1=(a.y-a.x)^(b.y-a.x),k2=(b.x-a.x)^(a.y-a.x);
    45     return b.x+(b.y-b.x)*(k2/(k1+k2));
    46 }
    47 inline bool onright(const Line a,const Node b){return ((b-a.x)^(a.y-a.x))>=-eps;}
    48 inline ld slope(Line a){return atan2((a.y-a.x).y,(a.y-a.x).x);}
    49 
    50 inline bool cmp(Line a,Line b){
    51     ld x=slope(a),y=slope(b);
    52     return (myabs(x-y)<eps)?(!onright(b,a.x)):(x<y);
    53 }
    54 
    55 inline ld solve(){
    56     sort(l+1,l+cnt+1,cmp);
    57     hd=1,tl=0;
    58     for(int i=1;i<=cnt;i++){
    59         // printf("~%Lf %Lf
    ",(l[i].y-l[i].x).x,(l[i].y-l[i].x).y);
    60         if(i>1&&myabs(slope(l[i])-slope(l[i-1]))<eps) continue;
    61         while(hd<tl&&onright(l[i],inter(l[q[tl]],l[q[tl-1]]))) tl--;
    62         while(hd<tl&&onright(l[i],inter(l[q[hd]],l[q[hd+1]]))) hd++;
    63         q[++tl]=i;
    64     }
    65     while(hd<tl&&onright(l[q[hd]],inter(l[q[tl]],l[q[tl-1]]))) tl--;
    66     // while(hd<tl&&onright(l[q[tl]],inter(l[q[hd]],l[q[hd+1]]))) hd++;
    67     // for(int i=hd;i<=tl;i++) printf("~%Lf %Lf %Lf %Lf
    ",l[q[i]].x.x,l[q[i]].x.y,l[q[i]].y.x,l[q[i]].y.y);
    68     if(hd+2>tl) return 0;
    69     ld re=0;
    70     q[tl+1]=q[hd];int n=0;
    71     for(int i=hd;i<=tl;i++) it[++n]=inter(l[q[i]],l[q[i+1]]);
    72     for(int i=2;i<n;i++) re+=myabs((it[i]-it[1])^(it[i+1]-it[1]));
    73     return re/2;
    74 }
    75 
    76 int main(){
    77     //freopen("","r",stdin);
    78     N=rd();
    79     for(int i=1;i<=N;i++){
    80         M[i]=rd();
    81         for(int j=0;j<M[i];j++)
    82             p[i][j].x=rd(),p[i][j].y=rd();
    83         for(int j=0;j<M[i];j++){
    84             l[++cnt]=Line(p[i][j],p[i][(j+1)%M[i]]);
    85         }
    86     }
    87     printf("%.3Lf
    ",solve());
    88     return 0;
    89 }
  • 相关阅读:
    MVC3分页传2参
    C# 二进制存储图片到mssql(一)
    著名黑客组织[转]
    浅看C# md5加密
    google搜索技巧
    字符串编码转换 GBK utf8
    objectivec 中随机数的用法 (3种:arc4random() 、random()、CCRANDOM_0_1() )
    NSPredicate的用法
    Java关键字final、static使用总结()
    CGAffineTransform相关函数
  • 原文地址:https://www.cnblogs.com/Ressed/p/11055401.html
Copyright © 2011-2022 走看看