zoukankan      html  css  js  c++  java
  • 【BZOJ 1185】 凸包+旋转卡壳

    Description

     

    【分析】

      打计算几何真的可以哭出来。。。

      跟那个求线段最远点差不多,这题弄三个东西转一转,一个表示左端最远点,一个表示右端最远点,一个表示上面最远点。

      左右两边的最远点用点积判断,上方最远点用差积判断。

      【向量是最好的解决平面几何问题的,不要画图!!!哭!!!

      输出那里,用的是向量加减法,乘一个比例系数,然后还用到了垂直单位向量。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<cmath>
      7 using namespace std;
      8 #define Maxn 50010
      9 
     10 const double eps=0.0000001;
     11 const double INF=999999999;
     12 
     13 struct P
     14 {
     15     double x,y;
     16 }a[Maxn],t[Maxn];
     17 int len,n;
     18 
     19 P operator - (P x,P y) 
     20 {
     21     P tt;
     22     tt.x=x.x-y.x;
     23     tt.y=x.y-y.y;
     24     return tt;
     25 }
     26 
     27 P operator * (P x,double y)
     28 {
     29     P tt;
     30     tt.x=x.x*y;
     31     tt.y=x.y*y;
     32     return tt;
     33 }
     34 
     35 P operator + (P x,P y)
     36 {
     37     P tt;
     38     tt.x=x.x+y.x;
     39     tt.y=x.y+y.y;
     40     return tt;
     41 }
     42 
     43 double myabs(double x) {return x>0?x:-x;}
     44 
     45 int fbs(double x)
     46 {
     47     if(myabs(x)<=eps) return 0;
     48     return x<0?-1:1;
     49 }
     50 
     51 double Dot(P x,P y) {return x.x*y.x+x.y*y.y;}
     52 double Cross(P x,P y) {return x.x*y.y-x.y*y.x;}
     53 bool cmp(P x,P y) {return fbs(x.x-y.x)==0?(x.y<y.y):(x.x<y.x);}
     54 
     55 void chull()
     56 {
     57     sort(a+1,a+1+n,cmp);
     58     len=0;
     59     for(int i=1;i<=n;i++)
     60     {
     61         while(len>1&&Cross(t[len]-t[len-1],a[i]-t[len])<=0) len--;
     62         t[++len]=a[i];
     63     }
     64     int k=len;
     65     for(int i=n-1;i>=1;i--)
     66     {
     67         while(len>k&&Cross(t[len]-t[len-1],a[i]-t[len])<=0) len--;
     68         t[++len]=a[i];
     69     }len--;
     70     t[0]=t[len];
     71 }
     72 
     73 void output()
     74 {
     75     for(int i=0;i<len;i++)
     76     {
     77         printf("%lf %lf
    ",t[i].x,t[i].y);
     78     }printf("
    ");
     79 }
     80 
     81 double ans;
     82 P op[5];
     83 
     84 void RC()
     85 {
     86     double L,R,H,D;
     87     ans=INF;
     88     int l=1,r=1,h=1;
     89     for(int i=0;i<len;i++)
     90     {
     91         int j=(i+1)%len;
     92         // l=i;r=j;h=j;
     93         // printf("%lf %lf
    ",(t[h+1]-t[i]).x,(t[h+1]-t[i]).y);
     94         // printf("%lf %lf
    ",(t[h+1]-t[j]).x,(t[h+1]-t[j]).y);
     95         while(Cross(t[h]-t[i],t[h]-t[j])<=Cross(t[h+1]-t[i],t[h+1]-t[j])) h=(h+1)%len;
     96         while(Dot(t[i]-t[j],t[r]-t[j])>=Dot(t[i]-t[j],t[r+1]-t[j])) r=(r+1)%len;
     97         if(i==0) l=r;
     98         
     99         // printf("%lf %lf
    ",Dot(t[j]-t[i],t[l]-t[i]),Dot(t[j]-t[i],t[l+1]-t[i]));
    100         while(Dot(t[j]-t[i],t[l]-t[i])>=Dot(t[j]-t[i],t[l+1]-t[i])) l=(l+1)%len;
    101         
    102         D=sqrt(Dot(t[i]-t[j],t[i]-t[j]));
    103         H=Cross(t[h]-t[i],t[h]-t[j])/D;
    104         L=-Dot(t[j]-t[i],t[l]-t[i])/D;
    105         R=-Dot(t[i]-t[j],t[r]-t[j])/D;
    106         
    107         // printf("**%lf %lf %lf %lf
    ",D,H,L,R);
    108         
    109         double now=(R+L+D)*H;
    110         // printf("%lf %lf %d %d %d %lf
    ",t[i].x,t[i].y,l,r,h,now);
    111         if(now<ans)
    112         {
    113             ans=now;
    114             op[0]=t[i]-(t[j]-t[i])*(L/D);
    115             op[1]=t[j]-(t[i]-t[j])*(R/D);
    116             P tt;
    117             tt.x=(t[i]-t[j]).y;tt.y=-(t[i]-t[j]).x;
    118             op[2]=op[1]+tt*(H/D);
    119             op[3]=op[0]+tt*(H/D);
    120             // op[0]=t[i];op[1]=t[j];op[2]=t[r];op[3]=t[l];
    121         }
    122     }
    123 }
    124 
    125 int main()
    126 {
    127     scanf("%d",&n);
    128     for(int i=1;i<=n;i++)
    129     {
    130         scanf("%lf%lf",&a[i].x,&a[i].y);
    131     }
    132     chull();
    133     // output();
    134     RC();
    135     int fr=0;
    136     for(int i=1;i<4;i++) if(op[i].y<op[fr].y||fbs(op[fr].y-op[i].y)==0&&op[i].x<op[i].x) fr=i;
    137     printf("%.5lf
    ",ans);
    138     for(int i=0;i<4;i++)
    139     {
    140         if(fbs(op[i].x)==0) op[i].x=0;
    141         if(fbs(op[i].y)==0) op[i].y=0;
    142     }
    143     // for(int i=0;i<4;i++) op[i].x=myabs(op[i].x),op[i].y=myabs(op[i].y);
    144     for(int i=0;i<4;i++)
    145     {
    146         printf("%.5lf %.5lf
    ",op[(fr+i)%4].x,op[(fr+i)%4].y);
    147     }
    148     return 0;
    149 }
    View Code

    调试过程不删了,心酸。。

    2016-12-15 16:55:18

  • 相关阅读:
    FSLIB.NETWORK 简易使用指南
    在CentOS上安装owncloud企业私有云过程
    用于ViEmu的重置为试用状态的Python脚本
    Microsoft.Office.Interop.Excel 报错
    FineUIMvc表格数据库分页,使用CYQ.Data组件
    如何在已有项目中引入FineUIMvc
    按键精灵-常用脚本命令汇集
    微信分享代码
    [教程] 【原创】媒体扫描耗电的彻底解决办法(申精)
    Less学习笔记
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6183880.html
Copyright © 2011-2022 走看看