Small Brown enclosure convex hull rotary chuck

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;
}

Posted by russellcox77777 on Wed, 02 Oct 2019 08:24:23 -0700