啊啊啊啊啊啊啊啊手速不行啊打了好久啊好吧其实也想了好久
这道题真是神奇WA了好几次= =结果还是因为看错题
我们可以做个凸包,然后这个矩形上一定有点,而且不止一个,所以只有一个点的一定不是最优的,这样的话我们就可以枚举一个凸包上面的点(因为点太多23333333不然我就枚举对角线了),然后我们可以用叉积来卡这个点对面的点,用点积来卡两边的店,这样我们就可以用旋转卡壳来完美卡住这个矩形
至于输出,真的好麻烦愣是调了40分钟
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> #include<iomanip> #define LL long long #define fo(i,a,b) for(int i=a;i<=b;i++) using namespace std; #define N 50005 #define eps 1e-8 struct dian { double x,y; }d[N],ch[N],ans[5]; double ansarea=0.0; int n; double cross(dian a,dian b,dian c) { dian xlab,xlac; xlab.x=b.x-a.x; xlab.y=b.y-a.y; xlac.x=c.x-a.x; xlac.y=c.y-a.y; return (xlab.x*xlac.y)-(xlac.x*xlab.y); } double dj(dian a,dian b,dian c) { dian xlab,xlac; xlab.x=b.x-a.x; xlab.y=b.y-a.y; xlac.x=c.x-a.x; xlac.y=c.y-a.y; return (xlab.x*xlac.x)+(xlab.y*xlac.y); } double dis(dian a,dian b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } bool sortcom(dian a,dian b) { double t=cross(d[1],a,b); if (fabs(t)<eps) return dis(d[1],a)-dis(d[1],b)<eps; return t>0; } bool xy(dian a,dian b) { if (fabs(a.x-b.x)<=eps) return (a.y-b.y<eps); else return (a.x-b.x<eps); } bool yx(dian a,dian b) { if (fabs(a.y-b.y)<eps) return (a.x-b.x<eps); else return (a.y-b.y<eps); } dian add(dian a,dian b) { dian t; t.x=a.x+b.x; t.y=a.y+b.y; return t; } dian minu(dian a,dian b) { dian t; t.x=a.x-b.x; t.y=a.y-b.y; return t; } dian dcheng(dian a,double b) { dian t; t.x=a.x*b; t.y=a.y*b; return t; } int s[N],top=0; void graham() { fo(i,2,n) if(yx(d[i],d[1])) swap(d[i],d[1]); sort(d+2,d+n+1,sortcom); s[++top]=1; fo(i,2,n) { while (top>1&&cross(d[s[top-1]],d[s[top]],d[i])<eps)top--; s[++top]=i; } s[0]=s[top]; fo(i,0,top) ch[i]=d[s[i]]; // cout<<top<<endl; // fo(i,1,top) cout<<ch[i].x<<' '<<ch[i].y<<endl; } //int q[5]; void getans(int i,int l,int up,int r) { double D,H,L,R,B,S; D=dis(ch[i],ch[i+1]); L=dj(ch[i],ch[i+1],ch[l])/D; R=dj(ch[i],ch[i+1],ch[r])/D; // B=(L+R)-D; B=R-L; H=fabs(cross(ch[i],ch[i+1],ch[up]))/D; S=H*B; // cout<<i<<' '<<l<<' '<<up<<' '<<r<<' '<<L<<' '<<R<<' '<<S<<' '<<ansarea<<endl; if (S-ansarea<eps||fabs(ansarea)<eps) { ans[0]=add(ch[i],dcheng(minu(ch[i+1],ch[i]),(R/D))); ans[1]=add(ans[0],dcheng(minu(ch[r],ans[0]),(H/dis(ans[0],ch[r])))); ans[2]=minu(ans[1],dcheng(minu(ans[0],ch[i]),((R-L)/dis(ch[i],ans[0])))); ans[3]=minu(ans[2],minu(ans[1],ans[0])); ansarea=S; } } void RC() { int up=1,l=1,r=1; fo(i,0,top-1) { while(cross(ch[i],ch[i+1],ch[up+1])-cross(ch[i],ch[i+1],ch[up])>-eps) up=(up+1)%top; while(dj(ch[i],ch[i+1],ch[r+1])-dj(ch[i],ch[i+1],ch[r])>-eps) r=(r+1)%top; if (i==0) l=r; while(dj(ch[i],ch[i+1],ch[l+1])-dj(ch[i],ch[i+1],ch[l])<eps) l=(l+1)%top; getans(i,l,up,r); } } int main() { // freopen("data.in","r",stdin); scanf("%d",&n); fo(i,1,n) scanf("%lf%lf",&d[i].x,&d[i].y); graham(); RC(); int st=0;dian mi=ans[0]; fo(i,1,3) if (yx(ans[i],mi)) st=i; cout<<setiosflags(ios::fixed); cout.precision(5); cout<<ansarea<<endl; fo(i,st,st+4) if (i%5==4) continue; else cout<<ans[i%5].x<<' '<<ans[i%5].y<<endl; return 0; }