POJ 2079 Triangle回転チャック


テーマの大意
平面上のいくつかの点を与えて、これらの点が構成できる最大面積の三角形を求めます.
構想
データの範囲は50 Wだが、POJのデータはずっと弱く、discussにはこう言う人がいる.
手動二分発見限界データ凸包上2596点RT好水のデータ
よし、残されたのはO(n 2)の時間内にこの問題を解決することだ.まず凸包を求め、その後、この大きな三角形のエッジを列挙し、別の頂点を列挙することができます.この過程はO(n 3)であることは明らかである.明らかに回転シェルを用いてO(n 2)まで最適化できるようになった.
CODE
#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
"
, RotatingCaliper()); } return 0; }