给出平面上的一些点,求这些点能够组成的最大面积三角形。
虽然数据范围有50W,但是POJ上的数据一向很弱,discuss中居然有人这样说:
手动二分发现极限数据凸包上有2596个点
RT
好水的数据
好吧,留给我们的就剩下
首先先求出凸包,之后可以枚举这个大三角形的一条边,然后枚举另一个顶点。很显然这个过程是
#define _CRT_SECURE_NO_WARNINGS
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 50010
using namespace std;
struct Point{
double x,y;
Point(double _, double __):x(_),y(__) {}
Point() {}
bool operator <(const Point &a)const {
if(x == a.x) return y > a.y;
return x < a.x;
}
Point operator +(const Point &a)const {
return Point(x + a.x,y + a.y);
}
Point operator -(const Point &a)const {
return Point(x - a.x,y - a.y);
}
Point operator *(double a)const {
return Point(x * a,y * a);
}
void Read() {
scanf("%lf%lf", &x, &y);
}
}point[MAX], stack[MAX];
int top;
inline double Cross(const Point &p1,const Point &p2)
{
return p1.x * p2.y - p1.y * p2.x;
}
inline void Add(const Point &p,int bottom)
{
while(top > bottom && Cross(p - stack[top - 1], stack[top] - stack[top - 1]) >= 0)
--top;
stack[++top] = p;
}
int points;
inline double RotatingCaliper()
{
double re = .0;
for(int i = 1; i < top; ++i) {
int p = i + 1;
for(int j = i + 1; j <= top; ++j) {
while(fabs(Cross(stack[j] - stack[i], stack[(p + 1) % top] - stack[j])) > fabs(Cross(stack[j] - stack[i], stack[p] - stack[j])))
p = (p + 1) % top;
re = max(re, fabs(Cross(stack[j] - stack[i], stack[p] - stack[j])));
}
}
return re / 2;
}
int main()
{
while(scanf("%d", &points), points + 1) {
for(int i = 1; i <= points; ++i)
point[i].Read();
sort(point + 1, point + points + 1);
top = 0;
stack[++top] = point[1];
for(int i = 2; i <= points; ++i)
Add(point[i], 1);
int temp = top;
for(int i = points - 1; i; --i)
Add(point[i], temp);
--top;
stack[0] = stack[top];
printf("%.2lf\n", RotatingCaliper());
}
return 0;
}
原文地址:http://blog.csdn.net/jiangyuze831/article/details/44082147