HDU - 3629 Convex (calculating the number of convex quadrilateral)

Topic links: Click here

Title effect: analysis n points, can count the number of the convex quadrilateral composed of

Topic Analysis: The simple way is to enumerate four points, complexity n ^ 4, and subject to the n-700, is clearly not enough, since the number of points is relatively large, is the anti difficult, we consider combinatorics first n points can be composed of C (n, 4) a quadrilateral, we just subtract the number of concave quadrilateral is the answer, and we note the number of concave quadrilateral is ans, concave quadrilateral, put it another way, is to take three a triangle dots, asked how many points fall within a triangle, the three vertices of the triangle plus points falling inside the triangle, the four points can be composed of the concave quadrangle, specific calculation method is very clever, and uses a two-hand guarantee to find all the time complexity of concave quadrilateral in O (n), the point at which we enumerate as a central point in the first outer layer of O (n), which is relatively polar origin, carried out for the remaining n-1 points polar angle after sorting, the sorted interval can be determined by a double pointer to find the longest section of the triangular section which can satisfy all the points constituting the projections are triangular, note that this is a convex triangle, we denote the triangular projections The number is ans2, after all the good statistics triangular convex and concave triangular number is C (n-1,3) -ans2, and also the use of combinatorial mathematics being the anti difficult to find, so we can get the required all the information, and directly realized on the line, the time complexity of n * n * logn

Code:

#include<iostream>
#include<cstdio> 
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;
 
typedef long long LL;
 
const int inf=0x3f3f3f3f;

const int N=1e3+100;

const double eps = 1e-8;

const double pi = acos(-1.0);

int pos;

int sgn(double x){
    if(fabs(x) < eps)return 0;
    if(x < 0)return -1;
    else return 1;
}

struct Point{
    double x,y;
    Point(){}
    Point(double _x,double _y){
        x = _x;
        y = _y;
    }
    void input(){
        scanf("%lf%lf",&x,&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 hypot(x-p.x,y-p.y);
    }
}point[N];

LL C(LL n,LL m)
{
    if(m>n)
        return 0;
    if(m==1)
        return n;
    if(m==2)
        return n*(n-1)/2;
    if(m==3)
        return n*(n-1)*(n-2)/6;
    if(m==4)
        return n*(n-1)*(n-2)*(n-3)/24;
}

double xmult(Point p0,Point p1,Point p2)
{
    return (p1-p0)^(p2-p0);
}

bool cmp(Point a,Point b)
{
    double temp=xmult(point[pos],a,b);
    if(sgn(temp)==0)
        return a.distance(point[pos])<b.distance(point[pos]);
    return sgn(temp)>0;
}

int main()
{
//    freopen("input.txt","r",stdin);
//    ios::sync_with_stdio(false);
    int w;
    cin>>w;
    while(w--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            point[i].input();
        LL ans=0;
        for(int i=1;i<=n;i++)
        {
            vector<Point>node;
            for(int j=1;j<=n;j++)
                if(j!=i)
                    node.push_back(point[j]);
            pos=i;
            sort(node.begin(),node.end(),cmp);
            int k=1;
            LL ans2=0;
            for(int j=0;j<node.size();j++)
            {
                while(sgn(xmult(point[i],node[j],node[k%(n-1)]))>0)//注意这里,k需要转圈走的,所以要对n-1取模
                    k++;
                ans2+=C(k-j-1,2);
            }
            ans+=C(n-1,3)-ans2;
        }
        printf("%lld\n",C(n,4)-ans);
    }
    
    
 
 
 
 
 
 
 
    
    
    
    
    
    
    
    
    
    return 0;
}

 

Published 577 original articles · won praise 18 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_45458915/article/details/104100926