POJ-2079 / HDU 3934___Triangle - the maximum area of the triangle rotary stuck +

Topic links: point I ah ╭ (╯ ^ ╰) ╮

Subject to the effect:

    Seeking the maximum area of ​​a triangle can be composed of the two-dimensional plane

Problem-solving ideas:

    The maximum triangle on the convex hull certainly
    assume three points i p q i,p,q , enum i i
    fixed i p i,p , rotate q q , is a readily available unimodal convex hull functions
    so is the answer in the first place a decrease
    and then fixed i q i,q , rotation p p , and then seek the answer to it again
    this time as a little triangle that is found i i maximum area of
    the time complexity: O ( n 2 ) O (n ^ 2)

    Why can this find? Read someone else's point is to continue to enumerate p p , according to such monotony q q point must only move forward, then why I was right? Gangster want to have to answer.

Core: rotary stuck

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
const double eps = 1e-6;
const int maxn = 1e5 + 10;
int n;
struct point {
	double x, y;
	point(){}
	point(double X, double Y){
		x = X, y = Y;
	}
	point operator - (const point &A) {
		return point(x-A.x, y-A.y);
	}
	bool operator < (const point &A)const {
		if(x == A.x) return y < A.y;
		return x < A.x;
	}
} a[maxn], pa[maxn];

int dcmp(double x){
	if(fabs(x) < eps) return 0;
	return x < 0 ? -1 : 1;
}
double cross(point A, point B) {	//	叉积
	return A.x*B.y - B.x*A.y;
}
double xmult(point a, point b, point c){
	return cross(a-c, b-c);
}

int andrew(point *P, int n, point *S) {	 //	P为点集合, A为凸包点
	sort(P, P+n);
	int tp = 0;
	for(int i=0; i<n; i++) {	//	下凸包 
		while(tp>1 && dcmp(cross(S[tp-1]-S[tp-2], P[i]-S[tp-2]))<=0) tp--;
		S[tp++] = P[i];
	}
	for(int i=n-2, k=tp; ~i; i--) {	//	上凸包 
		while(tp>k && dcmp(cross(S[tp-1]-S[tp-2], P[i]-S[tp-2]))<=0) tp--;
		S[tp++] = P[i];
	}
	return n > 1 ? tp - 1 : tp;
}

double rotating_calipers(int tp){
	int p = 1, q = 2;
	double ret = 0;
//	pa[++tp] = pa[0];
	for(int i=0; i<tp; i++){
		while(xmult(pa[i], pa[p], pa[(q+1)%tp]) > xmult(pa[i], pa[p], pa[q]))
			q = (q + 1) % tp;	//	i,p 固定,旋转 q 
		ret = max(ret, xmult(pa[i], pa[p], pa[q]));
		while(xmult(pa[i], pa[(p+1)%tp], pa[q]) > xmult(pa[i], pa[p], pa[q]))
			p = (p + 1) % tp;	//	i,q 固定,旋转 p 
		ret = max(ret, xmult(pa[i], pa[p], pa[q]));
	}
	return ret;
}

int main() {
    while(~scanf("%d", &n) && n!=-1){
		for(int i=0; i<n; i++) scanf("%lf%lf", &a[i].x, &a[i].y);
	    int tp = andrew(a, n, pa);
	    
		printf("%.2f\n", 0.5 * rotating_calipers(tp));	
	}
}
Published 221 original articles · won praise 220 · views 20000 +

Guess you like

Origin blog.csdn.net/Scar_Halo/article/details/102797106