POJ2187Beauty Contest(任意点的最远距离 + 凸包)

题目链接

题意:就是给N个点的坐标,然后求任意两个点距离的平方最大的值

枚举超时。

当明白了 最远距离的两个点一定在凸包上,一切就好办了。求出凸包,然后枚举

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const double eps = 1e-6;
const int Max = 50000 + 10;
struct Node
{
    int x, y;
};
Node node[Max], ch[Max];
int cmp(Node tempx, Node tempy)
{
    if(tempx.y == tempy.y)
        return tempx.x < tempy.x;
    return tempx.y < tempy.y;
}
int xmult(Node p1, Node p2, Node p3)
{
    return (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);
}
int andrew(int n)
{
    int len, top = 1;
    ch[0] = node[0];
    ch[1] = node[1];
    for(int i = 2; i < n; i++)
    {
        while(top && xmult(ch[top - 1], ch[top], node[i]) <= 0)
            top--;
        ch[ ++top ] = node[i];
    }
    len = top;
    ch[ ++top ] = node[n - 2];
    for(int i = n - 3; i >= 0; i--)
    {
        while(len != top && xmult(ch[top - 1], ch[top], node[i]) <= 0)
            top--;
        ch[ ++top ] = node[i];
    }
    return top;
}
int dist(Node p1, Node p2)
{
    return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) ;
}
int get_max(int x, int y)
{
    if(x - y > 0)
        return x;
    return y;
}
int main()
{
    int n;
    while( scanf("%d", &n) != EOF) {
        for(int i = 0; i < n; i++)
            scanf("%d%d", &node[i].x, &node[i].y);
        sort(node, node + n, cmp);
        int top = andrew(n);

        int ans = 0;
        if(top > 2)
        {
            for(int i = 0; i < top; i++)
            {
                for(int j = 0; j < top; j++)
                {
                    ans = get_max(ans, dist(ch[i], ch[j]));
                }
            }
        }
        else
        {
            ans = dist(ch[0], ch[1]);
        }
        printf("%d\n", ans);
    }
    return 0;
}

 

posted @ 2016-03-18 15:27  zhaop  阅读(251)  评论(0编辑  收藏  举报