题目:

给个n个点的多边形,n个点按顺序给出,给个点m,判断m在不在多边形内部


题解:

网上有两种方法,这里写一种:射线法

大体的思想是:以这个点为端点,做一条平行与x轴的射线(代码中射线指向x轴正方向)

如果交点个数为奇数的话就在内部,如果为偶数(包括0)就在外部

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #define N 105
  5. using namespace std;
  6. int n,m;
  7. struct point//点(向量的结构体)
  8. {
  9. int x,y;
  10. point() {}//初始化
  11. point (int _x,int _y) :
  12. x(_x),y(_y) {};//用一对坐标初始化点
  13. inline point operator + (const point &rhs) const//向量加法
  14. {
  15. return point(x+rhs.x,y+rhs.y);
  16. }
  17. inline point operator - (const point &rhs) const//向量减法
  18. {
  19. return point(x-rhs.x,y-rhs.y);
  20. }
  21. inline int operator * (const point &rhs) const//向量叉乘
  22. //向量叉乘的几何意义是以两个向量为邻边的平行四边形的有向面积 也就是|a|*|b|*sin<a,b> 这里的sin<a,b>决定了
  23. //如果a,b是逆时针的,那么sin<a,b>大于0,有向面积大于0,反之<0
  24. {
  25. return x*rhs.y-y*rhs.x;
  26. }
  27. friend inline int dot(const point &lhs,const point &rhs)//向量点乘
  28. {
  29. return lhs.x*rhs.x+lhs.y*rhs.y;
  30. }
  31. }q;
  32. inline int check(const point &u,const point &v,const point &p)//判断点是不是在线段上
  33. //u,v是线段端点,p是点
  34. {
  35. int det=(u-p)*(v-p);//如果向量(u-p)*(v-p)==0就说明u,v,p共线(因为没面积)
  36. if (det!=0) return 0;
  37. int Dot=dot(u-p,v-p);//如果(u-p)点乘(v-p)<=0 就说明点在线段上
  38. return Dot<=0;
  39. }
  40. struct polygon//多边形结构体
  41. {
  42. int n;
  43. point p[N];
  44. void init(int _n)
  45. {
  46. n=_n;
  47. for (int i=0;i<n;i++)
  48. scanf("%d%d",&p[i].x,&p[i].y);
  49. p[n]=p[0];
  50. if (Area()<0) reverse(p,p+n);//通过判断多边形的有向面积来把点规范成逆时针的
  51. p[n]=p[0];
  52. }
  53. inline int Area() const
  54. //计算多边形的有向面积(如果点是逆时针的话就是正的,否则是负的)
  55. {
  56. int ret=0;
  57. for (int i=0;i<n;i++)
  58. ret+=p[i]*p[i+1];
  59. return ret=0;
  60. }
  61. bool inner (const point &q)//判断点是不是在多边形内部
  62. {
  63. int cnt=0;
  64. for (int i=0;i<n;i++)
  65. {
  66. if (check(p[i],p[i+1],q)) return 1;//如果点在线段上显然可以
  67. int d1=p[i].y-q.y,d2=p[i+1].y-q.y;
  68. int det=(p[i]-q)*(p[i+1]-q);
  69. if ( (det>=0 && d1<0 && d2>=0) ||
  70. (det<=0 && d1>=0 && d2<0)) ++cnt;//第一个条件是判断p在多边形内的时候,第二个是判断p在多边形外的时候
  71. }
  72. return cnt&1;
  73. }
  74. }P;
  75.  
  76. int main()
  77. {
  78. for (int tt=1;;tt++)
  79. {
  80. scanf("%d",&n);
  81. if (n==0) break;
  82. scanf("%d",&m);
  83. P.init(n);
  84. if (tt!=1)
  85. putchar('\n');
  86. printf("Problem %d:\n",tt);
  87. while (m--)
  88. {
  89. scanf("%d%d",&q.x,&q.y);
  90. if (P.inner(q)) puts("Within");
  91. else puts("Outside");
  92. }
  93. }
  94. return 0;
  95. }

