Beauty Contest--POJ 2187
1、题目类型:凸包。
2、解题思路:(1)建立点集map[][],为了避免负数用ADD=10000进行的处理;(2)Graham法求解凸包,中间对于斜率的排序用的是STL的sort();(3)求解凸包中点间的最大距离。
3、注意事项:凸包处理过程中,考虑是一条直线上面的情况,即使在一条直线不是一个凸包。
4、实现方法:
#include<iostream>
#include<algorithm>
#define ADD 10000
using namespace std;
struct Point
{
int x,y;
};
int n;
Point map[50010];
Point S[50010];
//求斜率
float XieLv(Point p1,Point p2,Point p0)
{
return ((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}
//两点距离的平方
int Dis(Point p1,Point p2)
{
return ((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
int cmp(Point p1,Point p2)
{
if(XieLv(p1,p2,map[0])>0)
return 1;
if((XieLv(p1,p2,map[0])==0&&
Dis(p1,map[0])-Dis(p2,map[0])<0))
return 1;
return 0;
}
//Graham法求凸包,返回凸包中点数
int Graham()
{
int i,top,tmp=0;
for(i=1;i<n;i++)
{
if((map[i].y<map[tmp].y)||(map[i].y==map[tmp].y&&map[i].x<map[tmp].x))
tmp=i;
}
Point p=map[tmp];
map[tmp]=map[0];
map[0]=p;
sort(map+1,map+n,cmp);
top=2;
S[0]=map[0];
S[1]=map[1];
S[2]=map[2];
for(i=3;i<n;i++)
{
while(XieLv(map[i],S[top],S[top-1])>0)
top--;
S[++top]=map[i];
}
return top+1;
}
int main()
{
int i,j,len,ans=0;
cin>>n;
for(i=0;i<n;i++)
{
scanf("%d %d",&map[i].x,&map[i].y);
map[i].x+=ADD;
map[i].y+=ADD;
}
len=Graham();
for(i=0;i<len;i++)
for(j=i+1;j<len;j++)
ans=ans>Dis(S[i],S[j])?ans:Dis(S[i],S[j]);
cout<<ans<<endl;
return 0;
}