【POJ 2187】 Beauty Contest (凸包-Graham扫描算法)

【POJ 2187】 Beauty Contest (凸包-Graham扫描算法)

找平面最远点对 数据很大 用暴力会T..我感觉……

扫描出个凸包 然后枚举凸包上的点即可 没坑 int也可过 注意重边跟共线就行 代码下附赠几组数据


代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <stack>
#include <algorithm>
#define ll long long

using namespace std;

typedef struct Line Line;
typedef struct Point Point;

ll mx,my;

struct Point
{
    ll x,y;
    ll operator - (const Point a)const
    {
        return (x-a.x)*(x-a.x)+(y-a.y)*(y-a.y);
    }

    bool operator < (const Point a)const
    {
        if(x == mx && y == my) return false;
        if(a.x == mx && a.y == my) return true;
        if((x-mx)*(a.y-my) - (y-my)*(a.x-mx) == 0) return (x-mx)*(x-mx)+(y-my)*(y-my) < (a.x-mx)*(a.x-mx)+(a.y-my)*(a.y-my);
        return (x-mx)*(a.y-my) - (y-my)*(a.x-mx) > 0;
    }
};

struct Line
{
    ll x,y;
    bool operator > (const Line a)const//顺时针
    {
        return x*a.y - y*a.x > 0;
    }
};

Point pt[50000];
stack <Point> s;
vector <Point> tmp;

void Read(int &n)//输入并进行极角排序
{
    scanf("%d",&n);
    int mm = 0;
    for(int i = 0; i < n; ++i)
    {
        scanf("%lld %lld",&pt[i].x,&pt[i].y);
        if(pt[i].x < pt[mm].x || (pt[i].x == pt[mm].x && pt[i].y < pt[mm].y))
            mm = i;
    }
    mx = pt[mm].x;
    my = pt[mm].y;
    sort(pt,pt+n);
}

void SetTb(int n)//建凸包
{
    Point p1,p2;
    Line l1,l2;
    s.push(Point{mx,my});
    s.push(pt[0]);
    for(int i = 1; i < n; ++i)
    {
        if(pt[i].x == mx && pt[i].y == my) break;
        p2 = s.top();
        s.pop();
        while(!s.empty())
        {
            p1 = s.top();
            s.pop();
            l1.x = p2.x - p1.x;
            l1.y = p2.y - p1.y;
            l2.x = pt[i].x - p1.x;
            l2.y = pt[i].y - p1.y;
            if(l1 > l2)
            {
                s.push(p1);
                break;
            }
            p2 = p1;
        }
        s.push(p2);
        s.push(pt[i]);
    }
}

ll MaxLength()//从栈中不断出栈找最远点距
{
    int i;
    ll Maxlen = 0;
    while(!s.empty())
    {
        Point tp;
        tp = s.top();
        s.pop();
        for(i = 0; i < tmp.size(); ++i)
        {
            Maxlen = max(Maxlen,tp-tmp[i]);
        }
        tmp.push_back(tp);
    }
    return Maxlen;
}

int main()
{
    int n;
    Read(n);
    SetTb(n);
    printf("%lld\n",MaxLength());
    return 0;
}

/*
Input:
9
200 400
300 400
300 300
400 300
400 400
500 400
500 200
350 200
200 200
4
0 0
0 1
0 1
0 0
2
0 0
0 1
Output:
130000
1
1
*/


你可能感兴趣的:(【POJ 2187】 Beauty Contest (凸包-Graham扫描算法))