欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Beauty Contest POJ2187

程序员文章站 2022-03-30 09:26:38
...

Beauty Contest

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 43065   Accepted: 13331

Description

Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest, earning the title 'Miss Cow World'. As a result, Bessie will make a tour of N (2 <= N <= 50,000) farms around the world in order to spread goodwill between farmers and their cows. For simplicity, the world will be represented as a two-dimensional plane, where each farm is located at a pair of integer coordinates (x,y), each having a value in the range -10,000 ... 10,000. No two farms share the same pair of coordinates. 

Even though Bessie travels directly in a straight line between pairs of farms, the distance between some farms can be quite large, so she wants to bring a suitcase full of hay with her so she has enough food to eat on each leg of her journey. Since Bessie refills her suitcase at every farm she visits, she wants to determine the maximum possible distance she might need to travel so she knows the size of suitcase she must bring.Help Bessie by computing the maximum distance among all pairs of farms. 
 

Input

* Line 1: A single integer, N 

* Lines 2..N+1: Two space-separated integers x and y specifying coordinate of each farm 

Output

* Line 1: A single integer that is the squared distance between the pair of farms that are farthest apart from each other. 

Sample Input

4
0 0
0 1
1 1
1 0

Sample Output

2

Hint

Farm 1 (0, 0) and farm 3 (1, 1) have the longest distance (square root of 2) 

题意:给出点集,求两点之间的最远距离

这道题就是传说中的旋转卡壳,先求出凸包,然后用旋转卡壳就能求出最长距离,其实就是凸包的直径。下边给出旋转的卡壳的大佬博客,一看就能看懂:http://www.cppblog.com/staryjy/archive/2009/11/19/101412.html

我写下自己的理解,选定凸包的一条边做底边,找以这个底边为三角形的最大面积,那个顶点就是底边平行线上的点,它与底边两个顶点之一的长度就是最远距离。在遍历时看来是n^2的,但是在遍历边的时候,最远点也在跟着移动,所以是n的复杂度。

不过我在这里重点说

while(top&&cross(a[i],p[top],p[top-1])>=0)    这个语句。

我在凸包模板里更新过了,这样写的凸包P数组只会记录顶点,不会记录在凸包边上的点,所以不能写稳定凸包,而写这道题很合适,直接两点间距离就是一条边。

while(top&&cross(p[top-1],p[top],a[i])<0)

这样的话会把凸包边上的点都记录下来,稳定凸包稳得一批,但是这个题我有点不明白,想了好久。

这样写的话没影响啊,只是点多了,跑得慢了,应该不影响结果。想了下在一条边上的点都一个顶点的距离怎么都不可能比两端点到定点的距离长,所以我没想到为啥会错,希望大佬们看到我的博客能告诉我为啥会wa

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
    int x,y;
}a[50005],p[50005];
int top,n;
int cross(node p0,node p1,node p2)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
int dis(node a,node b)
{
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
bool cmp(node p1,node p2)
{
    double z=cross(a[0],p1,p2);
    if(z>0||(z==0&&dis(a[0],p1)<dis(a[0],p2)))
        return 1;
    return 0;
}
void graham()
{
    int id=0;
    for(int i=0;i<n;i++)
    {
        if(a[i].y<a[id].y||(a[i].y==a[id].y&&a[i].x<a[id].x))
            id=i;
    }
    swap(a[0],a[id]);
    sort(a+1,a+n,cmp);
    top=1;
    p[0]=a[0];
    p[1]=a[1];
    for(int i=2;i<n;i++)
    {
        while(top&&cross(a[i],p[top],p[top-1])>=0)
            top--;
        top++;
        p[top]=a[i];
    }
}
int rc()
{
    int q=1,ans=0;
    p[top+1]=p[0];
    for(int i=0;i<=top;i++)
    {
        while(cross(p[i+1],p[q+1],p[i])>cross(p[i+1],p[q],p[i]))
            q=(q+1)%(top+1);
        ans=max(ans,max(dis(p[i],p[q]),dis(p[i+1],p[q])));
    }
    return ans;
}
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; i++)
        {
            scanf("%d%d",&a[i].x,&a[i].y);
        }
        graham();
        printf("%d\n",rc());
    }
}