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 ≤ 10^5) — the number of vertices of polygon A. Then n lines contain pairs of integers xi, yi(|xi|, |yi| ≤ 10^9) — 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·10^4) — the number of vertices of polygon B. Then following m lines contain pairs of integers xj, yj (|xj|, |yj| ≤ 10^9) — 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
 
题解
判断给定的多边形B是否在严格凸的多边形A中,有两种思路:
  1. 枚举B中所有点,判断是否都在多边形A中。
  2. 将多边形AB的所有顶点放在一起,求凸包,判断求出来的凸包是否与原来的A一致。

思路一
由于是枚举B中所有点,且3 ≤ n ≤ 10^5、3 ≤ m ≤ 2·10^4,所以用复杂度为O(n)的点射法来判断一点是否在多边形内部肯定是不行的,由于A是严格凸的多边形,故可以考虑固定A上一点,从该点作到其他点的射线(此时相当于将A切割成了n-2个三角形),再二分查找B上一点在A中的角度区域,最后根据三角形第三边(指固定点对应的边)来判断改点是否严格在A内。当然有些情况要特判:

  • 点在最左和最右两个三角形的非第三边上,不满足B严格包含于A
  • 点在中间三角形的非第三边上,满足B严格包含于A
 /*******************************************************
二维几何基础
【注意】数组下标从1开始。
*******************************************************/ #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <string>
#define re register
#define il inline
#define ll long long
#define ld long double
using namespace std;
const ll MAXN = 1e5+;
const ll INF = 1e9;
const ld EPS = 1e-; //点坐标
struct POINT
{
ld x, y;
POINT() : x(), y() {}
POINT(ld _x, ld _y) : x(_x), y(_y) {}
};
//向量
typedef POINT VECTOR; POINT xy[MAXN]; //顺时针多边形顶点存储
POINT xyB[MAXN]; //判断点存储 //符号函数
ll sgn(ld x) {return x < -EPS ? - : x > EPS;}
//向量+向量=向量,点+向量=点
VECTOR operator + (VECTOR a, VECTOR b) {return {a.x+b.x,a.y+b.y};}
//向量-向量=向量,点-点=向量
VECTOR operator - (VECTOR a, VECTOR b) {return {a.x-b.x,a.y-b.y};}
//向量*数=向量
VECTOR operator * (VECTOR a, ld k) {return {a.x*k,a.y*k};}
VECTOR operator * (ld k, VECTOR a) {return {a.x*k,a.y*k};}
//向量/数=向量
VECTOR operator / (VECTOR a, ld k) {return {a.x/k,a.y/k};}
//向量==向量,点==点
bool operator == (const VECTOR a, const VECTOR b) {return !sgn(a.x-b.x) && !sgn(a.y-b.y);}
//向量旋转(逆时针)
VECTOR rot(VECTOR a, ld sita) {return {a.x*cos(sita)-a.y*sin(sita),a.x*sin(sita)+a.y*cos(sita)};}
//取下端点
POINT min(POINT p1, POINT p2) {return p1.y<p2.y ? p1:p2;}
//取上端点
POINT max(POINT p1, POINT p2) {return p1.y<p2.y ? p2:p1;}
//点积
ld dot(POINT p1, POINT p2, POINT p) {return (p.x-p1.x)*(p2.x-p1.x)+(p.y-p1.y)*(p2.y-p1.y);} //(三点式:共p1端点)
ld dot(VECTOR a, VECTOR b) {return a.x*b.x+a.y*b.y;} //向量式
//叉积
ld cross(POINT p1, POINT p2, POINT p) {return (p.x-p1.x)*(p2.y-p1.y)-(p.y-p1.y)*(p2.x-p1.x);} //(三点式:共p1端点)
ld cross(VECTOR a, VECTOR b) {return a.x*b.y-a.y*b.x;} //向量式(aXb)
//向量长度
ld vlen(VECTOR a) {return sqrt(dot(a,a));}
//向量夹角余弦值
ld vcos(VECTOR a, VECTOR b) {return dot(a,b)/(vlen(a)*vlen(b));}
//向量夹角正弦值
ld vsin(VECTOR a, VECTOR b) {return fabs(cross(a,b))/(vlen(a)*vlen(b));}
//求直线斜率【注意】确保斜率存在
ld slope(VECTOR a) {return a.y/a.x;} //向量式
ld slope(POINT p, POINT q) {return (p.y-q.y)/(p.x-q.x);} //两点式
//单位向量【注意】确保非零向量
VECTOR norm(VECTOR a) {return a/vlen(a);}
//两直线交点
POINT intersectline(POINT p, VECTOR v, POINT q, VECTOR w) {return p+v*cross(w,p-q)/cross(v,w);} //(参数式:P=P0+t*v,P0为直线上某一点,v为直线的方向向量)
//点在直线上的投影
POINT proline(POINT a, POINT b, POINT p) {return a+(b-a)*(dot(b-a,p-a)/dot(b-a,b-a));}
//点关于直线的对称点
POINT refline(POINT a, POINT b, POINT p) {return proline(a,b,p)*-p;}
//判断两直线是否平行
bool parallel(POINT p1, POINT p2, POINT q1, POINT q2) {return !sgn(cross(p2-p1,q2-q1)) && sgn(cross(p1-q1,p2-q1));}
//判断两直线重合
bool superposition(POINT p1, POINT p2, POINT q1, POINT q2) {return !sgn(cross(p2-p1,q2-q1)) && !sgn(cross(p1-q1,p2-q1));}
//点到直线距离
ld disline(POINT a, POINT b, POINT p) {return fabs(cross(b-a,p-a))/vlen(b-a);} //不取绝对值得到的是有向距离
//点到线段距离(两种情况:点的投影在线段上,则为垂直距离;点的投影不在线段上,则为到两端距离的最小值)
ld disseg(POINT a, POINT b, POINT p) {return a==b ? vlen(p-a):dot(b-a,p-a)< ? vlen(p-a):dot(b-a,p-b)> ? vlen(p-b):fabs(cross(b-a,p-a))/vlen(b-a);}
//线段相交判断(严格)
bool intersectseg(POINT p1, POINT p2, POINT q1, POINT q2) {return cross(p1-q1,q2-q1)*cross(p2-q1,q2-q1)< && cross(q1-p1,p2-p1)*cross(q2-p1,p2-p1)<;}
//判断点p(x,y)是否在线段p1p2上(两种情况:1.包括端点;2.不包含端点)
bool onseg(POINT p1, POINT p2, POINT p) {return !sgn(cross(p1,p2,p)) && sgn(dot(p,p1,p2))<=;} //包含端点
bool onseg_strict(POINT p1, POINT p2, POINT p) {return !sgn(cross(p1,p2,p)) && sgn(dot(p,p1,p2))<;} //不包含端点 //点射法判断点是否在多边形内部(边界也算在内部)
//复杂度O(n)(不论凹凸)
bool inpolygon_dot(ld x, ld y, ll n)
{
ll cnt = ;
for(re ll i = ; i < n; ++i)
{
POINT p1 = min(xy[i+], xy[(i+)%n+]); //取下端点
POINT p2 = max(xy[i+], xy[(i+)%n+]); //取上端点
//特判点在线段上
if(onseg(p1,p2,{x,y})) return true;
//从点(x,y)向x反方向引出射线
//计算点射到的多边形的边数边数
if(sgn(p1.y-y)< && sgn(y-p2.y) <= && sgn(cross(p1,p2,{x,y}))>) ++cnt;
}
if(cnt%) return true;
else return false;
} //二分法判断点是否在多边形内部(不包括边界)
//复杂度O(logn)(要求凸多边形)
bool inpolygon_bis(ld x, ld y, ll n)
{
POINT p = {x,y};
ll l = , r = n;
//判断是否在幅角最小和最大的两条边上
if(onseg(xy[],xy[l],p) || onseg(xy[],xy[n],p)) return false;
//二分法判断是否在多边形内部
while(l < r)
{
ll mid = (l+r)>>; //【注意】如此取中点最终:r==l或r==l-1(只有此两种情况)
ll d = sgn(cross(xy[mid]-xy[],p-xy[]));
if(d < ) l = mid+;
else if(d > ) r = mid-;
else
{
if(onseg_strict(xy[],xy[mid],p))
{
return true;
}
else
{
return false;
}
}
}
//判断在最终二分得到的对角线两端的边是否都满足严格在内的条件
if(l >= r && (sgn(cross(xy[l]-xy[l-],p-xy[l-]))>= || sgn(cross(xy[l%n+]-xy[l],p-xy[l]))>=))
{
return false;
}
return true;
} //计算多边形面积(凹凸均可)
ld polygonarea(ll n)
{
ld aera = ;
for(re ll i = ; i < n; ++i)
{
aera += cross(xy[i+], xy[(i+)%n+]);
}
//计算出来的aera为有向面积
return fabs(aera)/;
} int main()
{
std::ios::sync_with_stdio(false);
//判断点是否在多边形内(不包括边界)
ll n;
std::cin >> n;
for(re ll i = ; i <= n; ++i)
{
std::cin >> xy[i].x;
std::cin >> xy[i].y;
}
ll m;
cin >> m;
for(re ll i = ; i <= m; ++i)
{
cin >> xyB[i].x;
cin >> xyB[i].y;
}
for(re ll i = ; i <= m; ++i)
{
if(!inpolygon_bis(xyB[i].x, xyB[i].y, n))
{
printf("NO\n");
return ;
}
}
printf("YES\n");
return ;
}

