bzoj1185

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1185

裸的凸包外接矩形

要注意两点:

(1)输入时乘100000以减少误差

(2)注意-0的输出

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
 
using namespace std;

typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef complex<DB> CP;

#define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define re(i,a,b)  for(i=a;i<=b;i++)
#define red(i,a,b) for(i=a;i>=b;i--)
#define fi first
#define se second
#define m_p(a,b) make_pair(a,b)
#define SF scanf
#define PF printf
#define two(k) (1<<(k))

template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}

const DB EPS=1e-9;
inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
const DB Pi=acos(-1.0);

inline int gint()
  {
        int res=0;bool neg=0;char z;
        for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
        if(z==EOF)return 0;
        if(z=='-'){neg=1;z=getchar();}
        for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
        return (neg)?-res:res; 
    }
inline LL gll()
  {
      LL res=0;bool neg=0;char z;
        for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
        if(z==EOF)return 0;
        if(z=='-'){neg=1;z=getchar();}
        for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
        return (neg)?-res:res; 
    }

const int maxN=50000;
const DB INF=1e50;

struct Tpoint
  {
      DB x,y;
      inline Tpoint(DB _x=0.0,DB _y=0.0){x=_x;y=_y;}
      inline void input(){scanf("%lf%lf\n",&x,&y);x*=100000.0;y*=100000.0;}
  };

inline DB det(Tpoint p0,Tpoint p1,Tpoint p2){return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}

inline DB dist(Tpoint a,Tpoint b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}

inline DB area(Tpoint a,Tpoint st,Tpoint en){return abs(det(a,st,en))/2.0;}

inline DB dot(Tpoint p1,Tpoint p2,Tpoint p3,Tpoint p4){return (p2.x-p1.x)*(p4.x-p3.x)+(p2.y-p1.y)*(p4.y-p3.y);}

inline DB dot(Tpoint p0,Tpoint p1,Tpoint p2) {return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);}

inline Tpoint foot(Tpoint st,Tpoint en,Tpoint a)
  {
      DB l1=dist(st,en),l2=dot(st,en,a)/l1;
      Tpoint res;
      res.x=(en.x-st.x)*(l2/l1)+st.x;
      res.y=(en.y-st.y)*(l2/l1)+st.y;
        return res;
  }

int N;
Tpoint p[maxN+100];

inline bool cmp(Tpoint a,Tpoint b){return sgn(a.y-b.y)!=0?sgn(a.y-b.y)<0:sgn(a.x-b.x)<0;}
int top;Tpoint sta[maxN+100];
inline void tubao()
  {
      int i;
      sort(p+1,p+N+1,cmp);
      top=0;
      re(i,1,N)
        {
            while(top>1 && sgn(det(sta[top-1],sta[top],p[i]))<=0)top--;
            sta[++top]=p[i];
        }
      int m=top;
      red(i,N,1)
        {
            while(top>m && sgn(det(sta[top-1],sta[top],p[i]))<=0)top--;
            sta[++top]=p[i];
        }
      top--;
      N=top;
      re(i,1,top)p[i]=sta[i];
      p[N+1]=p[1];
  }

DB ans;
Tpoint t[5];

int main()
  {
      freopen("square.in","r",stdin);
      freopen("square.out","w",stdout);
      int i;
      N=gint();
      re(i,1,N)p[i].input();
      p[N+1]=p[1];
      tubao();
      ans=INF;
      #define next(i) (i%N+1)
      int a=1,b=2,c=2,d=3;
      re(a,1,N)
        {
            while( sgn( area(p[c],p[a],p[next(a)]) - area(p[next(c)],p[a],p[next(a)]) ) < 0 ){c=next(c);if(c==d)d=next(d);}
            while( next(b)!=c && sgn( dot(p[a],p[next(a)],p[b],p[next(b)]) ) >=0 ) b=next(b);
                while( next(d)!=a && sgn( dot(p[next(a)],p[a],p[d],p[next(d)]) ) >=0 ) d=next(d);
                Tpoint r1,r2,r3,r4,z;
                r1=foot(p[a],p[next(a)],p[b]);
                r4=foot(p[a],p[next(a)],p[d]);
                z=foot(p[a],p[next(a)],p[c]);
                r2=Tpoint(r1.x+p[c].x-z.x,r1.y+p[c].y-z.y);
                r3=Tpoint(r4.x+p[c].x-z.x,r4.y+p[c].y-z.y);
                DB res=area(r1,r2,r4)*2.0;
                if(sgn(res-ans)<0){ans=res;t[1]=r1;t[2]=r2;t[3]=r3;t[4]=r4;}
            }
        if(sgn(ans)==0) ans=0.0;
        printf("%0.5lf\n",ans/10000000000.0);
        int be=1;
        re(i,2,4)if(cmp(t[i],t[be])) be=i;
        re(i,1,4)\
          {
              if(sgn(t[be].x)==0)t[be].x=0.0;
              if(sgn(t[be].y)==0)t[be].y=0.0;
              printf("%0.5lf %0.5lf\n",t[be].x/100000.0,t[be].y/100000.0);
                be=be%4+1;
            }
        return 0;
  }
View Code

 

posted @ 2015-07-18 11:01  maijing  阅读(159)  评论(0编辑  收藏  举报