struct point
{
int x,y;
};
bool cmp(point a,point b)//自左到右,下到上
{
if(a.x!=b.x)
return a.x<b.x;
return a.y<b.y;
}
int cross(point a,point b,point c,point d)//叉乘
{
int x1=b.x-a.x;
int y1=b.y-a.y;
int x2=d.x-c.x;
int y2=d.y-c.y;
return x1*y2-x2*y1;
}
vector<point> convex_hull(vector<point> ve,int n)
{
sort(ve.begin(),ve.end(),cmp);
vector<point> down(n),up(n);//下侧链,上侧链
int k=0;
for(int i=0;i<n;i++)
{
while(k>1&&cross(down[k-1],down[k-2],ve[i],down[k-1])<=0)
k--;
down[k++]=ve[i];
}
down.resize(k);
k=0;
for(int i=n-1;i>=0;i--)
{
while(k>1&&cross(up[k-1],up[k-2],ve[i],up[k-1])<=0)
k--;
up[k++]=ve[i];
}
up.resize(k);
for(int i=1;;i++)
{
if(up[i].x==down[0].x&&up[i].y==down[0].y)
break;
down.push_back(up[i]);
}
return down;
}