思路二
AB所有顶点加在一起,利用graham算法或andrew算法求出凸包,判断是否和A相等即可。

 /************************************************************************
Graham算法
时间复杂度:O(nlogn)。Scan过程为O(n),预处理排序为O(nlogn)。
预处理排序:极角排序。
【注意】数组下标从1开始。
************************************************************************/ /*
思想:
把所有点放在二维坐标系中,则纵坐标最小的点一定是凸包上的点,记为xy0。计算
各个点相对xy0的幅角,按从小到大的顺序对各个点排序。(当幅角相同是,距离xy0
比较近的排在前面)则幅角最小的点和最大的点一定在凸包上,且第一个点即为xy0。
取幅角最小的点xy[j],将xy0、xy[j]入栈。连接栈顶的点和次栈顶的点,得到直线l,
看当前点是在直线的右边还是左边,在右边则栈顶元素不是凸包上的点,将其弹出,
返回继续执行。如果在左边,则当前点是凸包上的点。一直到幅角最大的那个点为之。
分析:
两个向量的叉积P1xP2 = x1*y2 - x2*y1,其中用结果的正负代表叉乘结果的方向。
该公式本质是两个三维向量(z轴分量为0)叉乘的结果(原来结果为(x1*y2 - x2*y1)
*k,其中k是z轴单位向量)。
*/ #include <bits/stdc++.h>
#include <stack>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define re register
#define il inline
#define ll long long
#define ld long double
using namespace std; const ll MAXN = 5e5+;
const ld INF = 1e9;
const ld EPS = 1e-; //点坐标
struct POINT
{
ld x, y;
POINT() : x(), y() {}
POINT(ld _x, ld _y) : x(_x), y(_y) {}
};
//向量
typedef POINT VECTOR; ll vexcnt = ; //凸包顶点数
POINT xy0; //先纵坐标后横坐标最小的点
POINT xy[MAXN], xyt[MAXN]; //多边形顶点存储,临时多边形顶点存储
POINT convex[MAXN]; //凸包顶点数组 //符号函数
ll sgn(ld x) {return x < -EPS ? - : x > EPS;}
//向量+向量=向量,点+向量=点
VECTOR operator + (VECTOR a, VECTOR b) {return {a.x+b.x,a.y+b.y};}
//向量-向量=向量,点-点=向量
VECTOR operator - (VECTOR a, VECTOR b) {return {a.x-b.x,a.y-b.y};}
//向量*数=向量
VECTOR operator * (VECTOR a, ld k) {return {a.x*k,a.y*k};}
VECTOR operator * (ld k, VECTOR a) {return {a.x*k,a.y*k};}
//向量/数=向量
VECTOR operator / (VECTOR a, ld k) {return {a.x/k,a.y/k};}
//向量==向量,点==点
bool operator == (const VECTOR a, const VECTOR b) {return !sgn(a.x-b.x) && !sgn(a.y-b.y);}
//向量偏序关系(先y轴再x轴)
bool operator < (const VECTOR a, const VECTOR b) {return !sgn(a.y-b.y) ? a.x < b.x : a.y < b.y;}
//向量旋转(逆时针)
VECTOR rot(VECTOR a, ld sita) {return {a.x*cos(sita)-a.y*sin(sita),a.x*sin(sita)+a.y*cos(sita)};}
//取下端点
POINT min(POINT p1, POINT p2) {return p1.y<p2.y ? p1:p2;}
//取上端点
POINT max(POINT p1, POINT p2) {return p1.y<p2.y ? p2:p1;}
//点积
ld dot(POINT p1, POINT p2, POINT p) {return (p.x-p1.x)*(p2.x-p1.x)+(p.y-p1.y)*(p2.y-p1.y);} //(三点式:共p1端点)
ld dot(VECTOR a, VECTOR b) {return a.x*b.x+a.y*b.y;} //向量式
//叉积
ld cross(POINT p1, POINT p2, POINT p) {return (p.x-p1.x)*(p2.y-p1.y)-(p.y-p1.y)*(p2.x-p1.x);} //(三点式:共p1端点)
ld cross(VECTOR a, VECTOR b) {return a.x*b.y-a.y*b.x;} //向量式(aXb)
//向量长度
ld vlen(VECTOR a) {return sqrt(dot(a,a));}
//向量夹角余弦值
ld vcos(VECTOR a, VECTOR b) {return dot(a,b)/(vlen(a)*vlen(b));}
//向量夹角正弦值
ld vsin(VECTOR a, VECTOR b) {return fabs(cross(a,b))/(vlen(a)*vlen(b));}
//极角排序(从小到大,极角相同则距离初始点由近到远)
bool cmppas(const POINT p1, const POINT p2) {return !sgn(cross(p1-xy0,p2-xy0)) ? vlen(p1-xy0)<vlen(p2-xy0):sgn(cross(p1-xy0,p2-xy0))>;}
//距离排序(从小到大,距离初始点的距离)
bool cmpdisup(const POINT p1, const POINT p2) {return vlen(p1-xy0)<vlen(p2-xy0);}
//距离排序(从大到小,距离初始点的距离)
bool cmpdisdown(const POINT p1, const POINT p2) {return vlen(p1-xy0)>vlen(p2-xy0);}
//求凸包周长
ld convexperimeter()
{
ld ans = ;
for(re ll i = ; i <= vexcnt; ++i)
{
ans += vlen(convex[i]-convex[i%vexcnt+]);
}
return ans;
}
//计算多边形面积
ld polygonarea()
{
ld aera = ;
for(re ll i = ; i < vexcnt; ++i)
{
aera += cross(convex[i+], convex[(i+)%vexcnt+]);
}
return fabs(aera)/; //不加绝对值为有向面积
} //graham算法求凸包(凸包数组正序为逆时针)
//1.严格凸包(没有重复点和三点共线)2.非严格凸包(允许重复点和三点共线)
void graham(ll n)
{
memcpy(xyt,xy,sizeof(xy)); //备份原来顶点集
sort(xyt+,xyt+n+,cmppas); //第一位一定为xy0(由极角排序规则可知)
//使极角最小和最大的点按照到初始点距离有序排序(便于后续划分严格凸包和非严格凸包)
ll first = , firstcnt = ; //first记录幅角最小的点
while(xyt[++first]==xyt[]);
for(re ll i = first; i <= n; ++i)
{
if(!sgn(cross(xyt[i]-xyt[],xyt[first]-xyt[]))) ++firstcnt;
else break;
}
sort(xyt+first,xyt+first+firstcnt,cmpdisup);
ll last = n, lastcnt = ; //last记录幅角最大的点
for(re ll i = last; i >= ; --i)
{
if(!sgn(cross(xyt[i]-xyt[],xyt[last]-xyt[]))) ++lastcnt;
else break;
}
last -= lastcnt-;
sort(xyt+last,xyt+last+lastcnt,cmpdisdown);
//求解凸包顶点集
convex[++vexcnt] = xyt[]; //xyt[1]一定在凸包中
ll j = ;
while(j <= n)
{
if(vexcnt <= ) //因为xyt[2]不一定在凸包集中(对于严格凸包来说)
{
convex[++vexcnt] = xyt[j++];
}
else
{
//取前面两个点
//严格凸包:sgn(cross(convex[vexcnt]-convex[vexcnt-1],xyt[j]-convex[vexcnt]))>0
//非严格凸包:sgn(cross(convex[vexcnt]-convex[vexcnt-1],xyt[j]-convex[vexcnt]))>=0
if(sgn(cross(convex[vexcnt]-convex[vexcnt-],xyt[j]-convex[vexcnt]))>=) convex[++vexcnt] = xyt[j++];
else --vexcnt;
}
}
//for(re ll i = 1; i <= vexcnt; ++i) cout << "(" << convex[i].x << "," << convex[i].y << ")" << endl;
return;
} int main()
{
std::ios::sync_with_stdio(false);
xy0.x = xy0.y = INF; //初始化第一个点
ll n;
cin >> n;
for(re ll i = ; i <= n; ++i)
{
cin >> xy[i].x >> xy[i].y;
if(xy[i] < xy0)
{
xy0 = xy[i];
}
}
ll m;
cin >> m;
for(re ll i = n+; i <= n+m; ++i)
{
cin >> xy[i].x >> xy[i].y;
if(xy[i] < xy0)
{
xy0 = xy[i];
}
}
graham(n+m);
//判断点是否全部在凸包内
if(vexcnt != n)
{
printf("NO\n");
return ;
}
ll record = -;
for(re ll i = ; i <= n; ++i)
{
if(convex[i] == xy[])
{
record = i;
break;
}
}
if(record == -)
{
printf("NO\n");
return ;
}
for(re ll i = ; i <= n; ++i, record=record<= ? n:record-)
{
if(!(convex[record] == xy[i]))
{
printf("NO\n");
return ;
}
}
printf("YES\n");
return ;
}
 /************************************************************************
Andrew算法(Graham算法变种)
时间复杂度:O(nlogn)。Scan过程为O(n),预处理排序为O(nlogn)。
预处理排序:水平排序排序。
【注意】数组下标从1开始。
************************************************************************/ /*
思想:
预处理排序改为水平排序,按照横坐标从小到大进行排序,横坐标相同则按纵坐标从
小到大排。按照graham算法思想从p1、p2扫描所有点得到下凸包,再从pn、pn-1扫
描所有点得到上凸包,二者结合即为整个凸包。(注意:这里的p2不一定在凸包里)
分析:
两个向量的叉积P1xP2 = x1*y2 - x2*y1,其中用结果的正负代表叉乘结果的方向。
该公式本质是两个三维向量(z轴分量为0)叉乘的结果(原来结果为(x1*y2 - x2*y1)
*k,其中k是z轴单位向量)。
*/ #include <bits/stdc++.h>
#include <stack>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define re register
#define il inline
#define ll long long
#define ld long double
using namespace std; const ll MAXN = 5e5+;
const ld INF = 1e9;
const ld EPS = 1e-; //点坐标
struct POINT
{
ld x, y;
POINT() : x(), y() {}
POINT(ld _x, ld _y) : x(_x), y(_y) {}
};
//向量
typedef POINT VECTOR; ll vexcnt = ; //凸包顶点数
POINT xy[MAXN], xyt[MAXN]; //多边形顶点存储,临时多边形顶点存储
POINT convex[MAXN]; //凸包顶点数组 //符号函数
ll sgn(ld x) {return x < -EPS ? - : x > EPS;}
//向量+向量=向量,点+向量=点
VECTOR operator + (VECTOR a, VECTOR b) {return {a.x+b.x,a.y+b.y};}
//向量-向量=向量,点-点=向量
VECTOR operator - (VECTOR a, VECTOR b) {return {a.x-b.x,a.y-b.y};}
//向量*数=向量
VECTOR operator * (VECTOR a, ld k) {return {a.x*k,a.y*k};}
VECTOR operator * (ld k, VECTOR a) {return {a.x*k,a.y*k};}
//向量/数=向量
VECTOR operator / (VECTOR a, ld k) {return {a.x/k,a.y/k};}
//向量==向量,点==点
bool operator == (const VECTOR a, const VECTOR b) {return !sgn(a.x-b.x) && !sgn(a.y-b.y);}
//向量偏序关系(先x轴再y轴)
bool operator < (const VECTOR a, const VECTOR b) {return !sgn(a.x-b.x) ? a.y < b.y : a.x < b.x;}
//向量旋转(逆时针)
VECTOR rot(VECTOR a, ld sita) {return {a.x*cos(sita)-a.y*sin(sita),a.x*sin(sita)+a.y*cos(sita)};}
//取下端点
POINT min(POINT p1, POINT p2) {return p1.y<p2.y ? p1:p2;}
//取上端点
POINT max(POINT p1, POINT p2) {return p1.y<p2.y ? p2:p1;}
//点积
ld dot(POINT p1, POINT p2, POINT p) {return (p.x-p1.x)*(p2.x-p1.x)+(p.y-p1.y)*(p2.y-p1.y);} //(三点式:共p1端点)
ld dot(VECTOR a, VECTOR b) {return a.x*b.x+a.y*b.y;} //向量式
//叉积
ld cross(POINT p1, POINT p2, POINT p) {return (p.x-p1.x)*(p2.y-p1.y)-(p.y-p1.y)*(p2.x-p1.x);} //(三点式:共p1端点)
ld cross(VECTOR a, VECTOR b) {return a.x*b.y-a.y*b.x;} //向量式(aXb)
//向量长度
ld vlen(VECTOR a) {return sqrt(dot(a,a));}
//向量夹角余弦值
ld vcos(VECTOR a, VECTOR b) {return dot(a,b)/(vlen(a)*vlen(b));}
//向量夹角正弦值
ld vsin(VECTOR a, VECTOR b) {return fabs(cross(a,b))/(vlen(a)*vlen(b));}
//求凸包周长
ld convexperimeter()
{
ld ans = ;
for(re ll i = ; i <= vexcnt; ++i)
{
ans += vlen(convex[i]-convex[i%vexcnt+]);
}
return ans;
}
//计算多边形面积
ld polygonarea()
{
ld aera = ;
for(re ll i = ; i < vexcnt; ++i)
{
aera += cross(convex[i+], convex[(i+)%vexcnt+]);
}
return fabs(aera)/; //不加绝对值为有向面积
} //andrew算法求凸包(凸包数组正序为逆时针)
//1.严格凸包(没有重复点和三点共线)2.非严格凸包(允许重复点和三点共线)
void andrew(ll n)
{
memcpy(xyt,xy,sizeof(xy)); //备份原来顶点集
sort(xyt+,xyt+n+); //排序后xyt[1]和xyt[n]一定在凸包中
//求解凸包顶点集
//正向扫描(下凸包)
convex[++vexcnt] = xyt[]; //xyt[1]一定在凸包中
ll j = ;
while(j <= n)
{
if(vexcnt <= ) //因为xyt[2]不一定在凸包集中
{
convex[++vexcnt] = xyt[j++];
}
else
{
//取前面两个点
//严格凸包:sgn(cross(convex[vexcnt]-convex[vexcnt-1],xyt[j]-convex[vexcnt]))>0
//非严格凸包:sgn(cross(convex[vexcnt]-convex[vexcnt-1],xyt[j]-convex[vexcnt]))>=0
if(sgn(cross(convex[vexcnt]-convex[vexcnt-],xyt[j]-convex[vexcnt]))>=) convex[++vexcnt] = xyt[j++];
else --vexcnt;
}
}
//反向扫描(上凸包)
//至少包含了xyt[1]和xyt[n]
ll k = n-;
while(k >= )
{
//取前面两个点
//严格凸包:sgn(cross(convex[vexcnt]-convex[vexcnt-1],xyt[k]-convex[vexcnt]))>0
//非严格凸包:sgn(cross(convex[vexcnt]-convex[vexcnt-1],xyt[k]-convex[vexcnt]))>=0
if(sgn(cross(convex[vexcnt]-convex[vexcnt-],xyt[k]-convex[vexcnt]))>=) convex[++vexcnt] = xyt[k--];
else --vexcnt;
}
while(convex[--vexcnt]==convex[]); //因为和xyt[1]相等的点都在下凸包中了
for(re ll i = ; i <= vexcnt; ++i) cout << "(" << convex[i].x << "," << convex[i].y << ")" << endl;
return;
} int main()
{
std::ios::sync_with_stdio(false);
ll n;
cin >> n;
for(re ll i = ; i <= n; ++i)
{
cin >> xy[i].x >> xy[i].y;
}
ll m;
cin >> m;
for(re ll i = n+; i <= n+m; ++i)
{
cin >> xy[i].x >> xy[i].y;
}
andrew(n+m);
//判断点是否全部在凸包内
if(vexcnt != n)
{
printf("NO\n");
return ;
}
ll record = -;
for(re ll i = ; i <= n; ++i)
{
if(convex[i] == xy[])
{
record = i;
break;
}
}
if(record == -)
{
printf("NO\n");
return ;
}
for(re ll i = ; i <= n; ++i, record=record<= ? n:record-)
{
if(!(convex[record] == xy[i]))
{
printf("NO\n");
return ;
}
}
printf("YES\n");
return ;
}

