BZOJ 1185 [HNOI2007]最小矩形覆盖 ——计算几何
程序写的太垃圾,卡不过去。
GG,甘拜下风。
#include <map> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) //#define double long double #define eps 1e-8 #define ll long long #define mp make_pair struct Vector{ double x,y; void print() { printf("Vector -> (%.3f,%.3f)\n",x,y); } }; struct Point{ double x,y; void print() { printf("%.5f %.5f\n",x+eps,y+eps); } }; int n; Vector operator - (Point a,Point b) {Vector ret;ret.x=a.x-b.x;ret.y=a.y-b.y;return ret;} Point operator + (Point a,Vector b) {Point ret;ret.x=a.x+b.x;ret.y=a.y+b.y;return ret;} Vector Vertical (Vector a) {Vector ret;ret.x=-a.y;ret.y=a.x;return ret;} double operator * (Vector a,Vector b) {return a.x*b.y-a.y*b.x;} Vector operator * (Vector a,double b) {Vector ret;ret.x=a.x*b;ret.y=a.y*b;return ret;} Point Node (Point P1,Vector V1,Point P2,Vector V2) {return P1+V1*((V2*(P1-P2))/(V1*V2));} Point a[50005]; void Test() { printf("Test : \n"); Point P1,P2;Vector V1,V2; P1.x=0;P1.y=1;V1.x=1;V1.y=1; P2.x=1;P2.y=0;V2.x=1;V2.y=2; Node(P1,V1,P2,V2).print(); } bool cmp(Point a,Point b) {return fabs(a.x-b.x)<eps?a.y<b.y:a.x<b.x;} Point sta[50005]; int top=0; void Andrew() { sta[++top]=a[1]; F(i,2,n) if (fabs(a[i].x-a[i-1].x)>=eps||fabs(a[i].y-a[i-1].y)>=eps){ while (top>=2&&(sta[top]-sta[top-1])*(a[i]-sta[top])<0) top--; sta[++top]=a[i]; } int lower=top; D(i,n-1,1) if (fabs(a[i].x-a[i+1].x)>=eps||fabs(a[i].y-a[i+1].y)>=eps){ while (top-lower>=1&&(sta[top]-sta[top-1])*(a[i]-sta[top])<0) top--; sta[++top]=a[i]; } } double Dot(Vector a,Vector b) {return a.x*b.x+a.y*b.y;} double Len(Vector a) { return Dot(a,a); } void Finout() { freopen("in.txt","r",stdin); } Point now[4],ans[4]; double tmp=1e18,nowans; void Rotating() { int l=top-1,r=3,p=2; while (Dot(sta[2]-sta[1],sta[l]-sta[1])>Dot(sta[2]-sta[1],sta[l-1]-sta[1])) l--; while (Dot(sta[2]-sta[1],sta[r]-sta[1])<Dot(sta[2]-sta[1],sta[r+1]-sta[1])) r++; F(i,1,top-1) { while (Dot(sta[i+1]-sta[i],sta[l]-sta[i])>Dot(sta[i+1]-sta[i],sta[l+1]-sta[i])) l=l%top+1; while (Dot(sta[i+1]-sta[i],sta[r]-sta[i])<Dot(sta[i+1]-sta[i],sta[r+1]-sta[i])) r=r%top+1; while ((sta[i+1]-sta[i])*(sta[p]-sta[i])<(sta[i+1]-sta[i])*(sta[p+1]-sta[i])) p=p%top+1; now[0]=Node(sta[i],sta[i+1]-sta[i],sta[l],Vertical(sta[i+1]-sta[i])); now[1]=Node(sta[i],sta[i+1]-sta[i],sta[r],Vertical(sta[i+1]-sta[i])); now[2]=Node(sta[p],sta[i+1]-sta[i],sta[r],Vertical(sta[i+1]-sta[i])); now[3]=Node(sta[p],sta[i+1]-sta[i],sta[l],Vertical(sta[i+1]-sta[i])); if ((nowans=sqrt(Len(now[0]-now[1])*Len(now[1]-now[2])))<tmp) { F(j,0,3) ans[j]=now[j]; tmp=nowans; } } int st=-1;Point stp; stp.x=1e18;stp.y=1e18; F(i,0,3) if (fabs(ans[i].y-stp.y)<eps?ans[i].x<stp.x:ans[i].y<stp.y) st=i,stp=ans[i]; printf("%.5f\n",tmp+eps); F(i,0,3) ans[(i+st)%4].print(); } int main() { scanf("%d",&n); F(i,1,n) scanf("%lf%lf",&a[i].x,&a[i].y); sort(a+1,a+n+1,cmp); Andrew(); Rotating(); }