zoukankan      html  css  js  c++  java
  • Codeforces Round #113 (Div. 2) B. Polygons Andrew求凸包

    B. Polygons
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You've got another geometrical task. You are given two non-degenerate polygons A and B as vertex coordinates. Polygon A is strictly convex. Polygon B is an arbitrary polygon without any self-intersections and self-touches. The vertices of both polygons are given in the clockwise order. For each polygon no three consecutively following vertices are located on the same straight line.

    Your task is to check whether polygon B is positioned strictly inside polygon A. It means that any point of polygon B should be strictly inside polygon A. "Strictly" means that the vertex of polygon B cannot lie on the side of the polygon A.

    Input

    The first line contains the only integer n (3 ≤ n ≤ 105) — the number of vertices of polygon A. Then n lines contain pairs of integers xi, yi (|xi|, |yi| ≤ 109) — coordinates of the i-th vertex of polygon A. The vertices are given in the clockwise order.

    The next line contains a single integer m (3 ≤ m ≤ 2·104) — the number of vertices of polygon B. Then following m lines contain pairs of integers xj, yj (|xj|, |yj| ≤ 109) — the coordinates of the j-th vertex of polygon B. The vertices are given in the clockwise order.

    The coordinates of the polygon's vertices are separated by a single space. It is guaranteed that polygons A and B are non-degenerate, that polygon A is strictly convex, that polygon B has no self-intersections and self-touches and also for each polygon no three consecutively following vertices are located on the same straight line.

    Output

    Print on the only line the answer to the problem — if polygon B is strictly inside polygon A, print "YES", otherwise print "NO" (without the quotes).

    Examples
    input
    6
    -2 1
    0 3
    3 3
    4 1
    3 -2
    2 -2
    4
    0 1
    2 2
    3 1
    1 0
    output
    YES
    input
    5
    1 2
    4 2
    3 -3
    -2 -2
    -2 1
    4
    0 1
    1 2
    4 1
    2 -1
    output
    NO
    input
    5
    -1 2
    2 3
    4 1
    3 -2
    0 -3
    5
    1 0
    1 1
    3 1
    5 -1
    2 -1
    output
    NO

     题意:给你两个多边形A,B,已知A为凸多边形,问B是否全部在A内(严格);

    思路:将所有点合并,查找凸包,求是否B上的点都不在凸包上;

       因为有一个严格的要求,对于扫描法的凸包,不一定可以找到相同斜率的点;

       对于Andrew求凸包 ,只删除一些点,使得形成凸包;

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<bitset>
    #include<set>
    #include<map>
    #include<time.h>
    using namespace std;
    #define LL long long
    
    #define bug(x)  cout<<"bug"<<x<<endl;
    const int N=2e5+10,M=1e6+10,inf=1e9+10;
    const LL INF=1e18+10,mod=1e9+7;
    const double eps=(1e-8),pi=(4*atan(1.0));
    
    int sgn(double x)
    {
        if(fabs(x) < eps)return 0;
        if(x < 0)return -1;
        else return 1;
    }
    struct Point
    {
        double x,y;
        Point() {}
        Point(double _x,double _y)
        {
            x = _x;
            y = _y;
        }
        Point operator -(const Point &b)const
        {
            return Point(x - b.x,y - b.y);
        }
        //叉积
        double operator ^(const Point &b)const
        {
            return x*b.y - y*b.x;
        }
    //点积
        double operator *(const Point &b)const
        {
            return x*b.x + y*b.y;
        }
    //绕原点旋转角度B(弧度值),后x,y的变化
        void transXY(double B)
        {
            double tx = x,ty = y;
            x= tx*cos(B) - ty*sin(B);
            y= tx*sin(B) + ty*cos(B);
        }
        bool operator <(const Point p)const
        {
            if(x!=p.x)
            return x<p.x;
            return y<p.y;
        }
    };
    struct Line
    {
        Point s,e;
        Line() {}
        Line(Point _s,Point _e)
        {
            s = _s;
            e = _e;
        }
    //两直线相交求交点 //第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交 //只有第一个值为2时,交点才有意义
        pair<int,Point> operator &(const Line &b)const
        {
            Point res = s;
            if(sgn((s-e)^(b.s-b.e)) == 0)
            {
                if(sgn((s-b.e)^(b.s-b.e)) == 0) return make_pair(0,res);//重合
                else return make_pair(1,res);//平行
            }
            double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
            res.x += (e.x-s.x)*t;
            res.y += (e.y-s.y)*t;
            return make_pair(2,res);
        }
    };
    
    double dist(Point a,Point b)
    {
        return sqrt((a-b)*(a-b));
    }
    const int MAXN = 200010;
    Point listt[MAXN];
    int Stack[MAXN],top;
    
    int convexhull(int n) /*建立凸包*/
    {
        sort(listt,listt+n);
        int m=0;
        for(int i=0; i<n; i++) {
            while(m>1 && sgn((listt[Stack[m-1]]-listt[Stack[m-2]])^(listt[i]-listt[Stack[m-2]]))<0)
                m--;
            Stack[m++]=i;
        }
        int k=m;
        for(int i=n-2; i>=0; i--) {
            while(m>k && sgn((listt[Stack[m-1]]-listt[Stack[m-2]])^(listt[i]-listt[Stack[m-2]]))<0)
                m--;
            Stack[m++]=i;
        }
        if(n>1) m--;
        return m;
    }
    set<Point>s;
    int n,m;
    int FIND()
    {
        //for(int i=0;i<top;i++)
            //cout<<listt[Stack[i]].x<<" "<<listt[Stack[i]].y<<endl;
        for(int i=0;i<top;i++)
            if(s.find(listt[Stack[i]])!=s.end())return 1;
        return 0;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            double x,y;
            scanf("%lf%lf",&x,&y);
            listt[i]=Point(x,y);
        }
        scanf("%d",&m);
        for(int i=0;i<m;i++)
        {
            double x,y;
            scanf("%lf%lf",&x,&y);
            listt[i+n]=Point(x,y);
            s.insert(listt[i+n]);
        }
        top=convexhull(n+m);if(FIND())printf("NO
    ");
        else printf("YES
    ");
        return 0;
    }
  • 相关阅读:
    拓端tecdat|R语言投资组合优化求解器:条件约束最优化、非线性规划求解
    拓端tecdat|R语言多元时间序列滚动预测:ARIMA、回归、ARIMAX模型分析
    拓端tecdat|R语言聚类有效性:确定最优聚类数分析IRIS鸢尾花数据和可视化
    拓端tecdat|R语言k-means聚类、层次聚类、主成分(PCA)降维及可视化分析鸢尾花iris数据集
    【拓端tecdat】R语言用Hessian-free 、Nelder-Mead优化方法对数据进行参数估计
    springcloud之zuul网关服务并携带头信息转发token
    windows环境搭建Vue开发环境
    JVM之top+jstack分析cpu过高原因
    JVM调优之jstack找出最耗cpu的线程并定位代码
    用自顶向下、逐步细化的方法进行以下算法的设计: 1. 输出1900---2000年中是软黏的年份,符合下面两个条件之一的年份是闰年:
  • 原文地址:https://www.cnblogs.com/jhz033/p/7526576.html
Copyright © 2011-2022 走看看