BZOJ1185 HNOI2007 最小矩阵覆盖
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; }