POJ2318&AcWing 2983. 玩具

二分求答案,判断点是不是在边的左边

//POJ2318//AcWing 2983. 玩具  

//acwing2983


#include<iostream>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<cstring>
using namespace std;
int ans[5010];
long long  n,m;


struct Point 
{
    long long  x,y;
    Point(long long x=0,long long y=0):x(x),y(y){}
};
typedef Point Vector;

Point a[5010],b[5010];

Vector operator + (Vector A,Vector B)
{
    return Vector(A.x+B.x,A.y+B.y);
}

Vector operator - (Vector A,Vector B)
{
    return Vector(A.x-B.x,A.y-B.y);
}

Vector operator * (Vector A,double p)
{
    return Vector(A.x*p,A.y*p);
}

Vector operator / (Vector A,double p)
{
    return Vector(A.x/p,A.y/p);
}


long long cross(Vector A,Vector B)
{
    return A.x*B.y-A.y*B.x;
}

long long  area2(Point A,Point B,Point C)
{
    return cross(B-A,C-A);
}

int find(long long x,long long y)
{
    long long  l=0,r=n;
    while(l<r)
    {
        long long  mid=l+r>>1;
        if(area2(b[mid],a[mid],{x,y})>0)    r=mid;
        else l=mid+1;   
    }
    return r;

}

int main()
{
    int t,flag=1;
    while(scanf("%d",&n),n)
    {
        long long x1,y1,x2,y2;
        cin>>m>>x1>>y1>>x2>>y2;

        for(int i=0;i<n;i++)
        {
            long long  u,l;
            cin>>u>>l;
            a[i]={u,y1},b[i]={l,y2};
        }
        a[n]={x2,y1};b[n]={x2,y2};
        memset(ans,0,sizeof ans);

        while(m--)
        {
            long long  x,y;
            cin>>x>>y;
            ans[find(x,y)]++;
        }
        if(flag==1) flag=0;
        else    cout<<endl;
        for(int i=0;i<=n;i++)
        {
            cout<<i<<": "<<ans[i]<<endl;
        }
    }
    return 0;
}

本人作者:magicat
链接:https://www.acwing.com/activity/content/code/content/1966238/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。