【bzoj1185】[HNOI2007]最小矩形覆盖 (旋转卡壳)
给你一些点,让你用最小的矩形覆盖这些点
首先有一个结论,矩形的一条边一定在凸包上!!!
枚举凸包上的边
用旋转卡壳在凸包上找矩形另外三点。。。
注意精度问题
1 #include<cstdio> 2 #include<cmath> 3 #include<ctime> 4 #include<cstring> 5 #include<iostream> 6 #include<algorithm> 7 #include<queue> 8 #include<set> 9 #define eps 1e-8 10 #define inf 1000000000 11 using namespace std; 12 double ans=1e60; 13 int n,top; 14 struct P{ 15 double x,y; 16 P(){} 17 P(double _x,double _y):x(_x),y(_y){} 18 friend bool operator<(P a,P b){ 19 return fabs(a.y-b.y)<eps?a.x<b.x:a.y<b.y; 20 } 21 friend bool operator==(P a,P b){ 22 return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps; 23 } 24 friend bool operator!=(P a,P b){ 25 return !(a==b); 26 } 27 friend P operator+(P a,P b){ 28 return P(a.x+b.x,a.y+b.y); 29 } 30 friend P operator-(P a,P b){ 31 return P(a.x-b.x,a.y-b.y); 32 } 33 friend double operator*(P a,P b){ 34 return a.x*b.y-a.y*b.x; 35 } 36 friend P operator*(P a,double b){ 37 return P(a.x*b,a.y*b); 38 } 39 friend double operator/(P a,P b){ 40 return a.x*b.x+a.y*b.y; 41 } 42 friend double dis(P a){ 43 return sqrt(a.x*a.x+a.y*a.y); 44 } 45 }p[50005],q[50005],t[5]; 46 bool cmp(P a,P b) 47 { 48 double t=(a-p[1])*(b-p[1]); 49 if(fabs(t)<eps)return dis(p[1]-a)-dis(p[1]-b)<0; 50 return t>0; 51 } 52 void graham() 53 { 54 for(int i=2;i<=n;i++) 55 if(p[i]<p[1]) 56 swap(p[i],p[1]); 57 sort(p+2,p+n+1,cmp); 58 q[++top]=p[1]; 59 for(int i=2;i<=n;i++) 60 { 61 while(top>1&&(q[top]-q[top-1])*(p[i]-q[top])<eps)top--; 62 q[++top]=p[i]; 63 } 64 q[0]=q[top]; 65 } 66 void RC() 67 { 68 int l=1,r=1,p=1; 69 double L,R,D,H; 70 for(int i=0;i<top;i++) 71 { 72 D=dis(q[i]-q[i+1]); 73 while((q[i+1]-q[i])*(q[p+1]-q[i])-(q[i+1]-q[i])*(q[p]-q[i])>-eps)p=(p+1)%top; 74 while((q[i+1]-q[i])/(q[r+1]-q[i])-(q[i+1]-q[i])/(q[r]-q[i])>-eps)r=(r+1)%top; 75 if(i==0)l=r; 76 while((q[i+1]-q[i])/(q[l+1]-q[i])-(q[i+1]-q[i])/(q[l]-q[i])<eps)l=(l+1)%top; 77 L=(q[i+1]-q[i])/(q[l]-q[i])/D,R=(q[i+1]-q[i])/(q[r]-q[i])/D; 78 H=(q[i+1]-q[i])*(q[p]-q[i])/D; 79 if(H<0)H=-H; 80 double tmp=(R-L)*H; 81 if(tmp<ans) 82 { 83 ans=tmp; 84 t[0]=q[i]+(q[i+1]-q[i])*(R/D); 85 t[1]=t[0]+(q[r]-t[0])*(H/dis(t[0]-q[r])); 86 t[2]=t[1]-(t[0]-q[i])*((R-L)/dis(q[i]-t[0])); 87 t[3]=t[2]-(t[1]-t[0]); 88 } 89 } 90 } 91 int main() 92 { 93 scanf("%d",&n); 94 for(int i=1;i<=n;i++) 95 scanf("%lf%lf",&p[i].x,&p[i].y); 96 graham(); 97 RC(); 98 printf("%.5lf\n",ans); 99 int fir=0; 100 for(int i=1;i<=3;i++) 101 if(t[i]<t[fir]) 102 fir=i; 103 for(int i=0;i<=3;i++) 104 printf("%.5lf %.5lf\n",t[(i+fir)%4].x,t[(i+fir)%4].y); 105 return 0; 106 }