zoukankan      html  css  js  c++  java
  • Saint John Festival UVA

    给出n个点。再给出q个询问。问是否在之前n个点组成的凸包内(不包括边上)

    算是存一个log查询是否在凸包内的模板吧。具体就是利用了叉积二分,叉积可以表示线段位置关系所以就可以。

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 10;
    typedef long long pType;
    int n, top;
    struct Point {
        pType x, y;
        Point(){x=y=0;}
        Point(pType _x, pType _y):x(_x),y(_y){}
        Point operator-(const Point& _p) const{return Point(x-_p.x, y-_p.y);}
    
        pType operator^(const Point& _p) const{return x*_p.y - y*_p.x;}
    
        void input(){scanf("%lld%lld", &x, &y);}
        /*sort*/
        bool operator==(const Point& _p) const{return x==_p.x&&y==_p.y;}
        bool operator<(const Point& _p) const{return x==_p.x ? y<_p.y : x<_p.x;}
    
    } A[N], B[N], C[N];
    
    pType cro(Point a, Point b, Point c) {return (b-a) ^ (c-a);}
    
    void getconvex(int flag) { /*0代表不严格1代表严格*/
        sort(A, A + n);
        n = flag ? unique(A, A + n) - A : n;
        top = 0;
        for (int i = 0; i < n; ++ i) {
            while (top > 1 && cro(B[top-2], B[top-1], A[i]) < flag) -- top;
            B[top++] = A[i];
        }
        int temp = top;
        for (int i = n - 2; i >= 0; -- i) {
            while (top > temp && cro(B[top-2], B[top-1], A[i]) < flag) -- top;
            B[top++] = A[i];
        }
        if (n > 1) top--;
    }
    
    //判断点在凸包内模板 O(logn)
    bool check(Point p) {
        int L = 1, R = top-1 -1;
        while (L <= R) {
            int mid = L + R >> 1;
            if (cro(B[0], B[mid], p) < 0)
                R = mid - 1;
            else {
                if(cro(B[0], B[mid+1], p) <= 0 && cro(B[mid], B[mid+1], p) >= 0)
                    return 1;
                L = mid + 1;
            }
        }
        return 0;
    }
    
    int main() {
    //    freopen("in.txt", "r", stdin);
    //    freopen("out.txt", "w", stdout);
        while (~scanf("%lld", &n) && n) {
            for (int i = 0; i < n; ++ i) {
                A[i].input();
            }
            getconvex(1);
            long long q, cnt = 0; scanf("%lld", &q);
            for (int i = 0; i < q; ++ i) {
                Point temp;
                temp.input();
                if (check(temp)) cnt++;
            }
            printf("%lld
    ", cnt);
    
        }
        return 0;
    }
    /*
    8
    3 4
    2 8
    5 4
    1 8
    4 7
    3 10
    11 2
    7 3
    6
    5 12
    3 7
    3 3
    4 5
    0 4
    2 6
    */
  • 相关阅读:
    POJ 2456 Aggressive cows
    POJ 1064 Cable master
    POJ 3723 Conscription
    左偏树
    tarjan模板
    [bzoj5017][Snoi2017]炸弹 tarjan缩点+线段树优化建图+拓扑
    [BZOJ4520][Cqoi2016]K远点对 kd-tree 优先队列
    [bzoj3218]a + b Problem 网络流+主席树优化建图
    #6034. 「雅礼集训 2017 Day2」线段游戏 李超树
    【UOJ UNR #1】火车管理 可持久化线段树
  • 原文地址:https://www.cnblogs.com/Vikyanite/p/14502221.html
Copyright © 2011-2022 走看看