首先这个矩形的一条边肯定在凸包上。那么可以求出凸包然后枚举边,用类似旋转卡壳的方法求出另外三条边的位置,也就是求出以它为底最上面最右边最左边的点的位置。离它最远的点可以用叉积求,最左最右的可以用点积求。顺便注意精度问题,因为很小的时候可能会输出-0.00000,所以特判一下,当坐标小于eps的时候强制它等于0就行了
//minamoto#include#define fp(i,a,b) for(register int i=a,I=b+1;i I;--i)#define ab(a) (a<0?a=-a:0)using namespace std;const int N=1e5+5;const double eps=1e-8;struct node{double x,y;}p[N],st[N],q[5];int top,n;inline node operator -(node a,node b){return node{a.x-b.x,a.y-b.y};}inline node operator +(node a,node b){return node{a.x+b.x,a.y+b.y};}inline node operator *(node a,double b){return node{a.x*b,a.y*b};}inline double operator *(node a,node b){return a.x*b.y-b.x*a.y;}inline double dot(node a,node b){return a.x*b.x+a.y*b.y;}inline double area(node a,node b,node c){return fabs((b-a)*(c-a));}inline double len(node a){return sqrt(a.x*a.x+a.y*a.y);}inline bool operator <(node a,node b){ a=a-p[1],b=b-p[1]; return a*b==0?len(a) 0;}void graham(){ int k=1; fp(i,1,n){ scanf("%lf%lf",&p[i].x,&p[i].y); if(p[i].y =0)--top; st[++top]=p[i]; }st[++top]=p[1];// fp(i,0,top)printf("%.2lf %.2lf\n",st[i].x,st[i].y);}void get(){ double ans=1e100;int a=1,b=1,c=1; fp(i,1,top-2){ while((st[a+1]-st[i])*(st[i-1]-st[i])>=(st[a]-st[i])*(st[i-1]-st[i]))a=(a+1)%top; while(dot(st[b+1]-st[i],st[i-1]-st[i])<=dot(st[b]-st[i],st[i-1]-st[i]))b=(b+1)%top; if(i==1)c=a; while(dot(st[c+1]-st[i-1],st[i]-st[i-1])<=dot(st[c]-st[i-1],st[i]-st[i-1]))c=(c+1)%top; double dis=len(st[i]-st[i-1]); double L=dot(st[c]-st[i],st[i-1]-st[i])/dis;ab(L); double R=dot(st[b]-st[i-1],st[i]-st[i-1])/dis;ab(R); double H=area(st[i],st[i-1],st[a])/dis;ab(H); double tmp=(L+R-dis)*H; if(tmp