Small dumpling enclosure
Problem description
There is a plot of land in Xiaozong's house, and there are n stakes on the ground. Xiaozongjia's land can be seen as a plane, and Xiaozong knows the coordinates of each stake (xi,yi).
Little zongzi likes the quadrilateral very much. Now she wants to choose 4 from these stakes to form a quadrilateral (this quadrilateral is a simple polygon, that is, each edge can not intersect with itself, but not necessarily a convex quadrilateral), and makes the quadrilateral the largest area. Please help Xiaozong figure out what the maximum is.
Input format
In the first line, a positive integer n denotes the size of the stake. Next, i n line n, two real numbers Xi and Yi at line I describe the coordinates of the pile I.
Output format
Output a real number in a row, representing the area of the largest quadrilateral enclosed. Keep three decimal places.
Input Sample 1
5 0 0 1 0 1 1 0 1 0.5 0.5
Output Sample 1
1.000
Example 2
Click here to download.
Data Scope and Agreement
20% of the data satisfies n < 100;
60% of the data meet n < 400;
80% of the data meet n < 1500;
100% of the data satisfy n < 5000, all coordinates are in the range of int.
Tips
[Obviously, the answer is on the convex hull]
[Consider enumerating a diagonal line and trying to locate the other two points, such as noticing that the location of the point is unimodal. ]
[More consideration should be given to finding the tangent points of diagonals and convex hulls, using monotonicity to equalize complexity]
Title Solution
//Rotating clamping method. #include <vector> #include <stdio.h> #include <iostream> #include <cstdio> #include <algorithm> using namespace std; struct Point { double x, y; Point(double x = 0, double y = 0) : x(x), y(y) {} void read() { scanf("%lf%lf", &x, &y); } void print() { printf("%lf %lf\n", x, y); } }; Point operator + (const Point& a, const Point& b) { return Point(a.x + b.x, a.y + b.y); } Point operator - (const Point& a, const Point& b) { return Point(a.x - b.x, a.y - b.y); } double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; } bool cmp(const Point& a, const Point& b) { return a.x==b.x ? a.y<b.y : a.x<b.x; } /* ============ Code implementation begins==========*/ // p, n: set and size of afferent points // ch: returned convex hull // Return value: convex hull size int getConvexhull(Point p[], int n, Point ch[]) { sort(p,p+n,cmp); int m=0; //Lower convex hull for(int i=0; i<n; ++i){ for(;m>1&&cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<0;--m) ; ch[m++]=p[i]; } //Upper convex hull int t=m; for(int i=n-2; i>=0; --i){ for(;m>t&&cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<0;--m) ; ch[m++]=p[i]; } // for(int i=0; i<m-1; i++) // printf("(%lf,%lf)\n",ch[i].x,ch[i].y); return m-1; //Number of points whose return value is convex hull } // p, n: Input convex hull and size // Return to the final answer double solve(Point p[], int n) { double ans = 0; for(int i=0; i<n; i++) p[i+n] = p[i]; //Copy a handy code for(int i=0; i<n; i++){ //int a=i,b=i+1; int a=1,b=1; //Rotating chuck method, enumerating with ij as diagonal line for(int j=i+1; j<n; j++){ while ( /*(a+1)%n!=j &&*/ cross(p[a+1]-p[i],p[j]-p[i])>cross(p[a]-p[i],p[j]-p[i]) ) a++; while ( /*(b+1)%n!=i &&*/ cross(p[j]-p[i],p[b+1]-p[i])>cross(p[j]-p[i],p[b]-p[i]) ) b++; ans = max(ans,cross(p[j]-p[i],p[b]-p[a])); } } return ans/2; } /* ============ End of Code Implementation==========*/ #define maxn 5000 Point p[2 * maxn + 10], ch[2 * maxn + 10]; int main() { int n; scanf("%d", &n); for (int i = 0; i < n; i++) p[i].read(); printf("%.3lf\n", solve(ch, getConvexhull(p, n, ch))); return 0; }