POJ

来源:互联网 发布:淘宝保证金交多少 编辑:程序博客网 时间:2024/05/29 03:02

题目链接:http://poj.org/problem?id=2187

题目大意:若干个点,求两个点之间的最远距离

解题思路:最远的距离一定是凸包上的点之间的最远距离,而对于凸包上的点的最远距离,可以用旋转卡壳求解

AC代码:

#include<cstdio>#include<algorithm>using namespace std;const int MAXN = 50000 + 5;struct Point{    int x, y;}polygon[MAXN],ham[MAXN];int stack[MAXN];int getCross(Point p1, Point p2, Point p){    return (p1.x - p.x)*(p2.y - p.y) - (p2.x - p.x)*(p1.y - p.y);}int getDis(Point a, Point b){    return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);}bool myCmp(Point a, Point b){    int flag = getCross(a, b, polygon[0]);    if (flag > 0) return true;    if (flag == 0 && getDis(a, polygon[0]) - getDis(b, polygon[0]) < 0)        return true;    return false;}int toGraham(Point polygon[],int n){    if (n == 1)    {        stack[0] = 0;        return 1;    }    int pos = 0;    for (int i = 1;i < n;++i)    {        if (polygon[pos].y > polygon[i].y)            pos = i;        else if (polygon[pos].y == polygon[i].y&&polygon[pos].x > polygon[i].x)            pos = i;    }    swap(polygon[0], polygon[pos]);    sort(polygon + 1, polygon + n, myCmp);    int top = 2;    stack[0] = 0, stack[1] = 1;    for (int i = 2;i < n;i++)    {        while (top&&getCross(polygon[i], polygon[stack[top - 2]], polygon[stack[top - 1]]) <= 0) top--;        stack[top++] = i;    }    return top;}int rotateCaliper(Point p[],int n){    int mxx = 0;    int t = 1;    for (int i = 0;i < n;i++)    {        while (abs(getCross(p[t], p[(i + 1) % n], p[i])) < abs(getCross(p[(t + 1) % n], p[(i + 1) % n], p[i])))            t = (t + 1) % n;        mxx = max(mxx, getDis(p[(i + 1) % n], p[(t + 1) % n]));        mxx = max(mxx, getDis(p[i], p[t]));    }    return mxx;}int main(){    int n;scanf("%d", &n);    for (int i = 0;i < n;i++)        scanf("%d%d", &polygon[i].x, &polygon[i].y);    int tot=toGraham(polygon, n);    for (int i = 0;i < tot;i++)        ham[i] = polygon[stack[i]];    printf("%d\n", rotateCaliper(ham, tot));    return 0;}