POJ 2318 TOYS 利用叉积判断点在线段的那一侧

题意:给定n(<=5000)条线段,把一个矩阵分成了n+1分了,有m个玩具,放在为位置是(x,y)。现在要问第几个位置上有多少个玩具。

思路:叉积,线段p1p2,记玩具为p0,那么如果(p1p2 ^ p1p0) (记得不能搞反顺序,不同的),如果他们的叉积是小于0,那么就是在线段的左边,否则右边。所以,可以用二分找,如果在mid的左边,end=mid-1 否则begin=mid+1。结束的begin,就是第一条在点右边的线段

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 5000+20;
struct coor
{
    double x,y;
    coor(){}
    coor(double xx,double yy):x(xx),y(yy){}
    double operator ^(coor rhs) const //计算叉积(向量积)
    {
        return x*rhs.y - y*rhs.x;
    }
    coor operator -(coor rhs) const //坐标相减,a-b得到向量ba
    {
        return coor(x-rhs.x,y-rhs.y);
    }
    double operator *(coor rhs) const //数量积
    {
        return x*rhs.x + y*rhs.y;
    }
};
struct Line
{
    coor point1,point2;
    Line(){}
    Line(coor xx,coor yy):point1(xx),point2(yy){}
}a[maxn];
int n,m;
double xx1,yy1,xx2,yy2;
int cnt[maxn];
int calc (coor t)
{
    int begin=1,end=n;
    while(begin<=end)
    {
        int mid = (begin+end)/2;
        coor ff1 = a[mid].point2 - a[mid].point1; //point1是起点
        coor ff2 = t - a[mid].point1;
        if ((ff1^ff2) < 0)
        {
            end=mid-1;
        }
        else begin=mid+1;
    }
    return begin;
}
void work ()
{
    memset(cnt,0,sizeof cnt);
    for (int i=1;i<=n;++i)
    {
        double xxx1,xxx2;
        scanf("%lf%lf",&xxx1,&xxx2);
        a[i].point1.x=xxx1, a[i].point1.y=yy1;
        a[i].point2.x=xxx2, a[i].point2.y=yy2;
    }
    for (int i=1;i<=m;++i)
    {
        coor t;
        scanf("%lf%lf",&t.x,&t.y);
        cnt[calc(t)-1]++;
        //printf ("%d\n",calc(t));
    }
    for (int i=0;i<=n;++i)
    {
        printf ("%d: %d\n",i,cnt[i]);
    }
    return ;
}
int main()
{
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    //while(~scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y) && (a.x+a.y+b.x+b.y)) work();
    while(scanf("%d%d%lf%lf%lf%lf",&n,&m,&xx1,&yy1,&xx2,&yy2)!=EOF && n)
    {
        work();
        printf ("\n");
    }
    return 0;
}
View Code

 

posted on 2016-08-10 21:01  stupid_one  阅读(270)  评论(0编辑  收藏  举报

导航