poj 2187 Beauty Contest

来源:互联网 发布:同声传译软件 知乎 编辑:程序博客网 时间:2024/05/23 15:35

题目链接:点击打开链接

Beauty Contest
Time Limit: 3000MS
Memory Limit: 65536KTotal Submissions: 35352
Accepted: 10943

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

40 00 11 11 0

Sample Output

2

Hint

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

ps:第二次写凸包,水平超级烂,想看代码或Andrew算法的可以当例题看一下。

首先百度一下凸包知识,上面链接的博客的Andrew算法还是可以的,在刘汝佳的算法指南上说Andrew算法要比Graham算法快,且数值稳定性好,所以自己先了解的Andrew算法,在看了一下Graham算法,个人感觉Andrew算法相对好学,且简单易懂。

在这里我简单说一下自己在学习这个算法时的不容易搞懂的点:

就是在计算叉积时判断两个向量的左右关系,这个可以认为是一个定理,看了好多资料也没有具体的证明,我想就算是有证明也未必看懂。在刘汝佳的算法指南上关于叉积的算法有两种做法(1)若有向量v,w,则叉积为cross(v,w)=-cross(w,v);(2)坐标计算:若两个向量OA和OB的叉积等于xAyB-xByA.判断左右:顺着向量v看,如果w在左边,那么v和w的叉积大于0,否则小于0.(用手在坐标上画一下看看)。

对于这个题:

题目大意:有一个农场主,在世界各地有农场用坐标表示,他想去旅游围绕着他的农场。他从一个农场到另一个农场的路程中要携带零食,每次到达一个农场都要将他的箱子装满,但是为了不能饿着,他想知道要买最大有多大的箱子才能满足路程。也就是说计算最远的两个农场的距离多少。

ps: 当然了,首先想到的是对这n个点暴力,这肯定超时。这个化在了凸包的分类中,也就不难想到用凸包,凸包的概念就是将最远的点围起来了,所以直接多凸包上的点进行暴力就可以找到最大值了。

但是一开始我想节约时间就用上凸包和下凸包暴力,wa了,原来最远的点不一定是上下凸包相连。

<span style="font-size:18px;">#include <iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>using namespace std;struct point{    int x,y;}p[50005],ch[50005];bool cmp(point a,point b){    if(a.x!=b.x)return a.x<b.x;    else return a.y<b.y;}int judge(point a,point b,point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}long long ass(point a,point b){    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}int main(){    int n;    while(~scanf("%d",&n))    {        for(int i=0;i<n;i++)        {            scanf("%d%d",&p[i].x,&p[i].y);        }        sort(p,p+n,cmp);        int top=0;        for(int i=0;i<n;i++)        {            while(top>1&&judge(ch[top-2],ch[top-1],p[i])<=0)top--;            ch[top++]=p[i];        }        int k=top;        for(int i=n-2;i>=0;i--)        {            while(top>k&&judge(ch[top-2],ch[top-1],p[i])<=0)top--;            ch[top++]=p[i];        }        if(n>1)top--;        long long mx=-1,num;        for(int i=0;i<top;i++)        {            for(int j=0;j<top;j++)            {                num=ass(ch[i],ch[j]);                if(num>mx)mx=num;            }        }        printf("%lld\n",mx);    }    return 0;}</span>


0 0