P3187 [HNOI2007]最小矩形覆蓋
阿新 • • 發佈:2018-11-23
首先這個矩形的一條邊肯定在凸包上。那麼可以求出凸包然後列舉邊,用類似旋轉卡殼的方法求出另外三條邊的位置,也就是求出以它為底最上面最右邊最左邊的點的位置。離它最遠的點可以用叉積求,最左最右的可以用點積求。順便注意精度問題,因為很小的時候可能會輸出-0.00000,所以特判一下,當座標小於eps的時候強制它等於0就行了
//minamoto #include<bits/stdc++.h> #define fp(i,a,b) for(register int i=a,I=b+1;i<I;++i) #define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i) #define ab(a) (a<0?a=-a:0) using namespace std; const int N=1e5+5;const double eps=1e-8; struct node{double x,y;}p[N],st[N],q[5];int top,n; inline node operator -(node a,node b){return node{a.x-b.x,a.y-b.y};} inline node operator +(node a,node b){return node{a.x+b.x,a.y+b.y};} inline node operator *(node a,double b){return node{a.x*b,a.y*b};} inline double operator *(node a,node b){return a.x*b.y-b.x*a.y;} inline double dot(node a,node b){return a.x*b.x+a.y*b.y;} inline double area(node a,node b,node c){return fabs((b-a)*(c-a));} inline double len(node a){return sqrt(a.x*a.x+a.y*a.y);} inline bool operator <(node a,node b){ a=a-p[1],b=b-p[1]; return a*b==0?len(a)<len(b):a*b>0; } void graham(){ int k=1; fp(i,1,n){ scanf("%lf%lf",&p[i].x,&p[i].y); if(p[i].y<p[k].y||(p[i].y==p[k].y&&p[i].x<p[k].x))k=i; }swap(p[1],p[k]),sort(p+2,p+n+1); st[0]=p[1],st[1]=p[2],top=1; fp(i,3,n){ while(top&&(p[i]-st[top-1])*(st[top]-st[top-1])>=0)--top; st[++top]=p[i]; }st[++top]=p[1]; // fp(i,0,top)printf("%.2lf %.2lf\n",st[i].x,st[i].y); } void get(){ double ans=1e100;int a=1,b=1,c=1; fp(i,1,top-2){ while((st[a+1]-st[i])*(st[i-1]-st[i])>=(st[a]-st[i])*(st[i-1]-st[i]))a=(a+1)%top; while(dot(st[b+1]-st[i],st[i-1]-st[i])<=dot(st[b]-st[i],st[i-1]-st[i]))b=(b+1)%top; if(i==1)c=a; while(dot(st[c+1]-st[i-1],st[i]-st[i-1])<=dot(st[c]-st[i-1],st[i]-st[i-1]))c=(c+1)%top; double dis=len(st[i]-st[i-1]); double L=dot(st[c]-st[i],st[i-1]-st[i])/dis;ab(L); double R=dot(st[b]-st[i-1],st[i]-st[i-1])/dis;ab(R); double H=area(st[i],st[i-1],st[a])/dis;ab(H); double tmp=(L+R-dis)*H; if(tmp<ans){ ans=tmp; q[0]=st[i]-(st[i]-st[i-1])*(L/dis); q[1]=q[0]+(st[i]-st[i-1])*((L+R-dis)/dis); q[2]=q[1]+(st[b]-q[1])*(H/len(st[b]-q[1])); q[3]=q[2]+(st[i-1]-st[i])*((L+R-dis)/dis); } }printf("%.5lf\n",ans); } int main(){ // freopen("testdata.in","r",stdin); scanf("%d",&n);graham();get(); int s=0; fp(i,0,3)if(q[i].y<q[s].y||(q[i].y==q[s].y&&q[i].x<q[s].x))s=i; if(fabs(q[s].x)<=eps)q[s].x=0;if(fabs(q[s].y)<=eps)q[s].y=0; printf("%.5lf %.5lf\n",q[s].x,q[s].y); fp(i,1,3){ s=(s+1)%4; if(fabs(q[s].x)<=eps)q[s].x=0;if(fabs(q[s].y)<=eps)q[s].y=0; printf("%.5lf %.5lf\n",q[s].x,q[s].y); }return 0; }