题目链接: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;
	}
}