1185: [HNOI2007]最小矩形覆盖
Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1898 Solved: 833
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
Sample Output
HINT
Source
先做出凸包,再旋转卡壳
注意卡上界用叉积,卡左右边界用点积
代码中定义的除号其实就是点积的函数
#include <bits/stdc++.h>
#define ll long long
#define eps 1e-8
using namespace std;
inline int read(){
int x=0;int f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f-=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=1e6+10;
struct node{
double x,y;
}s[MAXN],p[MAXN],t[10];
int top,n;
double ans=1e60;
inline bool operator < (node n,node m){
return abs(n.y-m.y)<eps?n.x<m.x:n.y<m.y;
}
inline node operator + (node n,node m){
node t;t.x=n.x+m.x;t.y=n.y+m.y;return t;
}
inline node operator - (node n,node m){
node t;t.x=n.x-m.x;t.y=n.y-m.y;return t;
}
inline double operator * (node n,node m){
return n.x*m.y-n.y*m.x;
}
inline node operator * (node n,double m){
node t;t.x=n.x*m;t.y=n.y*m;return t;
}
inline int dcmp(node n,node m){
return n.x-m.x<eps&&n.y-m.y<eps;
}
inline double dis(node n){
return sqrt(n.x*n.x+n.y*n.y);
}
inline bool mycmp(node n,node m){
double t=(n-p[1])*(m-p[1]);
if(abs(t)<eps) return dis(n-p[1])-dis(m-p[1])<0;
else return t>0;
}
inline double operator / (node n,node m){//dianji
return n.x*m.x+n.y*m.y;
}
void graham(){
for(int i=2;i<=n;i++){
if(p[i]<p[1]) swap(p[i],p[1]);
}
sort(p+2,p+n+1,mycmp);
s[++top]=p[1];
for(int i=2;i<=n;i++){
while(top>1&&(s[top]-s[top-1])*(p[i]-s[top])<eps) top--;
s[++top]=p[i];
}
s[0]=s[top];
}
void RC(){
int l=1,r=1,p=1;
double R,L,D,H;
for(int i=0;i<top;i++){
D=dis(s[i]-s[i+1]);
while((s[i+1]-s[i])*(s[p+1]-s[i])-(s[i+1]-s[i])*(s[p]-s[i])>-eps) p=(p+1)%top;
while((s[i+1]-s[i])/(s[r+1]-s[i])-(s[i+1]-s[i])/(s[r]-s[i])>-eps) r=(r+1)%top;
if(i==0) l=r;
while((s[i+1]-s[i])/(s[l+1]-s[i])-(s[i+1]-s[i])/(s[l]-s[i])<eps) l=(l+1)%top;
L=(s[i+1]-s[i])/(s[l]-s[i])/D;R=(s[i+1]-s[i])/(s[r]-s[i])/D;
H=(s[i+1]-s[i])*(s[p]-s[i])/D;
if(H<0) H=-H;
//cout<<l<<' '<<r<<endl;
double tmp=(R-L)*H;
if(tmp<ans){
ans=tmp;
t[0]=s[i]+(s[i+1]-s[i])*(R/D);
t[1]=t[0]+(s[r]-t[0])*(H/dis(t[0]-s[r]));
t[2]=t[1]-(t[0]-s[i])*((R-L)/dis(s[i]-t[0]));
t[3]=t[2]-(t[1]-t[0]);
}
}
}
int main(){
//freopen("All.in","r",stdin);
//freopen("a.out","w",stdout);
n=read();
for(int i=1;i<=n;i++){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
graham();
RC();
printf("%.5lf\n",ans);
int fir=0;
for(int i=1;i<=3;i++){
if(t[i]<t[fir]) fir=i;
}
for(int i=0;i<=3;i++){
printf("%.5lf %.5lf\n",t[(i+fir)%4].x,t[(i+fir)%4].y);
}
return 0;
}