题目链接
http://www.lydsy.com/JudgeOnline/problem.php?id=1185
思路
http://blog.csdn.net/qpswwww/article/details/44102039
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <cmath>
#define MAXN 1000000
#define EPS 1e-7
using namespace std;
int n;
double minsqr=1e20;
int dcmp(double x)
{
if(fabs(x)<EPS) return 0;
if(x>EPS) return 1;
return -1;
}
struct Point
{
double x,y;
Point(){}
Point(double _x,double _y):x(_x),y(_y){}
inline void read()
{
scanf("%lf%lf",&x,&y);
}
}points[MAXN],stack[MAXN<<1],ans[10];
int top=0;
Point operator-(Point a,Point b)
{
return Point(a.x-b.x,a.y-b.y);
}
Point operator*(Point a,double b)
{
return Point(a.x*b,a.y*b);
}
Point operator+(Point a,Point b)
{
return Point(a.x+b.x,a.y+b.y);
}
double cross(Point a,Point b,Point c) //a->b X a->c
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
double dot(Point a,Point b,Point c) //a->b 点乘 b->c
{
return (b.x-a.x)*(c.x-b.x)+(b.y-a.y)*(c.y-b.y);
}
double dist(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cmp(Point a,Point b)
{
if(!dcmp(a.x-b.x)) return a.y<b.y;
return a.x<b.x;
}
void Graham()
{
sort(points+1,points+n+1,cmp);
for(int i=1;i<=n;i++)
{
while(top>=2&&dcmp(cross(stack[top-1],stack[top],points[i]))<=0) top--;
stack[++top]=points[i];
}
int tmp=top;
for(int i=n-1;i>=1;i--)
{
while(top>=tmp+1&&dcmp(cross(stack[top-1],stack[top],points[i]))<=0) top--;
stack[++top]=points[i];
}
top--; //stack[1]=stack[top]
}
void rotcalip()
{
int left=1,right=1,up=1; //矩形卡在凸包上的左、右、上三个点,下面的是一条长度为L直线
for(int i=1;i<=top;i++)
{
while(dcmp(cross(stack[up+1],stack[i],stack[i+1])-cross(stack[up],stack[i],stack[i+1]))>=0) up=up%top+1;
while(dcmp(dot(stack[right+1],stack[i+1],stack[i])-dot(stack[right],stack[i+1],stack[i]))>=0) right=right%top+1; //!!!!!
if(i==1) left=right;
while(dcmp(dot(stack[left+1],stack[i],stack[i+1])-dot(stack[left],stack[i],stack[i+1]))>=0) left=left%top+1; //!!!!!!
double L=dist(stack[i],stack[i+1]);
double H=cross(stack[i+1],stack[up],stack[i])/L;
double bottom=(fabs(dot(stack[i],stack[i+1],stack[left])/L)+fabs(dot(stack[i],stack[i+1],stack[right])/L));
double nowsqr=bottom*H;
if(nowsqr<minsqr)
{
minsqr=nowsqr;
ans[0]=stack[i]+(stack[i+1]-stack[i])*((fabs(dot(stack[i],stack[i+1],stack[right])/L)+L)/L);
ans[1]=ans[0]+(stack[right]-ans[0])*(H/dist(stack[right],ans[0]));
ans[2]=ans[1]+(stack[up]-ans[1])*(bottom/dist(stack[up],ans[1]));
ans[3]=ans[2]+(stack[left]-ans[2])*(H/dist(stack[left],ans[2]));
}
}
}
bool operator<(Point a,Point b)
{
if(!dcmp(a.y-b.y)) return a.x<b.x;
return a.y<b.y;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
points[i].read();
Graham();
rotcalip();
printf("%.5lf\n",minsqr);
int tmp=0;
for(int i=0;i<=3;i++)
if(ans[i]<ans[tmp])
tmp=i;
for(int i=0;i<=3;i++)
printf("%.5lf %.5lf\n",ans[(i+tmp)%4].x,ans[(i+tmp)%4].y); //!!!!
return 0;
}