ZOJ 1081 Points Within | 判断点在多边形内的更多相关文章

  1. [zoj] 1081 Points Within || 判断点是否在多边形内

    原题 多组数据. n为多边形顶点数,m为要判断的点数 按逆时针序给出多边形的点,判断点是否在多边形内,在的话输出"Within",否则输出"Outside" / ...

  2. ZOJ 1081 Within(点是否在多边形内)| 计算几何

    ZOJ 1081 Within 我使用的是"射线法":从该点出发,作一条向左的水平射线,与多边形的边的交点有奇数个则点在多边形内. 需要注意的点: 如果点在多边形的边上特判. 考虑 ...

  3. zoj 1081 判断点在多边形内

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=81Points Within Time Limit: 2 Second ...

  4. R树判断点在多边形内-Java版本

    1.什么是RTree 待补充 2.RTree java依赖 rtree的java开源版本在GitHub上:https://github.com/davidmoten/rtree 上面有详细的使用说明 ...

  5. 判断点在多边形内算法的C++实现

    目录 1. 算法思路 2. 具体实现 3. 改进空间 1. 算法思路 判断平面内点是否在多边形内有多种算法,其中射线法是其中比较好理解的一种,而且能够支持凹多边形的情况.该算法的思路很简单,就是从目标 ...

  6. hdu 1756:Cupid's Arrow(计算几何,判断点在多边形内)

    Cupid's Arrow Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  7. php之判断点在多边形内的api

    1.判断点在多边形内的数学思想:以那个点为顶点,作任意单向射线,如果它与多边形交点个数为奇数个,那么那个点在多边形内,相关公式: <?php class AreaApi{ //$area是一个多 ...

  8. POJ 2318 TOYS | 二分+判断点在多边形内

    题意: 给一个矩形的区域(左上角为(x1,y1) 右下角为(x2,y2)),给出n对(u,v)表示(u,y1) 和 (v,y2)构成线段将矩形切割 这样构成了n+1个多边形,再给出m个点,问每个多边形 ...

  9. zoj 1081:Points Within(计算几何,判断点是否在多边形内,经典题)

    Points Within Time Limit: 2 Seconds      Memory Limit: 65536 KB Statement of the Problem Several dra ...

随机推荐

  1. JS笔试汇总

    //console.log(a[b]); var a={}; var b={key:'b'}; var c={key:'c'}; a[b] = 456; a[c] = 123; console.log ...

  2. TLS握手协议

    SSL/TLS基础 SSL(Secure Sockets Layer 安全套接层),及其继任者-传输层安全(Transport Layer Security, TLS)是为网络通信提供安全及数据完整性 ...

  3. ES6初识-Proxy和Reflect

    { let obj={ time:'2017-03-11', name:'net', _r:123 };   let monitor=new Proxy(obj,{ // 拦截对象属性的读取 get( ...

  4. SQL递归查询实现组织机构树

    系统用到的组织机构树,要实现对当前节点以及其子节点的查询,数据库SQL要用到递归查询,这也是我第一次接触SQL的递归查询. 先说一下什么是递归查询,简单说来是将一个树状结构存储在一张表里,比如一个表中 ...

  5. MySQL - Linux下安装

    本安装方式仅对5.7.21版本负责. 下载地址:wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.21-linux-glibc2 ...

  6. mysql中列属性

    mysql列属性包括:NULL .default.comment.primary key.unique key 一.NULL定义方式:NULL(默认) NOT NULL 空属性有2个值,mysql数据 ...

  7. http协议组成(请求状态码)

    http请求由:请求行:消息报头:请求正文组成 //请求行 Request URL: http://172.32.4.33:8080/operation/v2/autoServer/queryAuto ...

  8. Python基本数据类型及使用

    # 基本数据类型分类 - int 整数 - float 小数 - bool 布尔值 - str 字符串 ## int 整数 - 包括正整数和负整数 - 与java.c等语言相比并没有位数限制,理论上可 ...

  9. 43_2.VUE学习之--不使用组件computed计算属性超简单的实现美团购物车原理

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. Matplotlib库介绍

    pyplot的plot()函数 pyplot的中文显示 pyplot的文本显示 pyplot的子绘图区域