先放一道例题:
【题目描述】:
约翰农夫的母牛贝西,刚刚在牛选美比赛赢得第一名,赢得了“世界牛小姐”称号。为了传播善意,贝西将参观世界各地的农场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; }