[bzoj1185] [HNOI2007]最小矩形覆盖
旋(xuàn)转(zhuàn)卡(kǎ)壳(qiào)(大雾
抄了黄学长的标程当板子。。
求凸包后,两对平行线卡来卡去..上下一对的直接用单峰性质,左右一对的也是...就看到底边的投影长,这个用数量积除以底边长。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define ll long long 7 #define d double 8 using namespace std; 9 const int maxn=52333; 10 const d eps=1e-8; 11 struct P{ 12 d x,y; 13 }a[maxn],st[maxn],t[4];int tp; 14 int i,j,k,n,m; 15 int next[maxn]; 16 d ans=1e60; 17 18 P operator +(P a,P b){return (P){a.x+b.x,a.y+b.y};} 19 P operator -(P a,P b){return (P){a.x-b.x,a.y-b.y};} 20 P operator *(P a,d b){return (P){a.x*b,a.y*b};} 21 22 d operator ^(P a,P b){return a.x*b.y-b.x*a.y;} 23 d operator *(P a,P b){return a.x*b.x+a.y*b.y;} 24 25 26 27 bool operator <(P a,P b){return fabs(a.y-b.y)<eps?a.x<b.x:a.y<b.y;} 28 29 int ra;char rx; 30 inline int read(){ 31 rx=getchar(),ra=0; 32 while(rx<'0'||rx>'9')rx=getchar(); 33 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; 34 } 35 36 d dis(P a){return sqrt(a.x*a.x+a.y*a.y);} 37 inline void calc(){ 38 int l=1,r=1,p=1,i; 39 d L,R,D,H,tmp; 40 P now; 41 for(i=0;i<tp;i++)next[i]=(i+1==tp)?0:i+1; 42 for(i=0;i<tp;i++){ 43 now=st[i+1]-st[i], 44 D=dis(now); 45 while( (now^(st[p+1]-st[i])) > (now^(st[p]-st[i]))-eps )p=next[p]; 46 while( now*(st[r+1]-st[i]) > now*(st[r]-st[i])-eps )r=next[r]; 47 if(!i)l=r; 48 while( now*(st[l+1]-st[i]) < now*(st[l]-st[i])+eps )l=next[l]; 49 // printf(" %d %d %d\n",l,r,p); 50 L=now*(st[l]-st[i])/D,R=now*(st[r]-st[i])/D, 51 H=fabs( (now^(st[p]-st[i]))/D ); 52 // printf(" %.2lf %.2lf %.2lf %.2lf\n",L,R,H,D); 53 tmp=(R-L)*H; 54 if(tmp<ans) 55 ans=tmp, 56 t[0]=st[i]+(st[i+1]-st[i])*(R/D), 57 t[1]=t[0]+(st[r]-t[0])*(H/dis(t[0]-st[r])), 58 t[2]=t[1]-(t[0]-st[i])*((R-L)/dis(st[i]-t[0])), 59 t[3]=t[2]-(t[1]-t[0]); 60 } 61 } 62 bool cmp(P x,P y){ 63 d tmp=(x-a[1])^(y-a[1]); 64 if(fabs(tmp)<eps)return dis(a[1]-x)-dis(a[1]-y)<=-eps; 65 return tmp>=eps; 66 } 67 inline void graham(){ 68 register int i; 69 for(i=2;i<=n;i++)if(a[i]<a[1])swap(a[i],a[1]); 70 sort(a+2,a+n+1,cmp); 71 st[++tp]=a[1]; 72 for(i=2;i<=n;st[++tp]=a[i],i++) 73 while(tp>1&&((st[tp]-st[tp-1])^(a[i]-st[tp]))<eps)tp--;//,puts(".."); 74 st[0]=st[tp]; 75 } 76 77 78 int main(){ 79 n=read(); 80 for(i=1;i<=n;i++)scanf("%lf%lf",&a[i].x,&a[i].y); 81 graham(); 82 // for(i=1;i<=tp;i++)printf(" %.3lf %.3lf\n",st[i].x,st[i].y); 83 // for(i=1;i<=n;i++)printf(" %.3lf %.3lf\n",a[i].x,a[i].y); 84 calc(); 85 printf("%.5lf\n",ans); 86 int mn=0; 87 for(i=1;i<4;i++)if(t[i]<t[mn])mn=i; 88 for(i=0;i<4;i++)printf("%.5lf %.5lf\n",t[(i+mn)&3].x,t[(i+mn)&3].y); 89 }