Codeforces166B Polygons(叉乘+二分)
来源:互联网 发布:wkwebview 监听js方法 编辑:程序博客网 时间:2024/05/21 07:10
题目链接:http://codeforces.com/problemset/problem/166/B
此题还可以用凸包解决:http://blog.csdn.net/xuh723/article/details/22451957
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.
The first line contains the only integer n (3 ≤ n ≤ 105) — the number of vertices of polygon A. Then n lines contain pairs of integersxi, 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.
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).
6-2 10 33 34 13 -22 -240 12 23 11 0
YES
51 24 23 -3-2 -2-2 140 11 24 12 -1
NO
5-1 22 34 13 -20 -351 01 13 15 -12 -1
NO
题意:给出两个多边形A,B,保证A是一个凸多边形,判断B是否完全包含在A内。
一开始的思路是直接将B中的每个点与A中的每个点进行叉乘,判断是否在多边形内,结果超时了。
然后想到进行二分查找。
将多边形A分成n-2个三角形(pa[0],pa[i+1],pa[i]),按照顺序排列(如图)。(此处三角形顶点保证逆时针序以便于判断点与三角形关系)
随后判断点p与三角形(pa[0],pa[i+1],pa[i])的关系,在“后面”则l=mid,在“前面”则r=mid。最后找到所在三角形后再进行一次判断,若点正好在三角形内部则继续循环,否则退出循环输出NO。(注意特别处理点正好在边上的情况)
#include <iostream>#include <cstdio>#include <cstring>#include <string>using namespace std;#define eps 1e-8struct 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); }}pa[100005],pb[20005];int n,m;int dcmp(double x){ return (x>eps)-(x<-eps);}double cross(point a,point b){ return a.x*b.y-b.x*a.y;}int pd( point o, point a, point b, point c ) { //判断点与三角形关系 if( dcmp(cross(b - a, o - a)) < 0 ) return 1; if( dcmp(cross(c - b, o - b)) <= 0 ) return 100; if( dcmp(cross(a - c, o - c)) < 0 ) return -1; return 0;}int pd2( point o, point a, point b, point c ) { //特殊判断1 if( dcmp(cross(b - a, o - a)) < 0 ) return 1; if( dcmp(cross(c - b, o - b)) <= 0 ) return 100; if( dcmp(cross(a - c, o - c)) <= 0 ) return -1; return 0;}int pd3( point o, point a, point b, point c ) { //特殊判断2 if( dcmp(cross(b - a, o - a)) <= 0 ) return 1; if( dcmp(cross(c - b, o - b)) <= 0 ) return 100; if( dcmp(cross(a - c, o - c)) < 0 ) return -1; return 0;}int main(){ while (scanf("%d",&n)!=EOF) { for (int i=0;i<n;i++) { scanf("%lf%lf",&pa[i].x,&pa[i].y); } scanf("%d",&m); for (int i=0;i<m;i++) { scanf("%lf%lf",&pb[i].x,&pb[i].y); } bool flag=1; for(int i=0;i<m;i++) { int l=1,r=n-1;//二分查找可能包含点i的三角形 while (l<r) { int mid=(l+r)/2; int x=pd(pb[i],pa[0],pa[mid+1],pa[mid]);//返回1表示在“后面”,-1表示在“前面”,0表示在内部,100表示出了边界,可以不用考虑了 if (x==1) {l=mid+1;} else if (x==100) {flag=0;break;} else {r=mid;} } if (flag==0) break; if (l==1&&pd2(pb[i],pa[0],pa[l+1],pa[l])!=0) {flag=0;break;}//第一个三角形,特殊判断点是否在边上 if (l==n-2&&pd3(pb[i],pa[0],pa[l+1],pa[l])!=0) {flag=0;break;}//最后一个三角形,特殊判断点是否在边上 //其他三角形,则点肯定在三角形内部,不需要再次判断 } if (flag==1) printf("YES\n");else printf("NO\n"); } return 0;}
- Codeforces166B Polygons(叉乘+二分)
- Codeforces166B Polygons(凸包判断)
- Toy Storage(poj2398,向量叉乘+二分查找)
- Hust oj 1429 凸多边形(叉乘+二分)
- POJ 2318 TOYS (向量叉乘+二分)
- Polygons
- 计算几何叉乘二分+博弈
- 点乘 叉乘
- poj2398 几何运算(叉乘---判断是否在凸四边形内的判断(二分、排序))
- 向量的点乘与叉乘(转载)
- 向量积(叉乘)
- ZOJ1041-Transmitters(叉乘)
- 叉乘
- 叉乘
- 叉乘
- 叉乘
- 点乘和叉乘
- 点乘,叉乘总结
- 分享几个机试题目
- 第二类Stirling数
- NOIP2000 计算器的改良
- hdu1080解题报告
- OpenCL(CUDA5.0) + Visual Studio 2010 环境配置
- Codeforces166B Polygons(叉乘+二分)
- 常用的邮箱服务器(SMTP、POP3)地址、端口
- According to TLD or attribute directive in tag file, attribute items does not accept any expressions
- twisted scrapy安装
- PHP与WCF通信数据获取
- 成功投资的九大要诀
- js实现两个时间差
- 基于Arcgis Server的地图封装Javascript类定义
- 三层架构实例[ZT]