• 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
    ",calc(t));
        }
        for (int i=0;i<=n;++i)
        {
            printf ("%d: %d
    ",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 ("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    iOS设备后台播放音乐方法
    iOS 编译64位FFMPEG
    os8 location authorization 错误.
    IOS 使用新浪微博SDK
    IOS 解析歌词lrc
    IOS 通过button获取cell
    IOS 解析XML文档
    OC .(点)与->(箭头)用法区别
    黑苹果安装合集
    Hello,World
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/5758575.html
Copyright © 2020-2023  润新知