POJ 2079 Triangle(凸包+旋转卡壳求最大三角形面积)

来源:互联网 发布:淘宝网店押金 编辑:程序博客网 时间:2024/05/22 15:15
Triangle
Time Limit: 3000MS Memory Limit: 30000KTotal Submissions: 8730 Accepted: 2592

Description

Given n distinct points on a plane, your task is to find the triangle that have the maximum area, whose vertices are from the given points.

Input

The input consists of several test cases. The first line of each test case contains an integer n, indicating the number of points on the plane. Each of the following n lines contains two integer xi and yi, indicating the ith points. The last line of the input is an integer −1, indicating the end of input, which should not be processed. You may assume that 1 <= n <= 50000 and −104 <= xi, yi <= 104 for all i = 1 . . . n.

Output

For each test case, print a line containing the maximum area, which contains two digits after the decimal point. You may assume that there is always an answer which is greater than zero.

Sample Input

33 42 62 752 63 92 08 06 5-1

Sample Output

0.5027.00
求平面上n个点中的三个点组成的三角形面积最大,交C++一直TLE ,求解。。。。
#include <iostream>   //G++#include <cstdio>#include <cstring>#include <stdlib.h>#include <algorithm>#include <queue>#include <map>#include <cmath>#define inf 0x3f3f3f3f#define N 50010using namespace std;struct Point{    int x, y;    int dis;} pt[N], stack[N],p0;int top, tot;int Dis(int x1 ,int y1, int x2, int y2){    return  (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);}int Cmp_PolarAngel(struct Point p1, struct Point p2, struct Point pb){    int delta = (p1.x - pb.x) * (p2.y - pb.y) - (p2.x - pb.x) * (p1.y - pb.y);    if(delta < 0) return 1;    if(delta == 0) return 0;    return -1;}bool Is_LeftTurn(struct Point p3, struct Point p2, struct Point p1){    int type = Cmp_PolarAngel(p3, p1, p2);    if(type < 0) return true;    return false;}int cmp(const void *p1, const void *p2){    struct Point *a1 = (struct Point*) p1;    struct Point *a2 = (struct Point*) p2;    int type = Cmp_PolarAngel(*a1, *a2, p0);    if(type < 0) return -1;    if(type == 0)    {        if(a1->dis < a2->dis) return -1;        if(a1->dis == a2->dis) return 0;        return 1;    }    return 1;}void Hull(int n){    int k;    p0.x = inf;    p0.y = inf;    for(int i = 0; i < n; i++)    {        scanf("%d%d", &pt[i].x, &pt[i].y);        if(pt[i].y < p0.y )        {            p0.y = pt[i].y;            p0.x = pt[i].x;            k = i;        }        else if( pt[i].y == p0.y )        {            if(pt[i].x < p0.x)            {                p0.x = pt[i].x;                k = i;            }        }    }    pt[k] = pt[0];    pt[0] = p0;    for(int i = 1; i < n; i++)    {        pt[i].dis = Dis(pt[i].x, pt[i].y, p0.x, p0.y);    }    qsort(pt+1, n-1, sizeof(struct Point), cmp);    tot = 1;    for(int i = 2; i < n; i++)    {        if(Cmp_PolarAngel(pt[i], pt[i-1], p0))            pt[tot++] = pt[i-1];    }    pt[tot++] = pt[n-1];    top = 1;    stack[0] = pt[0];    stack[1] = pt[1];    for(int i = 2; i < tot; i++)    {        while(top >= 1 && Is_LeftTurn(pt[i], stack[top], stack[top - 1]) == false )        {            top--;        }        stack[++top] = pt[i];    }}double Area(struct Point p1, struct Point p2, struct Point p3){    return abs(((double)p1.x -(double)p3.x) * ((double)p2.y - (double)p3.y) -               ((double)p2.x - (double)p3.x) * ((double)p1.y - (double)p3.y) );}void Rotate(struct Point *ch, int n){    if(n<3)    {        printf("0.00\n");        return ;    }    int j, k;    double ans=0;    ch[n] = ch[0];    for(int i = 0; i < n; i++)    {        j = (i + 1) % n;        k = (j + 1) % n;        while( j != k && k != i)        {            while(Area(ch[i], ch[j], ch[k+1]) > Area(ch[i], ch[j], ch[k]))            {                k = (k + 1) % n;            }            ans = max(ans, Area(ch[i], ch[j], ch[k]));           j = (j + 1) %n ;        }    }    printf("%.2f\n",ans*0.5);     //%.2lf 会WA,看了[Discuss]才知道,why?}int main(){    int n;    while(~scanf("%d", &n))    {      if(n==-1) break;        Hull(n);        Rotate(stack , top + 1);    }    return 0;}


0 0
原创粉丝点击