zoukankan      html  css  js  c++  java
  • SGU 253 Theodore Roosevelt 快速判断点是否在凸包内

    http://acm.sgu.ru/problem.php?contest=0&problem=253

    题意简单易懂...给你n个点的凸包(经测试已经是极角序)...判断m个点是否在凸包内...数量>=k就输出YES

    46ms过的...貌似数据很水...但暴力判断每个点复杂度O(n*m)肯定T了...

    二分可以优化到O(mlogn)   -----该算法受到AC巨巨的启发:http://hi.baidu.com/aekdycoin/item/2d54f9c0fef55457ad00efd6

    把凸包分成n-2个三角形...然后二分点是否在这些三角形内即可...注意一下只有三个点的情况即可

    /********************* Template ************************/
    #include <set>
    #include <map>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <fstream>
    #include <numeric>
    #include <iomanip>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    
    #define EPS         1e-8
    #define MAXN        100005
    #define MOD         (int)1e9+7
    #define PI          acos(-1.0)
    #define INF         ((1LL)<<50)
    #define max(a,b)    ((a) > (b) ? (a) : (b))
    #define min(a,b)    ((a) < (b) ? (a) : (b))
    #define max3(a,b,c) (max(max(a,b),c))
    #define min3(a,b,c) (min(min(a,b),c))
    #define BUG         cout<<"BUG! "<<endl
    #define LINE        cout<<"------------------"<<endl
    #define L(t)        (t << 1)
    #define R(t)        (t << 1 | 1)
    #define Mid(a,b)    ((a + b) >> 1)
    #define lowbit(a)   (a & -a)
    #define FIN         freopen("in.txt","r",stdin)
    #pragma comment     (linker,"/STACK:102400000,102400000")
    
    // typedef long long LL;
    // typedef unsigned long long ULL;
    // typedef __int64 LL;
    // typedef unisigned __int64 ULL;
    // int gcd(int a,int b){ return b?gcd(b,a%b):a; }
    // int lcm(int a,int b){ return a*b/gcd(a,b); }
    
    /*********************   F   ************************/
    struct POINT{
        double x,y;
        POINT(double _x = 0, double _y = 0):x(_x),y(_y){};
        void show(){
            cout<<x<<" "<<y<<endl;
        }
    };
    POINT p[MAXN],wp[MAXN];
    double multiply(POINT sp,POINT ep,POINT op){ //叉积
        return (sp.x-op.x) * (ep.y-op.y) - (ep.x-op.x) * (sp.y-op.y);
    }
    bool onseg(POINT a,POINT s,POINT e){   // 判断点是否在线段上
        if(multiply(a,s,e) == 0 && a.x <= max(s.x,e.x) && a.x >= min(s.x,e.x)
           && a.y <= max(s.y,e.y) && a.y >= min(s.y,e.y))
            return true;
        return false;
    }
    bool inside(POINT pp,POINT sp,POINT ep,POINT op){ //判断点pp是否在三角形中(极角序)
        if(onseg(pp,sp,ep) || onseg(pp,sp,op) || onseg(pp,ep,op)) //如果在三角形上
            return true;
        if(multiply(sp,ep,pp) > 0 && multiply(ep,op,pp) > 0
           && multiply(sp,op,pp) < 0)  //如果在三角形内
               return true;
        return false;
    }
    bool bsearch(POINT a,int len){    //二分所构造的三角形
        int l = 1,r = len,m;
        while(l < r){
            m = (l + r) / 2;
            if(inside(a,p[0],p[m],p[m+1]) == true) return true;
            if(multiply(p[0],p[m],a) >= 0 && multiply(p[0],p[m+1],a) <= 0
                && multiply(p[m],p[m+1],a) < 0) return false;
            if(multiply(p[0],p[m],a) > 0 && multiply(p[0],p[m+1],a) > 0)
                l = m + 1;
            else r = m;
        }
        return false;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int n,m,k,tmp = 0,cnt = 0;
        scanf("%d%d%d",&n,&m,&k);
        for(int i = 0 ; i < n ; i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        p[n] = p[0];
        for(int i = 0 ; i < m ; i++){
            scanf("%lf%lf",&wp[i].x,&wp[i].y);
            if(bsearch(wp[i],n-1) == true) cnt++;
        }
        if(cnt >= k) printf("YES
    ");
        else printf("NO
    ");
        return 0;
    }
  • 相关阅读:
    图解表连接
    python 开发学习
    学习路线
    前端开发学习路径(完整版)
    JSON.parse()与JSON.stringify()的区别
    npm介绍和使用
    jQ
    BOM
    javaScript 内置对象-Array数组
    Ajax
  • 原文地址:https://www.cnblogs.com/Felix-F/p/3249568.html
Copyright © 2011-2022 走看看