先放一道例题:
【题目描述】:
约翰农夫的母牛贝西,刚刚在牛选美比赛赢得第一名,赢得了“世界牛小姐”称号。为了传播善意,贝西将参观世界各地的农场N(2 < = N < = 50000)。为简单起见,世界将被表示成一个二维平面,其中每个农场位于一对整数坐标(x,y),其值在-2000000~2000000范围内。没有两个农场共享相同的坐标。
尽管贝西旅行中走农场之间的直线,但一些农场之间的距离可能很大,所以她想带着一个手提箱,足够她装食物,即使最远的距离。她想确定旅行中最大可能的距离,这样她才能决定箱子的大小。帮助贝西计算所有成对的农场间最大距离。(最远点对)
【输入描述】:
第一行一个整数N
以下N行,每行两个整数,表示一个农场的坐标。
【输出描述】:
一行,一个整数表示最远一对农场距离的平方。
【样例输入】:
4
0 0
0 1
1 1
1 0
【样例输出】:
2
【时间限制、数据范围及描述】:
时间:1s 空间:256M
2 < = N < = 50000
我们可以将问题转化为标准的旋转卡壳解决的问题:将所有点做一遍凸包后求凸包的直径问题。
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const int Maxn=100005;
struct node{
ll x,y;
}a[Maxn],ans[Maxn];
ll n,k,lim,ansn;
node operator -(const node &a,const node &b){
node c;
c.x=a.x-b.x;c.y=a.y-b.y;
return c;
}
inline ll chaji(node a,node b){
return a.x*b.y-a.y*b.x;
}
inline ll mx(ll x,ll y){
return x>y?x:y;
}
inline ll dianji(node a,node b){
return a.x*b.x+a.y*b.y;
}
inline ll 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 x,node y){
if(x.y!=y.y)return x.y<y.y;
return x.x<y.x;
}
bool check(node o,node x,node y){
return chaji((x-o),(y-o))>0?0:1;
}
void convex(){
k=0;
sort(a+1,a+1+n,cmp);
for(ll i=1;i<=n;i++){
while(k>=2&&check(ans[k-1],ans[k],a[i]))k--;
ans[++k]=a[i];
}
lim=k;
for(ll i=n;i>=1;i--){
while(k>=lim+1&&check(ans[k-1],ans[k],a[i]))k--;
ans[++k]=a[i];
}
if(n>1)k--;
}
inline ll step(ll x){
x=x+1;
if(x>n)x=1;
return x;
}
void rotate(){
ll now=2,ansn=0;
scanf("%lld",&n);
for(ll i=1;i<=n;i++){
scanf("%lld%lld",&a[i].x,&a[i].y);
}
convex();
ans[n+1]=ans[1];
for(ll i=1;i<=k;i++){
while(chaji((ans[i+1]-ans[i]),(ans[now+1]-ans[i]))>chaji((ans[i+1]-ans[i]),(ans[now]-ans[i]))){now=step(now);}
ansn=mx(ansn,mx(dis(ans[i],ans[now]),dis(ans[i+1],ans[now+1])));
}
printf("%lld\n",ansn);
}
int main(){
rotate();
return 0;
}