CodeForces-166B-Polygons的更多相关文章

  1. Codeforces 166B - Polygon (判断凸包位置关系)

    Codeforces Round #113 (Div. 2) 题目链接:Polygons You've got another geometrical task. You are given two ...

  2. CodeForces 166B (凸包)

    求一个多边形是否完全在另一个凸多边形内. 乍一看,好像要判点在多边形内,但复杂度不允许,仔细一想,可以把两个多边形的点混起来求一个共同的凸包,如果共同的凸包依旧是原来凸包上的点,说明是. #inclu ...

  3. 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 o ...

  4. Codeforces Round #113 (Div. 2)

    Codeforces Round #113 (Div. 2) B. Polygons 题意 给一个\(N(N \le 10^5)\)个点的凸包 \(M(M \le 2 \cdot 10^4)\)次询问 ...

  5. Gym 100952J&&2015 HIAST Collegiate Programming Contest J. Polygons Intersection【计算几何求解两个凸多边形的相交面积板子题】

    J. Polygons Intersection time limit per test:2 seconds memory limit per test:64 megabytes input:stan ...

  6. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  7. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  8. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  9. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  10. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

随机推荐

  1. java使用递归遍历文件,使用内部类过滤文件,使用匿名内部类过滤文件

    public class TestFile { public static void main(String [] args) { //遍历文件夹中文件名称,若文件夹中还存有文件夹,递归读取文件夹名称 ...

  2. hook cookie

    // ==UserScript== // @name cookie // @namespace http://tampermonkey.net/ // @version 0.1 // @descrip ...

  3. 深度学习面试题09:一维卷积(Full卷积、Same卷积、Valid卷积、带深度的一维卷积)

    目录 一维Full卷积 一维Same卷积 一维Valid卷积 三种卷积类型的关系 具备深度的一维卷积 具备深度的张量与多个卷积核的卷积 参考资料 一维卷积通常有三种类型:full卷积.same卷积和v ...

  4. html5中progress/meter元素

    html5中progress/meter元素 一.总结 一句话总结: progress元素:用来建立一个进度条 meter元素的作用:用来建立一个度量条,用来表示度量衡的评定 <progress ...

  5. [转]Git 代码撤销、回滚到任意版本(当误提代码到本地或master分支时)

    两种情况(场景) 情况一      代码还只在本地,未push到运程仓库,想把代码还原到上一次commit的代码,此时操作为代码撤销 解决方案: 1 git reset [--hard|soft|mi ...

  6. YII2 composer update 报错解决一例-requires bower-asset/jquery 2.2

    ➜  yii-advanced composer update Loading composer repositories with package information Updating depe ...

  7. 【Java】Spring快速入门(一)

    Spring介绍 Spring可以轻松创建Java企业应用程序.它提供了在企业环境中使用Java语言所需的一切,支持Groovy和Kotlin作为JVM上的替代语言,并可根据应用程序的需要灵活地创建多 ...

  8. KSQL Syntax Reference

    KSQL Syntax Reference KSQL has similar semantics to SQL: Terminate KSQL statements with a semicolon ...

  9. LabWindows/CVI入门之第四章:库文件(转)

    按语: 在参考CVI参考书使用CVI生成动态库后,在另一工程中调用DLL ,编译通不过,后参考此文,豁然开朗. http://blog.sina.com.cn/s/blog_6373e9e60101b ...

  10. HTML布局排版5 测试某段html页面1

    除了div,常见的还有用table布局,这里直接用前面博文的页头页尾,如下面的页面的部分,是个简单的table.该页面样式,如果拖动浏览器,可以看到table和文本框总是居中,但是文本框下方那两个按钮 ...