1185: [HNOI2007]最小矩形覆盖
Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1945 Solved: 853
[Submit][Status][Discuss]
Description
题解
显然矩形一边一定在凸包一边上
旋转卡壳维护其他三条边经过的顶点
更新答案
这题1A欸嘿嘿
代码
//by 减维 #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<bitset> #include<set> #include<cmath> #include<vector> #include<set> #include<map> #include<ctime> #include<algorithm> #define LL long long #define db double #define inf 1<<30 #define maxn 50005 #define eps 1e-8 using namespace std; struct node{ db x,y; }poi[maxn],sta[maxn],ans[15]; int n,top; db mn=100000000.00; bool cmp(node x,node y){if(x.x==y.x)return x.y<y.y;return x.x<y.x;} bool cm2(node x,node y){if(x.x==y.x)return x.y>y.y;return x.x>y.x;} node operator - (node x,node y){return (node){x.x-y.x,x.y-y.y};} node operator + (node x,node y){return (node){x.x+y.x,x.y+y.y};} node operator * (node x,db y){return (node){x.x*y,x.y*y};} node operator * (db x,node y){return (node){x*y.x,x*y.y};} db operator * (node x,node y){return x.x*y.y-x.y*y.x;} db operator / (node x,node y){return x.x*y.x+x.y*y.y;} bool operator == (node x,node y){return x.x==y.x&&x.y==y.y;} bool operator > (node x,node y){if(x.y==y.y)return x.x>x.y;return x.y>y.y;} db dis(node x,node y){return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));} void solve() { db ds,h,ll,rr; int t=0,l=0,r=0; sta[0]=sta[top]; for(int i=0;i<top;++i) { ds=dis(sta[i],sta[i+1]); while((sta[i+1]-sta[i])*(sta[t+1]-sta[i])-(sta[i+1]-sta[i])*(sta[t]-sta[i])>-eps)t=(t+1)%top; while((sta[i+1]-sta[i])/(sta[r+1]-sta[i])-(sta[i+1]-sta[i])/(sta[r]-sta[i])>-eps)r=(r+1)%top; if(i==0)l=r; while((sta[i+1]-sta[i])/(sta[l]-sta[i])-(sta[i+1]-sta[i])/(sta[l+1]-sta[i])>-eps)l=(l+1)%top; ll=(sta[i+1]-sta[i])/(sta[l]-sta[i])/ds; rr=(sta[i+1]-sta[i])/(sta[r]-sta[i])/ds; h=(sta[i+1]-sta[i])*(sta[t]-sta[i])/ds; if(mn>(rr-ll)*h){ mn=(rr-ll)*h; ans[0]=sta[i]+(sta[i+1]-sta[i])*(rr/ds); ans[1]=ans[0]+(sta[r]-ans[0])*(h/dis(sta[r],ans[0])); ans[2]=ans[1]+(sta[t]-ans[1])*((rr-ll)/dis(sta[t],ans[1])); ans[3]=ans[2]+(ans[0]-ans[1]); } } } int main() { scanf("%d",&n); for(int i=1;i<=n;++i)scanf("%lf%lf",&poi[i].x,&poi[i].y); sort(poi+1,poi+n+1,cmp); sta[++top]=poi[1];sta[++top]=poi[2]; for(int i=3;i<=n;++i){ while((poi[i]-sta[top-1])*(sta[top]-sta[top-1])>-eps&&top>=2)top--; sta[++top]=poi[i]; } sort(poi+1,poi+n+1,cm2); int sa=top; if(sta[top]==poi[1])sta[++top]=poi[2],sa--; else sta[++top]=poi[1],sta[++top]=poi[2]; for(int i=3;i<=n;++i){ while((poi[i]-sta[top-1])*(sta[top]-sta[top-1])>-eps&&top>sa)top--; sta[++top]=poi[i]; } top--; solve(); printf("%.5lf ",mn); int fir=0; for(int i=1;i<=3;++i)if(ans[fir]>ans[i])fir=i; for(int i=0;i<=3;++i)printf("%.5lf %.5lf ",ans[(fir+i)%4],ans[(fir+i)%4]); return 0; }