BZOJ 1185 凸包+旋转卡壳

Posted konjak魔芋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\\n",t[i].x,t[i].y);
 78     }printf("\\n");
 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\\n",(t[h+1]-t[i]).x,(t[h+1]-t[i]).y);
 94         // printf("%lf %lf\\n",(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\\n",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\\n",D,H,L,R);
108         
109         double now=(R+L+D)*H;
110         // printf("%lf %lf %d %d %d %lf\\n",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\\n",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\\n",op[(fr+i)%4].x,op[(fr+i)%4].y);
147     }
148     return 0;
149 }
View Code

 

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

 

2016-12-15 16:55:18

 

以上是关于BZOJ 1185 凸包+旋转卡壳的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1185 [HNOI2007]最小矩形覆盖 旋转卡壳求凸包

●BZOJ 1185 [HNOI2007]最小矩形覆盖

BZOJ1185: [HNOI2007]最小矩形覆盖

bzoj 1185

模板计几最小矩形覆盖(bzoj1185)

bzoj 1185 最小矩形覆盖 —— 旋转卡壳