原题
给出n个点,求得到凸包的面积
多边形面积显然很好求,就是邻边叉积之和/2。
问题在于怎么求凸包上有哪些点。凸包显然每个点都要在前两个点连线的左边(也就是逆时针位置),所以:
1、先确定一个最近的点当原点(最近:x最小的情况下y最小)
2、以该点为原点将其余点按极角排序(极角排序:约等同于将其他点按逆时针排列//因为极角啥的解释起来好麻烦的)
3、按排好的序来往凸包里添加(每次判断是不是满足粗体条件//且保证当前栈里有>=2个元素)
4、我们得到了凸包
//所以说凸包还是挺简单的啊~
#include<cstdio>
#include<algorithm>
#define N 50010
using namespace std;
int n,m,per[N];
struct point
{
int x,y;
point() {}
point(int _x,int _y) : x(_x),y(_y) {}
point operator - (const point &b) const
{
return point(b.x-x,b.y-y);
}
double operator * (const point &b) const
{
return x*b.y-b.x*y;
}
bool operator < (const point &b) const
{
if (x==b.x) return y<b.y;
return x<b.x;
}
int norm()
{
return x*x+y*y;
}
}p[N],q[N];
bool cmp(int i,int j)
{
int d=(p[i]-p[1])*(p[j]-p[1]);
if (d!=0) return d>0;
return (p[i]-p[1]).norm()<(p[j]-p[1]).norm();
}
void Graham()
{
int id=1;
for (int i=2;i<=n;i++)
if (p[i]<p[id]) id=i;
if (id!=1) swap(p[id],p[1]);
for (int i=1;i<=n;i++) per[i]=i;
sort(per+2,per+n+1,cmp);
q[++m]=p[1];
for (int i=2;i<=n;i++)
{
int j=per[i];
while (m>=2 && (p[j]-q[m-1])*(q[m]-q[m-1])>=0) m--;
q[++m]=p[j];
}
}
int nxt(int x) { return x==m?1:x+1; }
int Area(point x,point y,point z)
{
return (y-x)*(z-x);
}
int solve()
{
if (m==2) return (q[2]-q[1]).norm();
int ret=0;
q[m+1]=q[1];
for (int i=1,j=3;i<=m;i++)
{
while (nxt(j)!=i && Area(q[i],q[i+1],q[j])<=Area(q[i],q[i+1],q[j+1])) j=nxt(j);
ret=max(ret,(q[j]-q[i]).norm());
ret=max(ret,(q[j]-q[i+1]).norm());
}
return ret;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
Graham();
printf("%d",solve());
return 0;
}