将所有点按从左至右顺序排序,然后将所有点先从左到右扫描再从右到左扫描,逐渐将凸包轮廓“勾勒”出来
(凸包轮廓满足,轮廓上连续的三个点按先后顺序给出的话呈逆时针方向)
最后删去一个重复的起(终)点
#include<bits/stdc++.h> using namespace std; struct point { double x,y; point operator -(const point& rhs)const { point ret; ret.x=x-rhs.x; ret.y=y-rhs.y; return ret; } double operator *(const point& rhs)const//叉乘 { return x*rhs.y-y*rhs.x; } bool operator <(const point& rhs)const { return x<rhs.x||x==rhs.x&&y<rhs.y; } }p[],s[]; bool ok(point A,point B,point C) //判断ABC是否是按逆时针顺序给出 { ; } int main() { int T;scanf("%d",&T); while(T--) { int n; scanf("%d",&n); ;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); sort(p,p+n); ; ;i<n;i++) //求下凸包 { && !ok(s[top-],s[top-],p[i])) top--; s[top++]=p[i]; } ; ;i>=;i--) //求上凸包 { && !ok(s[top-],s[top-],p[i])) top--; s[top++]=p[i]; } --top; // 首尾点相同,故舍去 sort(s,s+top); ;i<top;i++) printf("%.0lf %.0lf\n",s[i].x,s[i].y); } }