BZOJ 1069 [SCOI2007]最大土地面积 ——计算几何
枚举对角线,然后旋转卡壳即可。
#include <map> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) #define eps 1e-8 #define ll long long #define mp make_pair struct Vector{ double x,y; void print() { printf("Vector -> (%.3f,%.3f)\n",x,y); } }; struct Point{ double x,y; void print() { printf("Point (%.3f,%.3f)\n",x,y); } }; double operator * (Vector a,Vector b) {return a.x*b.y-a.y*b.x;} Vector operator - (Point a,Point b) {Vector ret;ret.x=a.x-b.x;ret.y=a.y-b.y;return ret;} int n,top=0; Point p[2005],sta[2005]; bool cmp(Point a,Point b) {return fabs(a.x-b.x)<eps?a.y<b.y:a.x<b.x;} void Andrew() { sta[++top]=p[1]; F(i,2,n) { while (top>=2&&(sta[top]-sta[top-1])*(p[i]-sta[top])<eps) top--; sta[++top]=p[i]; } int lower=top; D(i,n-1,1) { while (top-lower>=1&&(sta[top]-sta[top-1])*(p[i]-sta[top])<eps) top--; sta[++top]=p[i]; } // printf("In the outside :\n"); // F(i,1,top) sta[i].print(); } double ans=0; void Rotating() { F(x,1,top-2) { int a=x%top+1,b=(x+2)%top+1; F(y,x+2,top-1) { while (a%top+1!=y&&(sta[a+1]-sta[x])*(sta[y]-sta[x])>(sta[a]-sta[x])*(sta[y]-sta[x])) a=a%top+1; while (b%top+1!=x&&(sta[y]-sta[x])*(sta[b+1]-sta[x])>(sta[y]-sta[x])*(sta[b]-sta[x])) b=b%top+1; ans=max(ans,(sta[a]-sta[x])*(sta[y]-sta[x])+(sta[y]-sta[x])*(sta[b]-sta[x])); } } } int main() { // freopen("in.txt","r",stdin); scanf("%d",&n); F(i,1,n) scanf("%lf%lf",&p[i].x,&p[i].y); sort(p+1,p+n+1,cmp); Andrew(); Rotating(); printf("%.3f\n",ans/2.0); }