zoukankan      html  css  js  c++  java
  • 半平面交模板 HDU 1469

    题意就是要判断一个多边形是否存在核。

    我们可以把沿着顺时针方向走这个多边形,对于每个边向量,我们取其右边的半平面,判断交是否为空即可。

    对于半平面交算法,我只理解了O(n^2)的算法,大概就是用向量去切割多边形,对于O(nlogn)的算法,我从网上各种搜集以及参考了蓝书的实现,给出了一份能看的代码。

    O(n^2)

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cmath>
     5 using namespace std;
     6 #define maxn 1005
     7 const double eps=0.00000001;
     8 struct Point {double x,y;};
     9 struct Vector {double x,y;};
    10 int Case,n,tot1,tot2;
    11 Point a[maxn],b[maxn],tmp[maxn];
    12 
    13 Vector operator - (Point x,Point y) 
    14 {
    15     return (Vector){x.x-y.x,x.y-y.y};
    16 }
    17 
    18 bool operator == (Point x,Point y)
    19 {
    20     return fabs(x.x-y.x)<eps&&fabs(x.y-y.y)<eps;
    21 }
    22 
    23 double Cross(Vector a,Vector b)
    24 {
    25     return a.x*b.y-a.y*b.x;
    26 }
    27 
    28 double Dot(Vector a,Vector b)
    29 {
    30     return a.x*b.x+a.y*b.y;
    31 }
    32 
    33 void solve(void) 
    34 {
    35     a[0]=a[n];tot1=0;
    36     b[++tot1]=(Point){-1e9,-1e9};
    37     b[++tot1]=(Point){-1e9,1e9};
    38     b[++tot1]=(Point){1e9,1e9};
    39     b[++tot1]=(Point){1e9,-1e9};
    40     for (int i=1;i<=n;i++) 
    41     {
    42         Point A=a[i];
    43         Point B=a[(i+1)%n];
    44         tot2=0;
    45         for (int j=1;j<=tot1;j++) 
    46         {
    47             Point C=b[j];
    48             Point D=(j+1)%tot1?b[(j+1)%tot1]:b[tot1];
    49             if (Cross(B-A,C-A)<=0) tmp[++tot2]=C;
    50             if (fabs(Cross(B-A,C-D))>eps) 
    51             {
    52                 Vector v=A-C;
    53                 double lim=Cross(D-C,v)/Cross(B-A,D-C);
    54                 tot2++;
    55                 tmp[tot2].x=A.x+lim*(B-A).x;
    56                 tmp[tot2].y=A.y+lim*(B-A).y;
    57                 if (tmp[tot2]==C||tmp[tot2]==D) tot2--;
    58                 else if (Dot(tmp[tot2]-C,tmp[tot2]-D)>0) tot2--; 
    59             }
    60         }
    61         tot1=tot2;
    62         for (int i=1;i<=tot1;i++) b[i]=tmp[i];
    63     }
    64     Case++;
    65     printf("Floor #%d\n",Case);
    66     tot1?puts("Surveillance is possible."):puts("Surveillance is impossible.");
    67     puts("");
    68     //for (int i=1;i<=tot1;i++) printf("%.3f %.3f\n",b[i].x,b[i].y);
    69 }
    70 
    71 int main()
    72 {
    73     while (1) 
    74     {
    75         scanf("%d",&n);
    76         if (n==0) break;
    77         for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
    78         solve();
    79     }
    80     return 0;
    81 }

    O(nlogn)

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cmath>
     5 using namespace std;
     6 #define maxn 100005
     7 const double eps=0.00000001;
     8 struct Point {double x,y;};
     9 struct Vector {double x,y;};
    10 struct Line{Point p;Vector v;double ang;};
    11 Point a[maxn],b[maxn];
    12 Line c[maxn],dque[maxn];
    13 int n,Case;
    14 
    15 Vector operator - (Point x,Point y)
    16 {
    17     return (Vector){x.x-y.x,x.y-y.y};
    18 }
    19 
    20 double Cross(Vector a,Vector b)
    21 {
    22     return a.x*b.y-a.y*b.x;
    23 }
    24 
    25 inline bool cmp(Line x,Line y)
    26 {
    27     if (fabs(x.ang-y.ang)>eps) return x.ang<y.ang;
    28     return Cross(x.v,y.p-x.p)>0;
    29 }
    30 
    31 bool check(Line A,Line B,Line C) 
    32 {
    33     Vector v=A.p-B.p;
    34     double lim=Cross(B.v,v)/Cross(A.v,B.v);
    35     Point tmp;
    36     tmp.x=A.p.x+lim*A.v.x;
    37     tmp.y=A.p.y+lim*A.v.y;
    38     return Cross(C.v,tmp-C.p)>0;
    39 }
    40 
    41 int main()
    42 {
    43     while (1) 
    44     {
    45         scanf("%d",&n);
    46         if (n==0) break;
    47         for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
    48         a[0]=a[n];
    49         for (int i=1;i<=n;i++) 
    50         {
    51             c[i].p=a[i];
    52             c[i].v=a[(i+1)%n]-a[i];
    53             c[i].ang=atan2(c[i].v.y,c[i].v.x);
    54             //printf("%.3f\n",c[i].ang);
    55         }
    56         sort(c+1,c+n+1,cmp);
    57         int nn=1;
    58         for (int i=2;i<=n;i++)  
    59             if (fabs(c[nn].ang-c[i].ang)>eps) c[++nn]=c[i];
    60         n=nn;
    61         //printf("%d\n",n);
    62         dque[1]=c[1];
    63         dque[2]=c[2];
    64         int l=1,r=2;
    65         for (int i=3;i<=n;i++) 
    66         {
    67             while (l<r&&check(dque[r],dque[r-1],c[i])) r--;
    68             while (l<r&&check(dque[l],dque[l+1],c[i])) l++;
    69             dque[++r]=c[i];
    70         }
    71         while (l<r&&check(dque[r],dque[r-1],dque[l])) r--;
    72         while (l<r&&check(dque[l],dque[l+1],dque[r])) l++;
    73         printf("Floor #%d\n",++Case);
    74         r-l>1?puts("Surveillance is possible."):puts("Surveillance is impossible.");
    75         puts("");
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    随笔
    梨花落(短篇小说)
    javascript中的apply,call,bind详解
    js中this的指向问题
    你若安好,便是晴天
    gulp
    图标
    normalize.css
    git bash和toritoise客户端结合使用
    云计算基础知识
  • 原文地址:https://www.cnblogs.com/lvyouyw/p/6860360.html
Copyright © 2011-2022 走看看