BZOJ 1185 最小矩形覆盖

Description

Input

Output

Sample Input

Sample Output

HINT

其实这题就是一道旋转卡壳的裸题,但是我的精度萎了。直接上hzwer的代码吧。。。

#include<cstdio>
#include<cmath>
#include<ctime>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<set>
#define eps 1e-8
#define inf 1000000000
using namespace std;
double ans=1e60;
int n,top;
struct P{
	double x,y;
	P(){}
	P(double _x,double _y):x(_x),y(_y){}
	friend bool operator<(P a,P b){
		return fabs(a.y-b.y)<eps?a.x<b.x:a.y<b.y;
	}
	friend bool operator==(P a,P b){
		return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps;
	}
	friend bool operator!=(P a,P b){
		return !(a==b);
	}
	friend P operator+(P a,P b){
		return P(a.x+b.x,a.y+b.y);
	}
	friend P operator-(P a,P b){
		return P(a.x-b.x,a.y-b.y);
	}
	friend double operator*(P a,P b){
		return a.x*b.y-a.y*b.x;
	}
	friend P operator*(P a,double b){
		return P(a.x*b,a.y*b);
	}
	friend double operator/(P a,P b){
		return a.x*b.x+a.y*b.y;
	}
	friend double dis(P a){
		return sqrt(a.x*a.x+a.y*a.y);
	}
}p[50005],q[50005],t[5];
bool cmp(P a,P b)
{
	double t=(a-p[1])*(b-p[1]);
	if(fabs(t)<eps)return dis(p[1]-a)-dis(p[1]-b)<0;
	return t>0;
}
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,cmp);
	q[++top]=p[1];
	for(int i=2;i<=n;i++)
	{
		while(top>1&&(q[top]-q[top-1])*(p[i]-q[top])<eps)top--;
		q[++top]=p[i];
	}
	q[0]=q[top];
}
void RC()
{
	int l=1,r=1,p=1;
	double L,R,D,H;
	for(int i=0;i<top;i++)
	{
		D=dis(q[i]-q[i+1]);
		while((q[i+1]-q[i])*(q[p+1]-q[i])-(q[i+1]-q[i])*(q[p]-q[i])>-eps)p=(p+1)%top;
		while((q[i+1]-q[i])/(q[r+1]-q[i])-(q[i+1]-q[i])/(q[r]-q[i])>-eps)r=(r+1)%top;
		if(i==0)l=r;
		while((q[i+1]-q[i])/(q[l+1]-q[i])-(q[i+1]-q[i])/(q[l]-q[i])<eps)l=(l+1)%top;
	    L=(q[i+1]-q[i])/(q[l]-q[i])/D,R=(q[i+1]-q[i])/(q[r]-q[i])/D;
		H=(q[i+1]-q[i])*(q[p]-q[i])/D;
		if(H<0)H=-H;
		double tmp=(R-L)*H;
		if(tmp<ans)
		{
		    ans=tmp;
			t[0]=q[i]+(q[i+1]-q[i])*(R/D);
			t[1]=t[0]+(q[r]-t[0])*(H/dis(t[0]-q[r]));
			t[2]=t[1]-(t[0]-q[i])*((R-L)/dis(q[i]-t[0]));
			t[3]=t[2]-(t[1]-t[0]);
		}
	}
}
int main()
{
	freopen("1185.in","r",stdin);
	freopen("1185.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%lf%lf",&p[i].x,&p[i].y);
	graham();
	RC();
	printf("%.5lf
",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
",t[(i+fir)%4].x,t[(i+fir)%4].y);
	return 0;
}
原文地址:https://www.cnblogs.com/mmlz/p/4318393.html