Cupid's Arrow
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1163 Accepted Submission(s): 425Problem Description传说世上有一支丘比特的箭,凡是被这支箭射到的人,就会深深的爱上射箭的人。
世上无数人都曾经梦想得到这支箭。Lele当然也不例外。不过他想,在得到这支箭前,他总得先学会射箭。
日子一天天地过,Lele的箭术也越来越强,渐渐得,他不再满足于去射那圆形的靶子,他开始设计各种各样多边形的靶子。
不过,这样又出现了新的问题,由于长时间地练习射箭,Lele的视力已经高度近视,他现在甚至无法判断他的箭射到了靶子没有。所以他现在只能求助于聪明的Acmers,你能帮帮他嘛?Input本题目包含多组测试,请处理到文件结束。
在每组测试的第一行,包含一个正整数N(2<N<100),表示靶子的顶点数。
接着N行按顺时针方向给出这N个顶点的x和y坐标(0<x,y<1000)。
然后有一个正整数M,表示Lele射的箭的数目。
接下来M行分别给出Lele射的这些箭的X,Y坐标(0<X,Y<1000)。Output对于每枝箭,如果Lele射中了靶子,就在一行里面输出"Yes",否则输出"No"。Sample Input4 10 10 20 10 20 5 10 5 2 15 8 25 8Sample OutputYes NoAuthorlinleSource
这个题是裸的判断点p在多边形内部的, 直接用射线法就可以做, 射线法就是以p为端点,向一个方向做射线,然后看有几个交点,如果交点是奇数,则在内部,偶数,外部,一般选择往右做射线,还有就是判断几个特殊情况.代码中有注释
/************************************************************************* > File Name: hdu_1756.cpp > Author: Howe_Young > Mail: 1013410795@qq.com > Created Time: 2015年04月06日 星期一 09时06分42秒 ************************************************************************/ #include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <cstdio> #define EPS 1e-8 using namespace std; typedef long long LL; const int N = 105; struct point{ double x, y; }; point poly[N]; int n, m; double dabs(double a) { return a < 0 ? -a : a; } double Min(double a, double b) { return a < b ? a : b; } double Max(double a, double b) { return a > b ? a : b; } bool on_line(point a, point b, point c)//判断点在直线上 { if (c.x >= Min(a.x, b.x) && c.x <= Max(a.x, b.x) && c.y >= Min(a.y, b.y) && c.y <= Max(a.y, b.y)) { return (dabs((c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y)) <= EPS); } return false; } bool inside_polygon(point p, int n)//判断点在多边形内 { int counter = 0; double xinter; point p1, p2; p1 = poly[0]; for (int i = 1; i <= n; i++) { p2 = poly[i % n]; if (on_line(p1, p2, p))//此题在边界不算 return false; if (p.y > Min(p1.y, p2.y))//如果射线交于边的下端点,不算相交,所以是> { if (p.y <= Max(p1.y, p2.y)) { if (p.x <= Max(p1.x, p2.x)) { if (p1.y != p2.y)//如果射线和边重合,不算 { //判断是否满足在这个边的左边,其中(p1.x - p2.x) / (p1.y - p2.y)为tan xinter = (p.y - p2.y) * (p1.x - p2.x) / (p1.y - p2.y) + p2.x; if (p1.x == p2.x || p.x <= xinter) counter++; } } } } p1 = p2; } if (counter % 2 == 0) return false; return true; } int main() { while (~scanf("%d", &n)) { for (int i = 0; i < n; i++) { scanf("%lf %lf", &poly[i].x, &poly[i].y); } cin >> m; point p; for (int i = 0; i < m; i++) { cin >> p.x >> p.y; if (inside_polygon(p, n)) puts("Yes"); else puts("No"); } } return 0; }