zoukankan      html  css  js  c++  java
  • BZOJ 1185: [HNOI2007]最小矩形覆盖-旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标-备忘板子

    来源:旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标

     

     

    BZOJ又崩了,直接贴一下人家的代码。

     

    代码:

      1 #include"stdio.h"
      2 #include"string.h"
      3 #include"math.h"
      4 #define M 50006
      5 #define eps 1e-10
      6 #include"stdlib.h"
      7 #define inf 999999999
      8 typedef struct node
      9 {
     10     double x,y,dis,cos;
     11 }P;
     12 P p[M],q[M],pp[M];
     13 double min(double a,double b)
     14 {
     15     return a<b?a:b;
     16 }
     17 int cmp(const void *a,const void *b)
     18 {
     19     if(fabs((*(struct node*)a).cos-(*(struct node*)b).cos)<eps)
     20         return (*(struct node*)a).dis>(*(struct node*)b).dis?1:-1;
     21     else
     22         return (*(struct node*)b).cos>(*(struct node*)a).cos?1:-1;
     23  
     24 }
     25 double pow(double x)
     26 {
     27     return x*x;
     28 }
     29 double Len(node p0,node p1)
     30 {
     31     return pow(p1.x-p0.x)+pow(p1.y-p0.y);
     32 }
     33 double COS(node p0,node p1)
     34 {
     35     double x1=p1.x-p0.x;
     36     double y1=p1.y-p0.y;
     37     double x2=1;
     38     double y2=0;
     39     return (x1*x2+y1*y2)/sqrt((x1*x1+y1*y1)*(x2*x2+y2*y2));
     40 }
     41 double cross(node p0,node p1,node p2)
     42 {
     43     double x1=p1.x-p0.x;
     44     double y1=p1.y-p0.y;
     45     double x2=p2.x-p0.x;
     46     double y2=p2.y-p0.y;
     47     return x1*y2-x2*y1;
     48 }
     49 double dot(node p0,node p1,node p2)
     50 {
     51     double x1=p1.x-p0.x;
     52     double y1=p1.y-p0.y;
     53     double x2=p2.x-p1.x;
     54     double y2=p2.y-p1.y;
     55     return x1*x2+y1*y2;
     56 }
     57 node miss(node q1,double a,double b,node q2)//求两直线交点坐标
     58 {
     59     node ret;
     60     double c1=a*q1.y-b*q1.x;
     61     double c2=-a*q2.x-b*q2.y;
     62     ret.x=-(b*c1+a*c2)/(a*a+b*b);
     63     ret.y=(a*c1-b*c2)/(a*a+b*b);
     64     return ret;
     65 }
     66 int main()
     67 {
     68     int n,i,j;
     69     while(scanf("%d",&n)!=-1)
     70     {
     71         node start;
     72         int tep;
     73         start.x=start.y=inf;
     74         for(i=0;i<n;i++)
     75         {
     76             scanf("%lf%lf",&p[i].x,&p[i].y);
     77             if(start.y>p[i].y)
     78             {
     79                 start=p[i];
     80                 tep=i;
     81             }
     82             else if(fabs(start.y-p[i].y)<eps)
     83             {
     84                 if(start.x>p[i].x)
     85                 {
     86                     start=p[i];
     87                     tep=i;
     88                 }
     89             }
     90         }
     91         p[tep].dis=0;
     92         p[tep].cos=1.0;
     93         for(i=0;i<n;i++)
     94         {
     95             if(i!=tep)
     96             {
     97                 if(fabs(p[i].x-start.x)<eps&&fabs(p[i].y-start.y)<eps)
     98                 {
     99                     p[i].dis=0;
    100                     p[i].cos=1.0;
    101                 }
    102                 else
    103                 {
    104                     p[i].dis=Len(start,p[i]);
    105                     p[i].cos=COS(start,p[i]);
    106                 }
    107             }
    108         }
    109         qsort(p,n,sizeof(p[0]),cmp);
    110         int tt=0;
    111         for(i=0;i<n;i++)
    112         {
    113             if(fabs(p[i].cos-p[(i+1)%n].cos)>eps||fabs(p[i].dis-p[(i+1)%n].dis)>eps)
    114                 pp[tt++]=p[i];
    115         }
    116         if(tt==0)
    117         {
    118             printf("%.5lf
    ",0.0);
    119             for(i=0;i<4;i++)
    120                 printf("%.5lf %.5lf
    ",p[0].x,p[0].y);
    121             continue;
    122         }
    123         int flag=0;
    124         for(i=1;i<tt-1;i++)
    125         {
    126             if(fabs(p[i].cos-p[i+1].cos)>eps)
    127                 flag++;
    128         }
    129         if(!flag)
    130         {
    131             printf("%.5lf
    ",0.0);
    132             printf("%.5lf %.5lf
    ",pp[0].x,pp[0].y);
    133             printf("%.5lf %.5lf
    ",pp[tt-1].x,pp[tt-1].y);
    134             printf("%.5lf %.5lf
    ",pp[tt-1].x,pp[tt-1].y);
    135             printf("%.5lf %.5lf
    ",pp[0].x,pp[0].y);
    136             continue;
    137         }
    138         q[0]=pp[tt-1];//注意tt;
    139         q[1]=pp[0];
    140         q[2]=pp[1];
    141         int cnt=2;
    142         for(i=2;i<tt;i++)
    143         {
    144             while(cross(q[cnt-1],q[cnt],pp[i])<0)
    145             {
    146                 cnt--;
    147             }
    148             q[++cnt]=pp[i];
    149         }
    150         int k1,k2;
    151         k1=1;
    152         j=1;
    153         double S=inf;
    154         double a[5],b[5];
    155         int indx[5];
    156         for(i=0;i<cnt;i++)
    157         {
    158             double w=sqrt(Len(q[i],q[(i+1)%cnt]));
    159             while(cross(q[i],q[(i+1)%cnt],q[(j+1)%cnt])>cross(q[i],q[(i+1)%cnt],q[j%cnt]))
    160             {
    161                 j++;
    162             }
    163             double high=cross(q[i],q[(i+1)%cnt],q[j%cnt])/w;
    164             while(dot(q[i],q[(i+1)%cnt],q[(k1+1)%cnt])>dot(q[i],q[(i+1)%cnt],q[(k1)%cnt]))
    165             {
    166                 k1++;
    167             }
    168             if(i==0)
    169                 k2=k1;
    170             while(dot(q[i],q[(i+1)%cnt],q[(k2+1)%cnt])<=dot(q[i],q[(i+1)%cnt],q[(k2)%cnt]))
    171             {
    172                 k2++;
    173             }
    174             double wide=(dot(q[i],q[(i+1)%cnt],q[(k1)%cnt])-dot(q[i],q[(i+1)%cnt],q[(k2)%cnt]))/w;
    175             if(S>high*wide)
    176             {
    177                 S=high*wide;//更新四个切点坐标以及旋转的直线的方向向量
    178                 indx[0]=i;
    179                 indx[1]=k1%cnt;
    180                 indx[2]=j%cnt;
    181                 indx[3]=k2%cnt;
    182                 a[0]=q[(i+1)%cnt].x-q[i].x;
    183                 b[0]=q[(i+1)%cnt].y-q[i].y;
    184                 a[1]=b[0];
    185                 b[1]=-a[0];
    186                 a[2]=a[0];
    187                 b[2]=b[0];
    188                 a[3]=b[0];
    189                 b[3]=-a[0];
    190             }
    191         }
    192         printf("%.5lf
    ",S);
    193         node ret[5];
    194         start.x=start.y=inf;
    195  
    196         for(i=0;i<4;i++)//先找出左下角的点的坐标然后按照极角排序
    197         {
    198             ret[i]=miss(q[indx[i]],a[i],b[i],q[indx[(i+1)%4]]);
    199             //printf("%.5lf %.5lf
    ",ret[i].x,ret[i].y);
    200             if(start.y>ret[i].y)
    201             {
    202                 start=ret[i];
    203                 tep=i;
    204             }
    205             else if(fabs(start.y-ret[i].y)<eps)
    206             {
    207                 if(start.x>ret[i].x)
    208                 {
    209                      start=ret[i];
    210                 tep=i;
    211                 }
    212  
    213             }
    214         }
    215         ret[tep].dis=0;
    216         ret[tep].cos=1.5;
    217         for(i=0;i<4;i++)
    218         {
    219             if(i!=tep)
    220             {
    221                 ret[i].dis=Len(start,ret[i]);
    222                 ret[i].cos=COS(start,ret[i]);
    223             }
    224         }
    225         qsort(ret,4,sizeof(ret[0]),cmp);
    226         for(i=0;i<4;i++)
    227             printf("%.5lf %.5lf
    ",ret[i].x,ret[i].y);
    228     }
    229     return 0;
    230 }

    整理。

  • 相关阅读:
    调试SQL Server的存储过程及用户定义函数
    寻找 vb.net 事务处理高级编程 的代码!!
    解析Java类和对象的初始化过程
    SQL 安装进程被挂起!
    教你成为一个受欢迎的人
    final class作用
    微软反跨站脚本库
    pdf解析
    ce'shi测试微博
    淘宝架构变化
  • 原文地址:https://www.cnblogs.com/ZERO-/p/9736445.html
Copyright © 2011-2022 走看看