题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5784
参考博客:https://blog.csdn.net/qq_45458915/article/details/104218091
这次分析的代码是利用了叉积进行了一个排序。目前开始学习的第一个几何类的问题。
代码的给的比较详细了。
这里总结一下叉积,点积的相关问题。
叉积 = 0,两个向量平行。
叉积 < 0,前后顺序为顺时针180度。
叉积 > 0,前后顺序为逆时针180度。
点积 = 0,等于90度。点积 > 0,小于90度。
点积 < 0,大于90度。
code:
const int nn = 2020; int sgn(double x){ if(x==0) return 0;//两向量平行 if(x<0) return -1;//前后顺序为顺时针顺序在180度内 return 1;//前后顺序为逆时针顺序在180度内 } struct Point{ ll x,y; Point(){} Point(double _x,double _y){ x = _x; y = _y; } void input(){ scanf("%lld%lld",&x,&y); } bool operator == (Point b)const{ return sgn(x-b.x) == 0 && sgn(y-b.y) == 0; } bool operator < (Point b)const{ return sgn(x-b.x)== 0?sgn(y-b.y)<0:x<b.x; } Point operator -(const Point &b)const{ return Point(x-b.x,y-b.y); } Point operator +(const Point &b)const{ return Point(x+b.x,y+b.y); } //叉积 外积 除去方向 double operator ^(const Point &b)const{ return x*b.y - y*b.x; } //点积 内积 double operator *(const Point &b)const{ return x*b.x + y*b.y; } //返回两点的距离 double distance(Point p){ return (x-p.x)*(x-p.x)+(y-p.y)*(y-p.y); } }p[nn],q[nn<<1]; int n; ll ans = 0,noans = 0; int getxx(Point& a){//求点的象限 if(a.x>0&&a.y>=0) return 1; if(a.x<=0&&a.y>0) return 2; if(a.x<0&&a.y<=0) return 3; if(a.x>=0&&a.y<0) return 4; } bool cmp(Point a,Point b){ if(getxx(a)!=getxx(b)){ return getxx(a)<getxx(b); } return sgn(a^b)>0; } void runit(int id){ for(int i=1,j=1;i<=n;i++){ if(i!=id){ q[j++] = p[i]-p[id];//形成了一个以 p[id] 点为原点的一个新点 } } sort(q+1,q+n,cmp);//点的横坐标系数 和 外积进行排序 for(int i=1;i<n;i++){ cout<<q[i].x<<' '<<q[i].y<<endl; } int tn = n-1; for(int i=1;i<=n;i++){ q[i+tn]=q[i]; } int j=1,k=1,l=1; for(int i=1;i<=tn;i++){//点积大于0 小于90 。 等于0 等于90 。 小于0 大于90度 while(j<=i+n&&(q[i]^q[j])==0&&(q[i]*q[j])>0) j++;//逆时针走完180度 直到平行的0度 k = max(k,j); while(k<=i+n&&(q[i]^q[k])>0&&(q[i]*q[k])>0) k++;//直到顺时针走完180度 l = max(l,k); while(l<=i+n&&(q[i]^q[l])>0) l++; ans+=k-j; noans+=l-k; } } int main() { //cin.ignore(numeric_limits<streamsize>::max(),'\n'); //ios_base::sync_with_stdio(0); cin.tie(0); //cout.tie(0); while(cin>>n){ ans = 0,noans = 0; for(int i=1;i<=n;i++) p[i].input(); for(int i=1;i<=n;i++) runit(i); cout<<(ans-noans*2)/3<<endl; } }