您的位置:首页 > 其它

【POJ 2187】Beauty Contest(凸包直径、旋转卡壳)

2016-07-31 03:54 591 查看
给定点集的最远两点的距离。

先用graham求凸包。旋(xuán)转(zhuàn)卡(qiǎ)壳(ké)求凸包直径。

ps:旋转卡壳算法的典型运用

http://blog.csdn.net/hanchengxi/article/details/8639476

#include <cstdio>
#include <cmath>
#include <algorithm>
#define sqr(x) (x)*(x)
#define  N 50001
using namespace std;
struct P{
int x,y;
}p
,q
;
int n,ans,top;
int dis2(P a,P b){
return sqr(a.x-b.x)+sqr(a.y-b.y);
}
int xmult(P a,P b,P o){
return (a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x);
}
int cmp(P a,P b){
return xmult(a,b,p[1])>0||xmult(a,b,p[1])==0&&dis2(a,p[1])<dis2(b,p[1]);
}
void graham(){
sort(p+2,p+1+n,cmp);
q[1]=p[1],q[2]=p[2];
top=2;
for(int i=3;i<=n;i++){
while(xmult(q[top],p[i],q[top-1])<=0&&top>1)top--;
q[++top]=p[i];
}
}
void qiake(){
q[top+1]=q[1];
int now=2;
for(int i=1;i<=top;i++){
while(xmult(q[i+1],q[now],q[i])<xmult(q[i+1],q[now+1],q[i]))
{
now++;
if(now>top)now=1;
}
ans=max(ans,dis2(q[now],q[i]));
}
}
int main() {
scanf("%d",&n);
int t=1;
for(int i=1;i<=n;i++){
scanf("%d%d",&p[i].x,&p[i].y);
if(p[t].y>p[i].y||p[t].y==p[i].y&&p[t].x>p[i].x)t=i;
}
swap(p[1],p[t]);
graham();
qiake();
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: