BZOJ1185 HNOI2007 最小矩阵覆盖

1185: [HNOI2007]最小矩形覆盖

Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge
Submit: 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;
}

  

 

 
posted @ 2017-12-08 22:03  zhangenming  阅读(278)  评论(0编辑  收藏  举报