飞花的传送门
TimeLimit: 1000ms Memory limit: 65536K
题目描述
飞花壕最近手头比较宽裕,所以想买两个传送门来代步(夏天太热,实在是懒得走路)。平面上有N个传送门,飞花壕想要挑两个距离最远的传送门带回家(距离为欧几里得距离,即两点之间直线距离)。
请你帮他算一算他所挑选的最远的两个传送门有多远。
输入
多组输入。
对于每组输入,第一行输入一个整数N(2<= N <= 50000),接下来从第2行到第N+1行,每行两个整数(Xi,Yi),代表第i个传送门的坐标(-1000000<= Xi , Yi <= 1000000)。
数据为随机生成。
输出
输出一个整数,代表飞花壕要挑选的两个传送门的距离的平方。
示例输入
4
00
01
11
10
示例输出
2
/*
校赛的一道题,开始不知道什么意思,比完后听他们说是凸包;
*/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long LL;
const int Max=51000;
struct node
{
LL x;
LL y;
}point[Max],AA[Max];
LL py,px;
bool cmp(node a,node b)
{
return atan2(a.y-py, a.x-px) < atan2(b.y-py, b.x-px);
}
double compare(double x1,double y1,double x2,double y2)
{
return x1*y2-x2*y1;
}
double compare(int a,int b,int c)
{
return compare(AA[b].x-AA[a].x,AA[b].y-AA[a].y,point[c].x-AA[a].x,point[c].y-AA[a].y);
}
LL dis(int a,int b)
{
return (AA[a].x-AA[b].x)*(AA[a].x-AA[b].x)+(AA[a].y-AA[b].y)*(AA[a].y-AA[b].y);
}
int main()
{
int n;
int top;
LL sum;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
{
scanf("%lld %lld",&point[i].x,&point[i].y);
if(i)
{
if(py>point[i].y)
{
py=point[i].y;
px=point[i].x;
}
else if(py==point[i].y&&px>point[i].x)
{
px=point[i].x;
}
}
else
{
py=point[i].y;
px=point[i].x;
}
}
sort(point ,point+n, cmp);
AA[0]=point[0];
AA[1]=point[1];
top=1;
for(int i=2;i<n;)
{
if(top&&compare(top-1,top,i)<=0)
{
top--;
}
else
{
AA[++top]=point[i++];
}
}
while(compare(top-1,top,0)<=0)
{
top--;
}
sum=0;
LL ans;
for(int i=0;i<=top;i++)
{
for(int j=i+1;j<=top;j++)
{
ans=dis(i,j);
if(sum<ans)
{
sum=ans;
}
}
}
printf("%lld\n",sum);
}
return 0;
}