poj2079(*凸包內最大三角形面積)

/*
translation:
	給出一組點,從這些點裏面選擇三個點構成三角形。求這個三角形面積最大是多少?
solution:
	凸包
	很容易想到三角形的三個點肯定在凸包上面,但是關鍵怎麼找出來三個點。一一枚舉肯定超時。
note:
	* 如果固定一條邊的話,那麼枚舉剩下的一個點,在枚舉過程中面積肯定有達到極大值後又減小。根據這一特性,可以先固定
	  一點i,然後讓另外兩點a,b不斷旋轉來找三角形面積最大值(a,b事先設定成是點1和點2)。具體步驟如下:
	  1.枚舉i後就將i固定,旋轉a,直到找到三角形的最大值。同時更新答案。
	  2.旋轉b,直到找到此時三角形的最大值。同時更新答案。此時即找到三角形一點爲i時的最大面積。
	  3.枚舉下一個i,重複1,2步驟。
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>

using namespace std;
const int maxn = 50000 + 5;

struct Point
{
    double x, y;
    Point(){}
    Point(double x_, double y_):x(x_),y(y_){}
} p[maxn], ch[maxn];
typedef Point Vector;
int n;

Vector operator + (Vector a, Vector b)  { return Vector(a.x + b.x, a.y + b.y); }
Vector operator - (Point a, Point b)    { return Point(a.x - b.x, a.y - b.y); }
Vector operator * (Vector a, double p)  { return Vector(a.x * p, a.y * p); }
Vector operator / (Vector a, double p)  { return Vector(a.x / p, a.y / p); }

bool operator < (const Point& a, const Point& b)
{
    return a.x < b.x || (a.x == b.x && a.y < b.y);
}

const double eps = 1e-10;
int dcmp(double x)
{
    if(fabs(x) < eps)    return 0;
    else                return x < 0 ? -1 : 1;
}

bool operator == (const Point& a, const Point& b)
{
    return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}

double dot(Vector a, Vector b)      { return a.x * b.x + a.y * b.y; }
double length(Vector a)             { return sqrt(dot(a, a)); }
double angle(Vector a, Vector b)    { return acos(dot(a, b) / length(a) / length(b)); }
double angle(Vector v)              { return atan2(v.y, v.x); }
double cross(Vector a, Vector b)    { return a.x * b.y - b.x * a.y; }
double dist(Point p1,Point p2)      { return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); }

int convexHull(Point* p, int n, Point* ch)
{
	sort(p, p + n);
	int m = 0;
	for(int i = 0; i < n; i++) {
		while(m > 1 && cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) <= 0)	m--;
		ch[m++] = p[i];
	}
	int k = m;
	for(int i = n-2; i >= 0; i--) {
		while(m > k && cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) <= 0)	m--;
		ch[m++] = p[i];
	}
	if(n > 1)	m--;
	return m;
}

double area(Point a,Point b,Point c){
    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}

double solve()
{
	int m = convexHull(p, n, ch);
	//ch[++m] = ch[0];
	int a = 1, b = 2;
	double res = 0;
	for(int i = 0; i < m; i++) {
		while(area(ch[i], ch[a], ch[(b+1)%m]) > area(ch[i], ch[a], ch[b]))
			b = (b + 1) % m;
		res = max(res, area(ch[i], ch[a], ch[b]) / 2.0);
		while(area(ch[i], ch[(a+1)%m], ch[b]) > area(ch[i], ch[a], ch[b]))
			a = (a + 1) % m;
		res = max(res, area(ch[i], ch[a], ch[b]) / 2.0);
	}
	return res;
}

int main()
{
	//freopen("in.txt", "r", stdin);
    while(~scanf("%d", &n) && n != -1) {
		for(int i = 0; i < n; i++) {
			scanf("%lf%lf", &p[i].x, &p[i].y);
		}

		printf("%.2f\n", solve());
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章