zoukankan      html  css  js  c++  java
  • BZOJ 2564

    这道题挺像的,就不再多讲了。

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 10;
    typedef long long ll;
    
    struct Point {
        ll x, y;
        Point(){x=y=0;}
        Point(ll _x, ll _y):x(_x),y(_y){}
        Point operator-(const Point& _p) const{return Point(x-_p.x, y-_p.y);}
        Point operator+(const Point& _p) const{return Point(x+_p.x, y+_p.y);}
    
        ll operator*(const Point& _p) const{return x * _p.x + y * _p.y;}
        ll 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];
    
    ll cro(Point a, Point b, Point c) {return (b-a) ^ (c-a);}
    ll dot(Point a, Point b, Point c) {return (b-a) * (c-a);}
    
    int ConvexHull(Point *p, int n, Point* ch, int flag=1) {
        sort(p, p+n);      //先比较x坐标,再比较y坐标
        if (flag) n = unique(p, p+n)-p;
        int m = 0;
        for (int i = 0; i < n; ++ i) {
            while (m > 1 && cro(ch[m-2], ch[m-1], p[i]) < flag) -- m;
            ch[m++] = p[i];
        }
        int temp = m;
        for (int i = n - 2; i >= 0; -- i) {
            while (m > temp && cro(ch[m-2], ch[m-1], p[i]) < flag) -- m;
            ch[m++] = p[i];
        }
        return m -= (n > 1);
    }
    
    //点在线段上(包含端点),在为 1 ,不在为 0
    bool isPointOnSegment(Point P,Point A,Point B) {
        return cro(P, A, B) == 0 && dot(P, A, B) <= 0;  // 不包含端点时为 <0
    }
    //判断点在凸包内模板 O(logn)
    //凸包为逆时针
    //在边界,返回0,在内部,返回1,在外部,返回-1
    int check(Point A, Point*p, int n ) {
        if (isPointOnSegment(A, p[0], p[1])) return 0; // 包含端点
        if (isPointOnSegment(A, p[0], p[n-1])) return 0;
        int l = 1, r = n - 2, mid;
        while (l <= r) {
            mid = l + r >> 1;
            ll a1 = cro(p[0], p[mid], A);
            ll a2 = cro(p[0], p[mid+1], A);
            if (a1 >= 0 && a2 <= 0) {
                ll tmp = cro(p[mid], p[mid+1], A);
                if (tmp > 0)return 1;
                if (tmp == 0) return 0;
                return -1;
            }
            else if (a1 < 0) r = mid - 1;
            else l = mid + 1;
        }
        return -1;
    }
    
    int Minkowski(Point *A, int n, Point *B, int m, Point *C){
        int t = 0, x = 1, y = 1;
        C[t++] = A[0] + B[0];
        A[n] = A[0], B[m] = B[0];
        while (x <= n && y <= m)
            if ( ((A[x]-A[x-1]) ^ (B[y]-B[y-1])) > 0)
                C[t] = C[t-1] + A[x] - A[x-1], t ++, x ++;
            else
                C[t] = C[t-1] + B[y] - B[y-1], t ++, y ++;
        while (x <= n) C[t] = C[t-1] + A[x] - A[x-1], t ++, x ++;
        while (y <= m) C[t] = C[t-1] + B[y] - B[y-1], t ++, y ++;
        return t - 1;
    }
    
    ll Area(Point *p, int n) {
        p[n] = p[0];
        ll area = 0;
        for (int i = 1; i < n-1; ++ i) {
            area += cro(p[0], p[i], p[i+1]);
        }
        return area;
    }
    
    int main() {
    //    freopen("in.txt", "r", stdin);
    //    freopen("out.txt", "w", stdout);
        int n, m;
        scanf("%d%d", &n, &m);
    
        for (int i = 0; i < n; ++ i) A[i].input();
        for (int i = 0; i < m; ++ i) B[i].input();
        n = ConvexHull(A, n, C);
        memcpy(A, C, sizeof(Point)*(n));
        m = ConvexHull(B, m, C);
        memcpy(B, C, sizeof(Point)*(m));
    
        int p = Minkowski(A, n, B, m, C);
        printf("%lld
    ", Area(C, p));
    
        return 0;
    }
  • 相关阅读:
    JAVA代码中加了Try...Catch的执行顺序
    Java的注解机制——Spring自动装配的实现原理
    UWP蓝牙的例子
    MIT License
    Windows 运行时组件
    VS 的编译选项 build下的 platform target -- Any CPU和x86有什么影响?
    swfdump——从内存中提取swf的工具
    生成某一文件夹内文件清单(批量处理)
    统一用户认证和单点登录解决方案
    关键路径计算、总时差、自由时差
  • 原文地址:https://www.cnblogs.com/Vikyanite/p/14506487.html
Copyright © 2011-2022 走看看