zoukankan      html  css  js  c++  java
  • TOYS

    题目大意:给你一个矩形的左上角和右下角的坐标,然后这个矩形有 N 个隔板分割成 N+1 个区域,下面有 M 组坐标,求出来每个区域包含的坐标数。

     
    分析:做的第一道计算几何题目....使用叉积判断方向,然后使用二分查询找到点所在的区域。
     
    代码如下:
    ============================================================================================================================
    #include<stdio.h>
    #include<math.h>
    using namespace std;
    
    const int MAXN = 5e3+7;
    const double PI = acos(-1.0);
    
    struct point
    {
        double x, y;
    
        point(int x=0, int y=0):x(x), y(y){}
    };
    struct Vector
    {
        point a, b;
    
        void InIt(point t1, point t2){a=t1, b=t2;}
        double operator * (const point &p) const
        {
            return (p.x-b.x)*(a.y-b.y) - (p.y-b.y)*(a.x-b.x);
        }
    };
    
    Vector line[MAXN];
    
    int Find(int N, point a)
    {
        int L=0, R=N;
    
        while(L <= R)
        {
            int Mid = (L+R) >> 1;
    
            if(line[Mid] * a < 0)
                R = Mid - 1;
            else
                L = Mid + 1;
        }
    
        return R;
    }
    
    int main()
    {
        int M, N;
        double x1, x2, y1, y2, ui, li;
    
        while(scanf("%d", &N) != EOF && N)
        {
            scanf("%d%lf%lf%lf%lf", &M, &x1, &y1, &x2, &y2);
    
            int ans[MAXN]={0};
    
            line[0].InIt(point(x1, y1), point(x1, y2));
            for(int i=1; i<=N; i++)
            {
                scanf("%lf%lf", &ui, &li);
                line[i].InIt(point(ui, y1), point(li, y2));
            }
            while(M--)
            {
                scanf("%lf%lf", &ui, &li);
                int i = Find(N, point(ui, li));
    
                ans[i] += 1;
            }
    
            for(int i=0; i<=N; i++)
                printf("%d: %d
    ", i, ans[i]);
            printf("
    ");
        }
    
        return 0;
    }

     重写...

    #include<math.h>
    #include<stdio.h>
    #include<vector>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const double EPS = 1e-5;
    const int maxn = 5005;
    
    int SIGN(const double &val)
    {///整数返回1,负数返回-1, 0返回0
        if(val > EPS)return 1;
        if(fabs(val) < EPS)return 0;
        return -1;
    }
    
    class Point
    {
    public:
        Point(double x, double y): x(x), y(y){}
        Point operator- (const Point& other)const
        {///重载减号
            return Point((x-other.x), (y - other.y));
        }
        double operator^(const Point& other)const
        {///重载异或,定义叉积的运算
            return (x*other.y) - (y*other.x);
        }
    public:
        double x, y;
    };
    
    class Segment
    {
    public:
        Segment(Point S, Point E) : S(S), E(E){}
        int Mul(Point& other) const
        {///用差乘判断点在线段的方向
            return SIGN( (E-S)^(other-S) );
        }
    public:
        Point S, E;
    };
    
    class SetSegment
    {///定义一个线段的集合,有很多线段构成
    public:
        void Insert(const Segment& other)
        {///插入一个线段
            segs.push_back(other);
        }
        unsigned int Find(Point p)
        {///查找点p靠近的最左边的线段的下标
            unsigned int L=0, R=segs.size()-1, M;
    
            while(L <= R)
            {
                M = (L+R) / 2;
                Segment tmp = segs[M];
                if(tmp.Mul(p) == -1)
                    R = M-1;
                else
                    L = M+1;
            }
    
            return R;
        }
    public:
        vector<Segment> segs;
    };
    int main()
    {
        int N, M;
        double x1, x2, y1, y2, Ui, Li;
    
        while(scanf("%d", &N) != EOF && N)
        {
            scanf("%d%lf%lf%lf%lf", &M, &x1, &y1, &x2, &y2);
    
            SetSegment ss;
    
            ss.Insert(Segment(Point(x1, y1), Point(x1, y2)));
            for(int i=0; i<N; i++)
            {
                scanf("%lf%lf", &Ui, &Li);
                ss.Insert(Segment(Point(Ui, y1), Point(Li, y2)));
            }
    
            int ans[maxn] = {0};
    
            while(M--)
            {
                scanf("%lf%lf", &x1, &y1);
    
                int index = ss.Find(Point(x1, y1));
                ans[index] += 1;
            }
    
            for(int i=0; i<=N; i++)
                printf("%d: %d
    ", i, ans[i]);
            printf("
    ");
        }
    
        return 0;
    }
  • 相关阅读:
    大话西游·『一生所爱』
    大话西游·『一生所爱』
    大话西游·『一生所爱』
    2013年终的总结
    2013年终的总结
    2013年终的总结
    Python高效编程技巧
    Python高效编程技巧
    Python高效编程技巧
    分分钟搞定Python之排序与列表
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4783452.html
Copyright © 2011-2022 走看看